user_management.go 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338
  1. package dash
  2. import (
  3. "context"
  4. "crypto/rand"
  5. "encoding/base64"
  6. "fmt"
  7. "time"
  8. "github.com/seaweedfs/seaweedfs/weed/credential"
  9. "github.com/seaweedfs/seaweedfs/weed/pb/iam_pb"
  10. )
  11. // CreateObjectStoreUser creates a new user using the credential manager
  12. func (s *AdminServer) CreateObjectStoreUser(req CreateUserRequest) (*ObjectStoreUser, error) {
  13. if s.credentialManager == nil {
  14. return nil, fmt.Errorf("credential manager not available")
  15. }
  16. ctx := context.Background()
  17. // Create new identity
  18. newIdentity := &iam_pb.Identity{
  19. Name: req.Username,
  20. Actions: req.Actions,
  21. }
  22. // Add account if email is provided
  23. if req.Email != "" {
  24. newIdentity.Account = &iam_pb.Account{
  25. Id: generateAccountId(),
  26. DisplayName: req.Username,
  27. EmailAddress: req.Email,
  28. }
  29. }
  30. // Generate access key if requested
  31. var accessKey, secretKey string
  32. if req.GenerateKey {
  33. accessKey = generateAccessKey()
  34. secretKey = generateSecretKey()
  35. newIdentity.Credentials = []*iam_pb.Credential{
  36. {
  37. AccessKey: accessKey,
  38. SecretKey: secretKey,
  39. },
  40. }
  41. }
  42. // Create user using credential manager
  43. err := s.credentialManager.CreateUser(ctx, newIdentity)
  44. if err != nil {
  45. if err == credential.ErrUserAlreadyExists {
  46. return nil, fmt.Errorf("user %s already exists", req.Username)
  47. }
  48. return nil, fmt.Errorf("failed to create user: %w", err)
  49. }
  50. // Return created user
  51. user := &ObjectStoreUser{
  52. Username: req.Username,
  53. Email: req.Email,
  54. AccessKey: accessKey,
  55. SecretKey: secretKey,
  56. Permissions: req.Actions,
  57. }
  58. return user, nil
  59. }
  60. // UpdateObjectStoreUser updates an existing user
  61. func (s *AdminServer) UpdateObjectStoreUser(username string, req UpdateUserRequest) (*ObjectStoreUser, error) {
  62. if s.credentialManager == nil {
  63. return nil, fmt.Errorf("credential manager not available")
  64. }
  65. ctx := context.Background()
  66. // Get existing user
  67. identity, err := s.credentialManager.GetUser(ctx, username)
  68. if err != nil {
  69. if err == credential.ErrUserNotFound {
  70. return nil, fmt.Errorf("user %s not found", username)
  71. }
  72. return nil, fmt.Errorf("failed to get user: %w", err)
  73. }
  74. // Create updated identity
  75. updatedIdentity := &iam_pb.Identity{
  76. Name: identity.Name,
  77. Account: identity.Account,
  78. Credentials: identity.Credentials,
  79. Actions: identity.Actions,
  80. }
  81. // Update actions if provided
  82. if len(req.Actions) > 0 {
  83. updatedIdentity.Actions = req.Actions
  84. }
  85. // Update email if provided
  86. if req.Email != "" {
  87. if updatedIdentity.Account == nil {
  88. updatedIdentity.Account = &iam_pb.Account{
  89. Id: generateAccountId(),
  90. DisplayName: username,
  91. }
  92. }
  93. updatedIdentity.Account.EmailAddress = req.Email
  94. }
  95. // Update user using credential manager
  96. err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity)
  97. if err != nil {
  98. return nil, fmt.Errorf("failed to update user: %w", err)
  99. }
  100. // Return updated user
  101. user := &ObjectStoreUser{
  102. Username: username,
  103. Email: req.Email,
  104. Permissions: updatedIdentity.Actions,
  105. }
  106. // Get first access key for display
  107. if len(updatedIdentity.Credentials) > 0 {
  108. user.AccessKey = updatedIdentity.Credentials[0].AccessKey
  109. user.SecretKey = updatedIdentity.Credentials[0].SecretKey
  110. }
  111. return user, nil
  112. }
  113. // DeleteObjectStoreUser deletes a user using the credential manager
  114. func (s *AdminServer) DeleteObjectStoreUser(username string) error {
  115. if s.credentialManager == nil {
  116. return fmt.Errorf("credential manager not available")
  117. }
  118. ctx := context.Background()
  119. // Delete user using credential manager
  120. err := s.credentialManager.DeleteUser(ctx, username)
  121. if err != nil {
  122. if err == credential.ErrUserNotFound {
  123. return fmt.Errorf("user %s not found", username)
  124. }
  125. return fmt.Errorf("failed to delete user: %w", err)
  126. }
  127. return nil
  128. }
  129. // GetObjectStoreUserDetails returns detailed information about a user
  130. func (s *AdminServer) GetObjectStoreUserDetails(username string) (*UserDetails, error) {
  131. if s.credentialManager == nil {
  132. return nil, fmt.Errorf("credential manager not available")
  133. }
  134. ctx := context.Background()
  135. // Get user using credential manager
  136. identity, err := s.credentialManager.GetUser(ctx, username)
  137. if err != nil {
  138. if err == credential.ErrUserNotFound {
  139. return nil, fmt.Errorf("user %s not found", username)
  140. }
  141. return nil, fmt.Errorf("failed to get user: %w", err)
  142. }
  143. details := &UserDetails{
  144. Username: username,
  145. Actions: identity.Actions,
  146. }
  147. // Set email from account if available
  148. if identity.Account != nil {
  149. details.Email = identity.Account.EmailAddress
  150. }
  151. // Convert credentials to access key info
  152. for _, cred := range identity.Credentials {
  153. details.AccessKeys = append(details.AccessKeys, AccessKeyInfo{
  154. AccessKey: cred.AccessKey,
  155. SecretKey: cred.SecretKey,
  156. CreatedAt: time.Now().AddDate(0, -1, 0), // Mock creation date
  157. })
  158. }
  159. return details, nil
  160. }
  161. // CreateAccessKey creates a new access key for a user
  162. func (s *AdminServer) CreateAccessKey(username string) (*AccessKeyInfo, error) {
  163. if s.credentialManager == nil {
  164. return nil, fmt.Errorf("credential manager not available")
  165. }
  166. ctx := context.Background()
  167. // Check if user exists
  168. _, err := s.credentialManager.GetUser(ctx, username)
  169. if err != nil {
  170. if err == credential.ErrUserNotFound {
  171. return nil, fmt.Errorf("user %s not found", username)
  172. }
  173. return nil, fmt.Errorf("failed to get user: %w", err)
  174. }
  175. // Generate new access key
  176. accessKey := generateAccessKey()
  177. secretKey := generateSecretKey()
  178. credential := &iam_pb.Credential{
  179. AccessKey: accessKey,
  180. SecretKey: secretKey,
  181. }
  182. // Create access key using credential manager
  183. err = s.credentialManager.CreateAccessKey(ctx, username, credential)
  184. if err != nil {
  185. return nil, fmt.Errorf("failed to create access key: %w", err)
  186. }
  187. return &AccessKeyInfo{
  188. AccessKey: accessKey,
  189. SecretKey: secretKey,
  190. CreatedAt: time.Now(),
  191. }, nil
  192. }
  193. // DeleteAccessKey deletes an access key for a user
  194. func (s *AdminServer) DeleteAccessKey(username, accessKeyId string) error {
  195. if s.credentialManager == nil {
  196. return fmt.Errorf("credential manager not available")
  197. }
  198. ctx := context.Background()
  199. // Delete access key using credential manager
  200. err := s.credentialManager.DeleteAccessKey(ctx, username, accessKeyId)
  201. if err != nil {
  202. if err == credential.ErrUserNotFound {
  203. return fmt.Errorf("user %s not found", username)
  204. }
  205. if err == credential.ErrAccessKeyNotFound {
  206. return fmt.Errorf("access key %s not found for user %s", accessKeyId, username)
  207. }
  208. return fmt.Errorf("failed to delete access key: %w", err)
  209. }
  210. return nil
  211. }
  212. // GetUserPolicies returns the policies for a user (actions)
  213. func (s *AdminServer) GetUserPolicies(username string) ([]string, error) {
  214. if s.credentialManager == nil {
  215. return nil, fmt.Errorf("credential manager not available")
  216. }
  217. ctx := context.Background()
  218. // Get user using credential manager
  219. identity, err := s.credentialManager.GetUser(ctx, username)
  220. if err != nil {
  221. if err == credential.ErrUserNotFound {
  222. return nil, fmt.Errorf("user %s not found", username)
  223. }
  224. return nil, fmt.Errorf("failed to get user: %w", err)
  225. }
  226. return identity.Actions, nil
  227. }
  228. // UpdateUserPolicies updates the policies (actions) for a user
  229. func (s *AdminServer) UpdateUserPolicies(username string, actions []string) error {
  230. if s.credentialManager == nil {
  231. return fmt.Errorf("credential manager not available")
  232. }
  233. ctx := context.Background()
  234. // Get existing user
  235. identity, err := s.credentialManager.GetUser(ctx, username)
  236. if err != nil {
  237. if err == credential.ErrUserNotFound {
  238. return fmt.Errorf("user %s not found", username)
  239. }
  240. return fmt.Errorf("failed to get user: %w", err)
  241. }
  242. // Create updated identity with new actions
  243. updatedIdentity := &iam_pb.Identity{
  244. Name: identity.Name,
  245. Account: identity.Account,
  246. Credentials: identity.Credentials,
  247. Actions: actions,
  248. }
  249. // Update user using credential manager
  250. err = s.credentialManager.UpdateUser(ctx, username, updatedIdentity)
  251. if err != nil {
  252. return fmt.Errorf("failed to update user policies: %w", err)
  253. }
  254. return nil
  255. }
  256. // Helper functions for generating keys and IDs
  257. func generateAccessKey() string {
  258. // Generate 20-character access key (AWS standard)
  259. const charset = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
  260. b := make([]byte, 20)
  261. for i := range b {
  262. b[i] = charset[randomInt(len(charset))]
  263. }
  264. return string(b)
  265. }
  266. func generateSecretKey() string {
  267. // Generate 40-character secret key (AWS standard)
  268. b := make([]byte, 30) // 30 bytes = 40 characters in base64
  269. rand.Read(b)
  270. return base64.StdEncoding.EncodeToString(b)
  271. }
  272. func generateAccountId() string {
  273. // Generate 12-digit account ID
  274. b := make([]byte, 8)
  275. rand.Read(b)
  276. return fmt.Sprintf("%012d", b[0]<<24|b[1]<<16|b[2]<<8|b[3])
  277. }
  278. func randomInt(max int) int {
  279. b := make([]byte, 1)
  280. rand.Read(b)
  281. return int(b[0]) % max
  282. }