diff --git a/auth/iam.go b/auth/iam.go index b8e7cdd2..47c5ce25 100644 --- a/auth/iam.go +++ b/auth/iam.go @@ -18,6 +18,8 @@ import ( "errors" "fmt" "time" + + "github.com/versity/versitygw/s3err" ) type Role string @@ -57,10 +59,19 @@ type ListUserAccountsResult struct { // Mutable props, which could be changed when updating an IAM account type MutableProps struct { Secret *string `json:"secret"` + Role Role `json:"role"` UserID *int `json:"userID"` GroupID *int `json:"groupID"` } +func (m MutableProps) Validate() error { + if m.Role != "" && !m.Role.IsValid() { + return s3err.GetAPIError(s3err.ErrAdminInvalidUserRole) + } + + return nil +} + func updateAcc(acc *Account, props MutableProps) { if props.Secret != nil { acc.Secret = *props.Secret @@ -71,6 +82,9 @@ func updateAcc(acc *Account, props MutableProps) { if props.UserID != nil { acc.UserID = *props.UserID } + if props.Role != "" { + acc.Role = props.Role + } } // IAMService is the interface for all IAM service implementations diff --git a/auth/iam_ipa.go b/auth/iam_ipa.go index 1856cae6..efb2ce08 100644 --- a/auth/iam_ipa.go +++ b/auth/iam_ipa.go @@ -30,6 +30,7 @@ import ( "net/http" "net/http/cookiejar" "net/url" + "slices" "strconv" "strings" ) @@ -52,7 +53,6 @@ type IpaIAMService struct { var _ IAMService = &IpaIAMService{} func NewIpaIAMService(rootAcc Account, host, vaultName, username, password string, isInsecure, debug bool) (*IpaIAMService, error) { - ipa := IpaIAMService{ id: 0, version: IpaVersion, @@ -102,13 +102,7 @@ func NewIpaIAMService(rootAcc Account, host, vaultName, username, password strin ipa.kraTransportKey = cert.PublicKey.(*rsa.PublicKey) - isSupported := false - for _, algo := range vaultConfig.Wrapping_supported_algorithms { - if algo == "aes-128-cbc" { - isSupported = true - break - } - } + isSupported := slices.Contains(vaultConfig.Wrapping_supported_algorithms, "aes-128-cbc") if !isSupported { return nil, diff --git a/auth/iam_ldap.go b/auth/iam_ldap.go index 576c7c15..1be77fb5 100644 --- a/auth/iam_ldap.go +++ b/auth/iam_ldap.go @@ -139,6 +139,9 @@ func (ld *LdapIAMService) UpdateUserAccount(access string, props MutableProps) e if props.UserID != nil { req.Replace(ld.userIdAtr, []string{fmt.Sprint(*props.UserID)}) } + if props.Role != "" { + req.Replace(ld.roleAtr, []string{string(props.Role)}) + } err := ld.conn.Modify(req) //TODO: Handle non existing user case diff --git a/cmd/versitygw/admin.go b/cmd/versitygw/admin.go index dddc3aff..612456d5 100644 --- a/cmd/versitygw/admin.go +++ b/cmd/versitygw/admin.go @@ -100,6 +100,11 @@ func adminCommand() *cli.Command { Usage: "secret access key for the new user", Aliases: []string{"s"}, }, + &cli.StringFlag{ + Name: "role", + Usage: "the new user role", + Aliases: []string{"r"}, + }, &cli.IntFlag{ Name: "user-id", Usage: "userID for the new user", @@ -311,8 +316,14 @@ func deleteUser(ctx *cli.Context) error { } func updateUser(ctx *cli.Context) error { - access, secret, userId, groupId := ctx.String("access"), ctx.String("secret"), ctx.Int("user-id"), ctx.Int("group-id") + access, secret, userId, groupId, role := ctx.String("access"), ctx.String("secret"), ctx.Int("user-id"), ctx.Int("group-id"), auth.Role(ctx.String("role")) props := auth.MutableProps{} + if ctx.IsSet("role") { + if !role.IsValid() { + return fmt.Errorf("invalid user role: %v", role) + } + props.Role = role + } if ctx.IsSet("secret") { props.Secret = &secret } diff --git a/s3api/controllers/admin.go b/s3api/controllers/admin.go index fda224da..9aada79f 100644 --- a/s3api/controllers/admin.go +++ b/s3api/controllers/admin.go @@ -100,7 +100,16 @@ func (c AdminController) UpdateUser(ctx *fiber.Ctx) error { }) } - err := c.iam.UpdateUserAccount(access, props) + err := props.Validate() + if err != nil { + return SendResponse(ctx, s3err.GetAPIError(s3err.ErrAdminInvalidUserRole), + &MetaOpts{ + Logger: c.l, + Action: metrics.ActionAdminUpdateUser, + }) + } + + err = c.iam.UpdateUserAccount(access, props) if err != nil { if strings.Contains(err.Error(), "user not found") { err = s3err.GetAPIError(s3err.ErrAdminUserNotFound) diff --git a/s3api/router.go b/s3api/router.go index 448bf667..f640cb67 100644 --- a/s3api/router.go +++ b/s3api/router.go @@ -42,7 +42,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ app.Patch("/delete-user", middlewares.IsAdmin(logger), adminController.DeleteUser) // UpdateUser admin api - app.Patch("update-user", middlewares.IsAdmin(logger), adminController.UpdateUser) + app.Patch("/update-user", middlewares.IsAdmin(logger), adminController.UpdateUser) // ListUsers admin api app.Patch("/list-users", middlewares.IsAdmin(logger), adminController.ListUsers)