ext_user.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  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. func init() {
  10. bus.AddHandler("auth", UpsertUser)
  11. }
  12. func UpsertUser(cmd *m.UpsertUserCommand) error {
  13. extUser := cmd.ExternalUser
  14. userQuery := &m.GetUserByAuthInfoQuery{
  15. AuthModule: extUser.AuthModule,
  16. AuthId: extUser.AuthId,
  17. UserId: extUser.UserId,
  18. Email: extUser.Email,
  19. Login: extUser.Login,
  20. }
  21. err := bus.Dispatch(userQuery)
  22. if err != nil {
  23. if err != m.ErrUserNotFound {
  24. return err
  25. }
  26. if !cmd.SignupAllowed {
  27. log.Warn(fmt.Sprintf("Not allowing %s login, user not found in internal user database and allow signup = false", extUser.AuthModule))
  28. return ErrInvalidCredentials
  29. }
  30. limitReached, err := quota.QuotaReached(cmd.ReqContext, "user")
  31. if err != nil {
  32. log.Warn("Error getting user quota", "err", err)
  33. return ErrGettingUserQuota
  34. }
  35. if limitReached {
  36. return ErrUsersQuotaReached
  37. }
  38. cmd.Result, err = createUser(extUser)
  39. if err != nil {
  40. return err
  41. }
  42. if extUser.AuthModule != "" && extUser.AuthId != "" {
  43. cmd2 := &m.SetAuthInfoCommand{
  44. UserId: cmd.Result.Id,
  45. AuthModule: extUser.AuthModule,
  46. AuthId: extUser.AuthId,
  47. }
  48. if err := bus.Dispatch(cmd2); err != nil {
  49. return err
  50. }
  51. }
  52. } else {
  53. cmd.Result = userQuery.Result
  54. // sync user info
  55. err = updateUser(cmd.Result, extUser)
  56. if err != nil {
  57. return err
  58. }
  59. }
  60. return syncOrgRoles(cmd.Result, extUser)
  61. }
  62. func createUser(extUser *m.ExternalUserInfo) (*m.User, error) {
  63. cmd := &m.CreateUserCommand{
  64. Login: extUser.Login,
  65. Email: extUser.Email,
  66. Name: extUser.Name,
  67. SkipOrgSetup: len(extUser.OrgRoles) > 0,
  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. user.Login = extUser.Login
  83. needsUpdate = true
  84. }
  85. if extUser.Email != "" && extUser.Email != user.Email {
  86. updateCmd.Email = extUser.Email
  87. user.Email = extUser.Email
  88. needsUpdate = true
  89. }
  90. if extUser.Name != "" && extUser.Name != user.Name {
  91. updateCmd.Name = extUser.Name
  92. user.Name = extUser.Name
  93. needsUpdate = true
  94. }
  95. if needsUpdate {
  96. log.Debug("Syncing user info", "id", user.Id, "update", updateCmd)
  97. err := bus.Dispatch(updateCmd)
  98. if err != nil {
  99. return err
  100. }
  101. }
  102. return nil
  103. }
  104. func syncOrgRoles(user *m.User, extUser *m.ExternalUserInfo) error {
  105. // don't sync org roles if none are specified
  106. if len(extUser.OrgRoles) == 0 {
  107. return nil
  108. }
  109. orgsQuery := &m.GetUserOrgListQuery{UserId: user.Id}
  110. if err := bus.Dispatch(orgsQuery); err != nil {
  111. return err
  112. }
  113. handledOrgIds := map[int64]bool{}
  114. deleteOrgIds := []int64{}
  115. // update existing org roles
  116. for _, org := range orgsQuery.Result {
  117. handledOrgIds[org.OrgId] = true
  118. if extUser.OrgRoles[org.OrgId] == "" {
  119. deleteOrgIds = append(deleteOrgIds, org.OrgId)
  120. } else if extUser.OrgRoles[org.OrgId] != org.Role {
  121. // update role
  122. cmd := &m.UpdateOrgUserCommand{OrgId: org.OrgId, UserId: user.Id, Role: extUser.OrgRoles[org.OrgId]}
  123. if err := bus.Dispatch(cmd); err != nil {
  124. return err
  125. }
  126. }
  127. }
  128. // add any new org roles
  129. for orgId, orgRole := range extUser.OrgRoles {
  130. if _, exists := handledOrgIds[orgId]; exists {
  131. continue
  132. }
  133. // add role
  134. cmd := &m.AddOrgUserCommand{UserId: user.Id, Role: orgRole, OrgId: orgId}
  135. err := bus.Dispatch(cmd)
  136. if err != nil && err != m.ErrOrgNotFound {
  137. return err
  138. }
  139. }
  140. // delete any removed org roles
  141. for _, orgId := range deleteOrgIds {
  142. cmd := &m.RemoveOrgUserCommand{OrgId: orgId, UserId: user.Id}
  143. if err := bus.Dispatch(cmd); err != nil {
  144. return err
  145. }
  146. }
  147. // update user's default org if needed
  148. if _, ok := extUser.OrgRoles[user.OrgId]; !ok {
  149. for orgId := range extUser.OrgRoles {
  150. user.OrgId = orgId
  151. break
  152. }
  153. err := bus.Dispatch(&m.SetUsingOrgCommand{
  154. UserId: user.Id,
  155. OrgId: user.OrgId,
  156. })
  157. if err != nil {
  158. return err
  159. }
  160. }
  161. return nil
  162. }