ext_user.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. package login
  2. import (
  3. "fmt"
  4. "github.com/grafana/grafana/pkg/bus"
  5. "github.com/grafana/grafana/pkg/log"
  6. m "github.com/grafana/grafana/pkg/models"
  7. "github.com/grafana/grafana/pkg/services/quota"
  8. )
  9. var UpsertUser = func(ctx *m.ReqContext, cmd *m.UpsertUserCommand) error {
  10. extUser := cmd.ExternalUser
  11. userQuery := m.GetUserByAuthInfoQuery{
  12. AuthModule: extUser.AuthModule,
  13. AuthId: extUser.AuthId,
  14. UserId: extUser.UserId,
  15. Email: extUser.Email,
  16. Login: extUser.Login,
  17. }
  18. err := bus.Dispatch(&userQuery)
  19. if err != nil {
  20. if err != m.ErrUserNotFound {
  21. return err
  22. }
  23. if !cmd.SignupAllowed {
  24. log.Warn(fmt.Sprintf("Not allowing %s login, user not found in internal user database and allow signup = false", extUser.AuthModule))
  25. return ErrInvalidCredentials
  26. }
  27. limitReached, err := quota.QuotaReached(ctx, "user")
  28. if err != nil {
  29. log.Warn("Error getting user quota", "err", err)
  30. return ErrGettingUserQuota
  31. }
  32. if limitReached {
  33. return ErrUsersQuotaReached
  34. }
  35. cmd.Result, err = createUser(extUser)
  36. if err != nil {
  37. return err
  38. }
  39. } else {
  40. cmd.Result = userQuery.User
  41. // sync user info
  42. err = updateUser(cmd.Result, extUser)
  43. if err != nil {
  44. return err
  45. }
  46. }
  47. if userQuery.UserAuth == nil && extUser.AuthModule != "" && extUser.AuthId != "" {
  48. cmd2 := m.SetAuthInfoCommand{
  49. UserId: cmd.Result.Id,
  50. AuthModule: extUser.AuthModule,
  51. AuthId: extUser.AuthId,
  52. }
  53. if err := bus.Dispatch(&cmd2); err != nil {
  54. return err
  55. }
  56. }
  57. err = syncOrgRoles(cmd.Result, extUser)
  58. if err != nil {
  59. return err
  60. }
  61. return nil
  62. }
  63. func createUser(extUser *m.ExternalUserInfo) (*m.User, error) {
  64. cmd := m.CreateUserCommand{
  65. Login: extUser.Login,
  66. Email: extUser.Email,
  67. Name: extUser.Name,
  68. }
  69. if err := bus.Dispatch(&cmd); err != nil {
  70. return nil, err
  71. }
  72. return &cmd.Result, nil
  73. }
  74. func updateUser(user *m.User, extUser *m.ExternalUserInfo) error {
  75. // sync user info
  76. updateCmd := m.UpdateUserCommand{
  77. UserId: user.Id,
  78. }
  79. needsUpdate := false
  80. if extUser.Login != "" && extUser.Login != user.Login {
  81. updateCmd.Login = extUser.Login
  82. needsUpdate = true
  83. }
  84. if extUser.Email != "" && extUser.Email != user.Email {
  85. updateCmd.Email = extUser.Email
  86. needsUpdate = true
  87. }
  88. if extUser.Name != "" && extUser.Name != user.Name {
  89. updateCmd.Name = extUser.Name
  90. needsUpdate = true
  91. }
  92. if needsUpdate {
  93. log.Debug("Syncing user info", "id", user.Id, "update", updateCmd)
  94. err := bus.Dispatch(&updateCmd)
  95. if err != nil {
  96. return err
  97. }
  98. }
  99. return nil
  100. }
  101. func syncOrgRoles(user *m.User, extUser *m.ExternalUserInfo) error {
  102. // don't sync org roles if none are specified
  103. if len(extUser.OrgRoles) == 0 {
  104. return nil
  105. }
  106. orgsQuery := m.GetUserOrgListQuery{UserId: user.Id}
  107. if err := bus.Dispatch(&orgsQuery); err != nil {
  108. return err
  109. }
  110. handledOrgIds := map[int64]bool{}
  111. deleteOrgIds := []int64{}
  112. // update existing org roles
  113. for _, org := range orgsQuery.Result {
  114. handledOrgIds[org.OrgId] = true
  115. if extUser.OrgRoles[org.OrgId] == "" {
  116. deleteOrgIds = append(deleteOrgIds, org.OrgId)
  117. } else if extUser.OrgRoles[org.OrgId] != org.Role {
  118. // update role
  119. cmd := m.UpdateOrgUserCommand{OrgId: org.OrgId, UserId: user.Id, Role: extUser.OrgRoles[org.OrgId]}
  120. if err := bus.Dispatch(&cmd); err != nil {
  121. return err
  122. }
  123. }
  124. }
  125. // add any new org roles
  126. for orgId, orgRole := range extUser.OrgRoles {
  127. if _, exists := handledOrgIds[orgId]; exists {
  128. continue
  129. }
  130. // add role
  131. cmd := m.AddOrgUserCommand{UserId: user.Id, Role: orgRole, OrgId: orgId}
  132. err := bus.Dispatch(&cmd)
  133. if err != nil && err != m.ErrOrgNotFound {
  134. return err
  135. }
  136. }
  137. // delete any removed org roles
  138. for _, orgId := range deleteOrgIds {
  139. cmd := m.RemoveOrgUserCommand{OrgId: orgId, UserId: user.Id}
  140. if err := bus.Dispatch(&cmd); err != nil {
  141. return err
  142. }
  143. }
  144. return nil
  145. }