diff options
Diffstat (limited to 'weed/admin/dash/user_management.go')
| -rw-r--r-- | weed/admin/dash/user_management.go | 357 |
1 files changed, 124 insertions, 233 deletions
diff --git a/weed/admin/dash/user_management.go b/weed/admin/dash/user_management.go index 007faeed8..1ed0b071e 100644 --- a/weed/admin/dash/user_management.go +++ b/weed/admin/dash/user_management.go @@ -1,45 +1,23 @@ package dash import ( - "bytes" + "context" "crypto/rand" "encoding/base64" "fmt" "time" - "github.com/seaweedfs/seaweedfs/weed/filer" - "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb" + "github.com/seaweedfs/seaweedfs/weed/credential" "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb" ) -// CreateObjectStoreUser creates a new user in identity.json +// CreateObjectStoreUser creates a new user using the credential manager func (s *AdminServer) CreateObjectStoreUser(req CreateUserRequest) (*ObjectStoreUser, error) { - s3cfg := &iam_pb.S3ApiConfiguration{} - - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - if err != filer_pb.ErrNotFound { - return err - } - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) - - if err != nil { - return nil, fmt.Errorf("failed to load IAM configuration: %v", err) + if s.credentialManager == nil { + return nil, fmt.Errorf("credential manager not available") } - // Check if user already exists - for _, identity := range s3cfg.Identities { - if identity.Name == req.Username { - return nil, fmt.Errorf("user %s already exists", req.Username) - } - } + ctx := context.Background() // Create new identity newIdentity := &iam_pb.Identity{ @@ -69,13 +47,13 @@ func (s *AdminServer) CreateObjectStoreUser(req CreateUserRequest) (*ObjectStore } } - // Add to configuration - s3cfg.Identities = append(s3cfg.Identities, newIdentity) - - // Save configuration - err = s.saveS3Configuration(s3cfg) + // Create user using credential manager + err := s.credentialManager.CreateUser(ctx, newIdentity) if err != nil { - return nil, fmt.Errorf("failed to save IAM configuration: %v", err) + if err == credential.ErrUserAlreadyExists { + return nil, fmt.Errorf("user %s already exists", req.Username) + } + return nil, fmt.Errorf("failed to create user: %v", err) } // Return created user @@ -92,35 +70,27 @@ func (s *AdminServer) CreateObjectStoreUser(req CreateUserRequest) (*ObjectStore // UpdateObjectStoreUser updates an existing user func (s *AdminServer) UpdateObjectStoreUser(username string, req UpdateUserRequest) (*ObjectStoreUser, error) { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return nil, fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Get existing user + identity, err := s.credentialManager.GetUser(ctx, username) if err != nil { - return nil, fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find and update user - var updatedIdentity *iam_pb.Identity - for _, identity := range s3cfg.Identities { - if identity.Name == username { - updatedIdentity = identity - break + if err == credential.ErrUserNotFound { + return nil, fmt.Errorf("user %s not found", username) } + return nil, fmt.Errorf("failed to get user: %v", err) } - if updatedIdentity == nil { - return nil, fmt.Errorf("user %s not found", username) + // Create updated identity + updatedIdentity := &iam_pb.Identity{ + Name: identity.Name, + Account: identity.Account, + Credentials: identity.Credentials, + Actions: identity.Actions, } // Update actions if provided @@ -139,10 +109,10 @@ func (s *AdminServer) UpdateObjectStoreUser(username string, req UpdateUserReque updatedIdentity.Account.EmailAddress = req.Email } - // Save configuration - err = s.saveS3Configuration(s3cfg) + // Update user using credential manager + err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity) if err != nil { - return nil, fmt.Errorf("failed to save IAM configuration: %v", err) + return nil, fmt.Errorf("failed to update user: %v", err) } // Return updated user @@ -161,142 +131,95 @@ func (s *AdminServer) UpdateObjectStoreUser(username string, req UpdateUserReque return user, nil } -// DeleteObjectStoreUser deletes a user from identity.json +// DeleteObjectStoreUser deletes a user using the credential manager func (s *AdminServer) DeleteObjectStoreUser(username string) error { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Delete user using credential manager + err := s.credentialManager.DeleteUser(ctx, username) if err != nil { - return fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find and remove user - found := false - for i, identity := range s3cfg.Identities { - if identity.Name == username { - s3cfg.Identities = append(s3cfg.Identities[:i], s3cfg.Identities[i+1:]...) - found = true - break + if err == credential.ErrUserNotFound { + return fmt.Errorf("user %s not found", username) } + return fmt.Errorf("failed to delete user: %v", err) } - if !found { - return fmt.Errorf("user %s not found", username) - } - - // Save configuration - return s.saveS3Configuration(s3cfg) + return nil } // GetObjectStoreUserDetails returns detailed information about a user func (s *AdminServer) GetObjectStoreUserDetails(username string) (*UserDetails, error) { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return nil, fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Get user using credential manager + identity, err := s.credentialManager.GetUser(ctx, username) if err != nil { - return nil, fmt.Errorf("failed to load IAM configuration: %v", err) + if err == credential.ErrUserNotFound { + return nil, fmt.Errorf("user %s not found", username) + } + return nil, fmt.Errorf("failed to get user: %v", err) } - // Find user - for _, identity := range s3cfg.Identities { - if identity.Name == username { - details := &UserDetails{ - Username: username, - Actions: identity.Actions, - } - - // Set email from account if available - if identity.Account != nil { - details.Email = identity.Account.EmailAddress - } + details := &UserDetails{ + Username: username, + Actions: identity.Actions, + } - // Convert credentials to access key info - for _, cred := range identity.Credentials { - details.AccessKeys = append(details.AccessKeys, AccessKeyInfo{ - AccessKey: cred.AccessKey, - SecretKey: cred.SecretKey, - CreatedAt: time.Now().AddDate(0, -1, 0), // Mock creation date - }) - } + // Set email from account if available + if identity.Account != nil { + details.Email = identity.Account.EmailAddress + } - return details, nil - } + // Convert credentials to access key info + for _, cred := range identity.Credentials { + details.AccessKeys = append(details.AccessKeys, AccessKeyInfo{ + AccessKey: cred.AccessKey, + SecretKey: cred.SecretKey, + CreatedAt: time.Now().AddDate(0, -1, 0), // Mock creation date + }) } - return nil, fmt.Errorf("user %s not found", username) + return details, nil } // CreateAccessKey creates a new access key for a user func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return nil, fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Check if user exists + _, err := s.credentialManager.GetUser(ctx, username) if err != nil { - return nil, fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find user - var targetIdentity *iam_pb.Identity - for _, identity := range s3cfg.Identities { - if identity.Name == username { - targetIdentity = identity - break + if err == credential.ErrUserNotFound { + return nil, fmt.Errorf("user %s not found", username) } - } - - if targetIdentity == nil { - return nil, fmt.Errorf("user %s not found", username) + return nil, fmt.Errorf("failed to get user: %v", err) } // Generate new access key accessKey := generateAccessKey() secretKey := generateSecretKey() - newCredential := &iam_pb.Credential{ + credential := &iam_pb.Credential{ AccessKey: accessKey, SecretKey: secretKey, } - // Add to user's credentials - targetIdentity.Credentials = append(targetIdentity.Credentials, newCredential) - - // Save configuration - err = s.saveS3Configuration(s3cfg) + // Create access key using credential manager + err = s.credentialManager.CreateAccessKey(ctx, username, credential) if err != nil { - return nil, fmt.Errorf("failed to save IAM configuration: %v", err) + return nil, fmt.Errorf("failed to create access key: %v", err) } return &AccessKeyInfo{ @@ -308,111 +231,79 @@ func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) { // DeleteAccessKey deletes an access key for a user func (s *AdminServer) DeleteAccessKey(username, accessKeyId string) error { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Delete access key using credential manager + err := s.credentialManager.DeleteAccessKey(ctx, username, accessKeyId) if err != nil { - return fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find user and remove access key - for _, identity := range s3cfg.Identities { - if identity.Name == username { - for i, cred := range identity.Credentials { - if cred.AccessKey == accessKeyId { - identity.Credentials = append(identity.Credentials[:i], identity.Credentials[i+1:]...) - return s.saveS3Configuration(s3cfg) - } - } + if err == credential.ErrUserNotFound { + return fmt.Errorf("user %s not found", username) + } + if err == credential.ErrAccessKeyNotFound { return fmt.Errorf("access key %s not found for user %s", accessKeyId, username) } + return fmt.Errorf("failed to delete access key: %v", err) } - return fmt.Errorf("user %s not found", username) + return nil } // GetUserPolicies returns the policies for a user (actions) func (s *AdminServer) GetUserPolicies(username string) ([]string, error) { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return nil, fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Get user using credential manager + identity, err := s.credentialManager.GetUser(ctx, username) if err != nil { - return nil, fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find user and return policies - for _, identity := range s3cfg.Identities { - if identity.Name == username { - return identity.Actions, nil + if err == credential.ErrUserNotFound { + return nil, fmt.Errorf("user %s not found", username) } + return nil, fmt.Errorf("failed to get user: %v", err) } - return nil, fmt.Errorf("user %s not found", username) + return identity.Actions, nil } // UpdateUserPolicies updates the policies (actions) for a user func (s *AdminServer) UpdateUserPolicies(username string, actions []string) error { - s3cfg := &iam_pb.S3ApiConfiguration{} + if s.credentialManager == nil { + return fmt.Errorf("credential manager not available") + } - // Load existing configuration - err := s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil { - return err - } - if buf.Len() > 0 { - return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg) - } - return nil - }) + ctx := context.Background() + // Get existing user + identity, err := s.credentialManager.GetUser(ctx, username) if err != nil { - return fmt.Errorf("failed to load IAM configuration: %v", err) - } - - // Find user and update policies - for _, identity := range s3cfg.Identities { - if identity.Name == username { - identity.Actions = actions - return s.saveS3Configuration(s3cfg) + if err == credential.ErrUserNotFound { + return fmt.Errorf("user %s not found", username) } + return fmt.Errorf("failed to get user: %v", err) } - return fmt.Errorf("user %s not found", username) -} + // Create updated identity with new actions + updatedIdentity := &iam_pb.Identity{ + Name: identity.Name, + Account: identity.Account, + Credentials: identity.Credentials, + Actions: actions, + } -// saveS3Configuration saves the S3 configuration to identity.json -func (s *AdminServer) saveS3Configuration(s3cfg *iam_pb.S3ApiConfiguration) error { - return s.WithFilerClient(func(client filer_pb.SeaweedFilerClient) error { - var buf bytes.Buffer - if err := filer.ProtoToText(&buf, s3cfg); err != nil { - return fmt.Errorf("failed to marshal configuration: %v", err) - } + // Update user using credential manager + err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity) + if err != nil { + return fmt.Errorf("failed to update user policies: %v", err) + } - return filer.SaveInsideFiler(client, filer.IamConfigDirectory, filer.IamIdentityFile, buf.Bytes()) - }) + return nil } // Helper functions for generating keys and IDs |
