| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338 |
- package dash
- import (
- "context"
- "crypto/rand"
- "encoding/base64"
- "fmt"
- "time"
- "github.com/seaweedfs/seaweedfs/weed/credential"
- "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
- )
- // CreateObjectStoreUser creates a new user using the credential manager
- func (s *AdminServer) CreateObjectStoreUser(req CreateUserRequest) (*ObjectStoreUser, error) {
- if s.credentialManager == nil {
- return nil, fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Create new identity
- newIdentity := &iam_pb.Identity{
- Name: req.Username,
- Actions: req.Actions,
- }
- // Add account if email is provided
- if req.Email != "" {
- newIdentity.Account = &iam_pb.Account{
- Id: generateAccountId(),
- DisplayName: req.Username,
- EmailAddress: req.Email,
- }
- }
- // Generate access key if requested
- var accessKey, secretKey string
- if req.GenerateKey {
- accessKey = generateAccessKey()
- secretKey = generateSecretKey()
- newIdentity.Credentials = []*iam_pb.Credential{
- {
- AccessKey: accessKey,
- SecretKey: secretKey,
- },
- }
- }
- // Create user using credential manager
- err := s.credentialManager.CreateUser(ctx, newIdentity)
- if err != nil {
- if err == credential.ErrUserAlreadyExists {
- return nil, fmt.Errorf("user %s already exists", req.Username)
- }
- return nil, fmt.Errorf("failed to create user: %w", err)
- }
- // Return created user
- user := &ObjectStoreUser{
- Username: req.Username,
- Email: req.Email,
- AccessKey: accessKey,
- SecretKey: secretKey,
- Permissions: req.Actions,
- }
- return user, nil
- }
- // UpdateObjectStoreUser updates an existing user
- func (s *AdminServer) UpdateObjectStoreUser(username string, req UpdateUserRequest) (*ObjectStoreUser, error) {
- if s.credentialManager == nil {
- return nil, fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Get existing user
- identity, err := s.credentialManager.GetUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return nil, fmt.Errorf("user %s not found", username)
- }
- return nil, fmt.Errorf("failed to get user: %w", err)
- }
- // Create updated identity
- updatedIdentity := &iam_pb.Identity{
- Name: identity.Name,
- Account: identity.Account,
- Credentials: identity.Credentials,
- Actions: identity.Actions,
- }
- // Update actions if provided
- if len(req.Actions) > 0 {
- updatedIdentity.Actions = req.Actions
- }
- // Update email if provided
- if req.Email != "" {
- if updatedIdentity.Account == nil {
- updatedIdentity.Account = &iam_pb.Account{
- Id: generateAccountId(),
- DisplayName: username,
- }
- }
- updatedIdentity.Account.EmailAddress = req.Email
- }
- // Update user using credential manager
- err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity)
- if err != nil {
- return nil, fmt.Errorf("failed to update user: %w", err)
- }
- // Return updated user
- user := &ObjectStoreUser{
- Username: username,
- Email: req.Email,
- Permissions: updatedIdentity.Actions,
- }
- // Get first access key for display
- if len(updatedIdentity.Credentials) > 0 {
- user.AccessKey = updatedIdentity.Credentials[0].AccessKey
- user.SecretKey = updatedIdentity.Credentials[0].SecretKey
- }
- return user, nil
- }
- // DeleteObjectStoreUser deletes a user using the credential manager
- func (s *AdminServer) DeleteObjectStoreUser(username string) error {
- if s.credentialManager == nil {
- return fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Delete user using credential manager
- err := s.credentialManager.DeleteUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return fmt.Errorf("user %s not found", username)
- }
- return fmt.Errorf("failed to delete user: %w", err)
- }
- return nil
- }
- // GetObjectStoreUserDetails returns detailed information about a user
- func (s *AdminServer) GetObjectStoreUserDetails(username string) (*UserDetails, error) {
- if s.credentialManager == nil {
- return nil, fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Get user using credential manager
- identity, err := s.credentialManager.GetUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return nil, fmt.Errorf("user %s not found", username)
- }
- return nil, fmt.Errorf("failed to get user: %w", err)
- }
- details := &UserDetails{
- Username: username,
- Actions: identity.Actions,
- }
- // Set email from account if available
- if identity.Account != nil {
- details.Email = identity.Account.EmailAddress
- }
- // 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 details, nil
- }
- // CreateAccessKey creates a new access key for a user
- func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) {
- if s.credentialManager == nil {
- return nil, fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Check if user exists
- _, err := s.credentialManager.GetUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return nil, fmt.Errorf("user %s not found", username)
- }
- return nil, fmt.Errorf("failed to get user: %w", err)
- }
- // Generate new access key
- accessKey := generateAccessKey()
- secretKey := generateSecretKey()
- credential := &iam_pb.Credential{
- AccessKey: accessKey,
- SecretKey: secretKey,
- }
- // Create access key using credential manager
- err = s.credentialManager.CreateAccessKey(ctx, username, credential)
- if err != nil {
- return nil, fmt.Errorf("failed to create access key: %w", err)
- }
- return &AccessKeyInfo{
- AccessKey: accessKey,
- SecretKey: secretKey,
- CreatedAt: time.Now(),
- }, nil
- }
- // DeleteAccessKey deletes an access key for a user
- func (s *AdminServer) DeleteAccessKey(username, accessKeyId string) error {
- if s.credentialManager == nil {
- return fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Delete access key using credential manager
- err := s.credentialManager.DeleteAccessKey(ctx, username, accessKeyId)
- if err != nil {
- 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: %w", err)
- }
- return nil
- }
- // GetUserPolicies returns the policies for a user (actions)
- func (s *AdminServer) GetUserPolicies(username string) ([]string, error) {
- if s.credentialManager == nil {
- return nil, fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Get user using credential manager
- identity, err := s.credentialManager.GetUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return nil, fmt.Errorf("user %s not found", username)
- }
- return nil, fmt.Errorf("failed to get user: %w", err)
- }
- return identity.Actions, nil
- }
- // UpdateUserPolicies updates the policies (actions) for a user
- func (s *AdminServer) UpdateUserPolicies(username string, actions []string) error {
- if s.credentialManager == nil {
- return fmt.Errorf("credential manager not available")
- }
- ctx := context.Background()
- // Get existing user
- identity, err := s.credentialManager.GetUser(ctx, username)
- if err != nil {
- if err == credential.ErrUserNotFound {
- return fmt.Errorf("user %s not found", username)
- }
- return fmt.Errorf("failed to get user: %w", err)
- }
- // Create updated identity with new actions
- updatedIdentity := &iam_pb.Identity{
- Name: identity.Name,
- Account: identity.Account,
- Credentials: identity.Credentials,
- Actions: actions,
- }
- // Update user using credential manager
- err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity)
- if err != nil {
- return fmt.Errorf("failed to update user policies: %w", err)
- }
- return nil
- }
- // Helper functions for generating keys and IDs
- func generateAccessKey() string {
- // Generate 20-character access key (AWS standard)
- const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
- b := make([]byte, 20)
- for i := range b {
- b[i] = charset[randomInt(len(charset))]
- }
- return string(b)
- }
- func generateSecretKey() string {
- // Generate 40-character secret key (AWS standard)
- b := make([]byte, 30) // 30 bytes = 40 characters in base64
- rand.Read(b)
- return base64.StdEncoding.EncodeToString(b)
- }
- func generateAccountId() string {
- // Generate 12-digit account ID
- b := make([]byte, 8)
- rand.Read(b)
- return fmt.Sprintf("%012d", b[0]<<24|b[1]<<16|b[2]<<8|b[3])
- }
- func randomInt(max int) int {
- b := make([]byte, 1)
- rand.Read(b)
- return int(b[0]) % max
- }
|