Merge pull request #80 from versity/admin-delete-api

feat: Added admin api and admin CLI aciton to delete a user
This commit is contained in:
Ben McClelland
2023-06-12 09:21:31 -07:00
committed by GitHub
4 changed files with 112 additions and 0 deletions
+40
View File
@@ -70,10 +70,17 @@ func (c *AccountsCache) updateAccounts() error {
return nil
}
func (c *AccountsCache) deleteAccount(access string) {
c.mu.Lock()
defer c.mu.Unlock()
delete(c.Accounts, access)
}
type IAMService interface {
GetIAMConfig() (*IAMConfig, error)
CreateAccount(access string, account *Account) error
GetUserAccount(access string) *Account
DeleteUserAccount(access string) error
}
type IAMServiceUnsupported struct {
@@ -135,3 +142,36 @@ func (s IAMServiceUnsupported) GetUserAccount(access string) *Account {
return acc
}
func (s IAMServiceUnsupported) DeleteUserAccount(access string) error {
var data IAMConfig
file, err := os.ReadFile("users.json")
if err != nil {
return fmt.Errorf("unable to read config file: %w", err)
}
if err := json.Unmarshal(file, &data); err != nil {
return fmt.Errorf("failed to parse the config file: %w", err)
}
_, ok := data.AccessAccounts[access]
if !ok {
return fmt.Errorf("invalid access for the user: user does not exist")
}
delete(data.AccessAccounts, access)
updatedJSON, err := json.MarshalIndent(data, "", " ")
if err != nil {
return fmt.Errorf("failed to parse the data: %w", err)
}
if err := os.WriteFile("users.json", updatedJSON, 0644); err != nil {
return fmt.Errorf("failed to saved the changes: %w", err)
}
s.accCache.deleteAccount(access)
return nil
}
+53
View File
@@ -73,6 +73,19 @@ func adminCommand() *cli.Command {
},
},
},
{
Name: "delete-user",
Usage: "Delete a user",
Action: deleteUser,
Flags: []cli.Flag{
&cli.StringFlag{
Name: "access",
Usage: "access value for the user to be deleted",
Required: true,
Aliases: []string{"a"},
},
},
},
},
Flags: []cli.Flag{
// TODO: create a configuration file for this
@@ -143,3 +156,43 @@ func createUser(ctx *cli.Context) error {
return nil
}
func deleteUser(ctx *cli.Context) error {
access := ctx.String("access")
if access == "" {
return fmt.Errorf("invalid input parameter for the new user")
}
req, err := http.NewRequest(http.MethodDelete, fmt.Sprintf("http://localhost:7070/delete-user?access=%v", access), nil)
if err != nil {
return fmt.Errorf("failed to send the request: %w", err)
}
signer := v4.NewSigner()
hashedPayload := sha256.Sum256([]byte{})
hexPayload := hex.EncodeToString(hashedPayload[:])
req.Header.Set("X-Amz-Content-Sha256", hexPayload)
signErr := signer.SignHTTP(req.Context(), aws.Credentials{AccessKeyID: adminAccess, SecretAccessKey: adminSecret}, req, hexPayload, "s3", adminRegion, time.Now())
if signErr != nil {
return fmt.Errorf("failed to sign the request: %w", err)
}
client := http.Client{}
resp, err := client.Do(req)
if err != nil {
return fmt.Errorf("failed to send the request: %w", err)
}
body, err := io.ReadAll(resp.Body)
if err != nil {
return err
}
fmt.Printf("%s", body)
return nil
}
+16
View File
@@ -47,3 +47,19 @@ func (c AdminController) CreateUser(ctx *fiber.Ctx) error {
ctx.SendString("The user has been created successfully")
return nil
}
func (c AdminController) DeleteUser(ctx *fiber.Ctx) error {
access := ctx.Query("access")
requesterRole := ctx.Locals("role")
if requesterRole != "admin" {
return fmt.Errorf("access denied: only admin users have access to this resource")
}
err := c.IAMService.DeleteUserAccount(access)
if err != nil {
return err
}
ctx.SendString("The user has been created successfully")
return nil
}
+3
View File
@@ -29,6 +29,9 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
// TODO: think of better routing system
app.Post("/create-user", adminController.CreateUser)
// Admin Delete api
app.Delete("/delete-user", adminController.DeleteUser)
// ListBuckets action
app.Get("/", s3ApiController.ListBuckets)