ext_user.go 4.6 KB

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