filer_etc_identity.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. package filer_etc
  2. import (
  3. "bytes"
  4. "context"
  5. "fmt"
  6. "github.com/seaweedfs/seaweedfs/weed/credential"
  7. "github.com/seaweedfs/seaweedfs/weed/filer"
  8. "github.com/seaweedfs/seaweedfs/weed/pb/filer_pb"
  9. "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
  10. )
  11. func (store *FilerEtcStore) LoadConfiguration(ctx context.Context) (*iam_pb.S3ApiConfiguration, error) {
  12. s3cfg := &iam_pb.S3ApiConfiguration{}
  13. err := store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  14. var buf bytes.Buffer
  15. if err := filer.ReadEntry(nil, client, filer.IamConfigDirectory, filer.IamIdentityFile, &buf); err != nil {
  16. if err != filer_pb.ErrNotFound {
  17. return err
  18. }
  19. }
  20. if buf.Len() > 0 {
  21. return filer.ParseS3ConfigurationFromBytes(buf.Bytes(), s3cfg)
  22. }
  23. return nil
  24. })
  25. return s3cfg, err
  26. }
  27. func (store *FilerEtcStore) SaveConfiguration(ctx context.Context, config *iam_pb.S3ApiConfiguration) error {
  28. return store.withFilerClient(func(client filer_pb.SeaweedFilerClient) error {
  29. var buf bytes.Buffer
  30. if err := filer.ProtoToText(&buf, config); err != nil {
  31. return fmt.Errorf("failed to marshal configuration: %w", err)
  32. }
  33. return filer.SaveInsideFiler(client, filer.IamConfigDirectory, filer.IamIdentityFile, buf.Bytes())
  34. })
  35. }
  36. func (store *FilerEtcStore) CreateUser(ctx context.Context, identity *iam_pb.Identity) error {
  37. // Load existing configuration
  38. config, err := store.LoadConfiguration(ctx)
  39. if err != nil {
  40. return fmt.Errorf("failed to load configuration: %w", err)
  41. }
  42. // Check if user already exists
  43. for _, existingIdentity := range config.Identities {
  44. if existingIdentity.Name == identity.Name {
  45. return credential.ErrUserAlreadyExists
  46. }
  47. }
  48. // Add new identity
  49. config.Identities = append(config.Identities, identity)
  50. // Save configuration
  51. return store.SaveConfiguration(ctx, config)
  52. }
  53. func (store *FilerEtcStore) GetUser(ctx context.Context, username string) (*iam_pb.Identity, error) {
  54. config, err := store.LoadConfiguration(ctx)
  55. if err != nil {
  56. return nil, fmt.Errorf("failed to load configuration: %w", err)
  57. }
  58. for _, identity := range config.Identities {
  59. if identity.Name == username {
  60. return identity, nil
  61. }
  62. }
  63. return nil, credential.ErrUserNotFound
  64. }
  65. func (store *FilerEtcStore) UpdateUser(ctx context.Context, username string, identity *iam_pb.Identity) error {
  66. config, err := store.LoadConfiguration(ctx)
  67. if err != nil {
  68. return fmt.Errorf("failed to load configuration: %w", err)
  69. }
  70. // Find and update the user
  71. for i, existingIdentity := range config.Identities {
  72. if existingIdentity.Name == username {
  73. config.Identities[i] = identity
  74. return store.SaveConfiguration(ctx, config)
  75. }
  76. }
  77. return credential.ErrUserNotFound
  78. }
  79. func (store *FilerEtcStore) DeleteUser(ctx context.Context, username string) error {
  80. config, err := store.LoadConfiguration(ctx)
  81. if err != nil {
  82. return fmt.Errorf("failed to load configuration: %w", err)
  83. }
  84. // Find and remove the user
  85. for i, identity := range config.Identities {
  86. if identity.Name == username {
  87. config.Identities = append(config.Identities[:i], config.Identities[i+1:]...)
  88. return store.SaveConfiguration(ctx, config)
  89. }
  90. }
  91. return credential.ErrUserNotFound
  92. }
  93. func (store *FilerEtcStore) ListUsers(ctx context.Context) ([]string, error) {
  94. config, err := store.LoadConfiguration(ctx)
  95. if err != nil {
  96. return nil, fmt.Errorf("failed to load configuration: %w", err)
  97. }
  98. var usernames []string
  99. for _, identity := range config.Identities {
  100. usernames = append(usernames, identity.Name)
  101. }
  102. return usernames, nil
  103. }
  104. func (store *FilerEtcStore) GetUserByAccessKey(ctx context.Context, accessKey string) (*iam_pb.Identity, error) {
  105. config, err := store.LoadConfiguration(ctx)
  106. if err != nil {
  107. return nil, fmt.Errorf("failed to load configuration: %w", err)
  108. }
  109. for _, identity := range config.Identities {
  110. for _, credential := range identity.Credentials {
  111. if credential.AccessKey == accessKey {
  112. return identity, nil
  113. }
  114. }
  115. }
  116. return nil, credential.ErrAccessKeyNotFound
  117. }
  118. func (store *FilerEtcStore) CreateAccessKey(ctx context.Context, username string, cred *iam_pb.Credential) error {
  119. config, err := store.LoadConfiguration(ctx)
  120. if err != nil {
  121. return fmt.Errorf("failed to load configuration: %w", err)
  122. }
  123. // Find the user and add the credential
  124. for _, identity := range config.Identities {
  125. if identity.Name == username {
  126. // Check if access key already exists
  127. for _, existingCred := range identity.Credentials {
  128. if existingCred.AccessKey == cred.AccessKey {
  129. return fmt.Errorf("access key %s already exists", cred.AccessKey)
  130. }
  131. }
  132. identity.Credentials = append(identity.Credentials, cred)
  133. return store.SaveConfiguration(ctx, config)
  134. }
  135. }
  136. return credential.ErrUserNotFound
  137. }
  138. func (store *FilerEtcStore) DeleteAccessKey(ctx context.Context, username string, accessKey string) error {
  139. config, err := store.LoadConfiguration(ctx)
  140. if err != nil {
  141. return fmt.Errorf("failed to load configuration: %w", err)
  142. }
  143. // Find the user and remove the credential
  144. for _, identity := range config.Identities {
  145. if identity.Name == username {
  146. for i, cred := range identity.Credentials {
  147. if cred.AccessKey == accessKey {
  148. identity.Credentials = append(identity.Credentials[:i], identity.Credentials[i+1:]...)
  149. return store.SaveConfiguration(ctx, config)
  150. }
  151. }
  152. return credential.ErrAccessKeyNotFound
  153. }
  154. }
  155. return credential.ErrUserNotFound
  156. }