user.go 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290
  1. package api
  2. import (
  3. "github.com/grafana/grafana/pkg/api/dtos"
  4. "github.com/grafana/grafana/pkg/bus"
  5. "github.com/grafana/grafana/pkg/middleware"
  6. m "github.com/grafana/grafana/pkg/models"
  7. "github.com/grafana/grafana/pkg/setting"
  8. "github.com/grafana/grafana/pkg/util"
  9. )
  10. // GET /api/user (current authenticated user)
  11. func GetSignedInUser(c *middleware.Context) Response {
  12. return getUserUserProfile(c.UserId)
  13. }
  14. // GET /api/users/:id
  15. func GetUserById(c *middleware.Context) Response {
  16. return getUserUserProfile(c.ParamsInt64(":id"))
  17. }
  18. func getUserUserProfile(userId int64) Response {
  19. query := m.GetUserProfileQuery{UserId: userId}
  20. if err := bus.Dispatch(&query); err != nil {
  21. if err == m.ErrUserNotFound {
  22. return ApiError(404, m.ErrUserNotFound.Error(), nil)
  23. }
  24. return ApiError(500, "Failed to get user", err)
  25. }
  26. return Json(200, query.Result)
  27. }
  28. // GET /api/users/lookup
  29. func GetUserByLoginOrEmail(c *middleware.Context) Response {
  30. query := m.GetUserByLoginQuery{LoginOrEmail: c.Query("loginOrEmail")}
  31. if err := bus.Dispatch(&query); err != nil {
  32. if err == m.ErrUserNotFound {
  33. return ApiError(404, m.ErrUserNotFound.Error(), nil)
  34. }
  35. return ApiError(500, "Failed to get user", err)
  36. }
  37. user := query.Result
  38. result := m.UserProfileDTO{
  39. Id: user.Id,
  40. Name: user.Name,
  41. Email: user.Email,
  42. Login: user.Login,
  43. Theme: user.Theme,
  44. IsGrafanaAdmin: user.IsAdmin,
  45. OrgId: user.OrgId,
  46. }
  47. return Json(200, &result)
  48. }
  49. // POST /api/user
  50. func UpdateSignedInUser(c *middleware.Context, cmd m.UpdateUserCommand) Response {
  51. if setting.AuthProxyEnabled {
  52. if setting.AuthProxyHeaderProperty == "email" && cmd.Email != c.Email {
  53. return ApiError(400, "Not allowed to change email when auth proxy is using email property", nil)
  54. }
  55. if setting.AuthProxyHeaderProperty == "username" && cmd.Login != c.Login {
  56. return ApiError(400, "Not allowed to change username when auth proxy is using username property", nil)
  57. }
  58. }
  59. cmd.UserId = c.UserId
  60. return handleUpdateUser(cmd)
  61. }
  62. // POST /api/users/:id
  63. func UpdateUser(c *middleware.Context, cmd m.UpdateUserCommand) Response {
  64. cmd.UserId = c.ParamsInt64(":id")
  65. return handleUpdateUser(cmd)
  66. }
  67. //POST /api/users/:id/using/:orgId
  68. func UpdateUserActiveOrg(c *middleware.Context) Response {
  69. userId := c.ParamsInt64(":id")
  70. orgId := c.ParamsInt64(":orgId")
  71. if !validateUsingOrg(userId, orgId) {
  72. return ApiError(401, "Not a valid organization", nil)
  73. }
  74. cmd := m.SetUsingOrgCommand{UserId: userId, OrgId: orgId}
  75. if err := bus.Dispatch(&cmd); err != nil {
  76. return ApiError(500, "Failed to change active organization", err)
  77. }
  78. return ApiSuccess("Active organization changed")
  79. }
  80. func handleUpdateUser(cmd m.UpdateUserCommand) Response {
  81. if len(cmd.Login) == 0 {
  82. cmd.Login = cmd.Email
  83. if len(cmd.Login) == 0 {
  84. return ApiError(400, "Validation error, need to specify either username or email", nil)
  85. }
  86. }
  87. if err := bus.Dispatch(&cmd); err != nil {
  88. return ApiError(500, "Failed to update user", err)
  89. }
  90. return ApiSuccess("User updated")
  91. }
  92. // GET /api/user/orgs
  93. func GetSignedInUserOrgList(c *middleware.Context) Response {
  94. return getUserOrgList(c.UserId)
  95. }
  96. // GET /api/user/:id/orgs
  97. func GetUserOrgList(c *middleware.Context) Response {
  98. return getUserOrgList(c.ParamsInt64(":id"))
  99. }
  100. func getUserOrgList(userId int64) Response {
  101. query := m.GetUserOrgListQuery{UserId: userId}
  102. if err := bus.Dispatch(&query); err != nil {
  103. return ApiError(500, "Failed to get user organizations", err)
  104. }
  105. return Json(200, query.Result)
  106. }
  107. func validateUsingOrg(userId int64, orgId int64) bool {
  108. query := m.GetUserOrgListQuery{UserId: userId}
  109. if err := bus.Dispatch(&query); err != nil {
  110. return false
  111. }
  112. // validate that the org id in the list
  113. valid := false
  114. for _, other := range query.Result {
  115. if other.OrgId == orgId {
  116. valid = true
  117. }
  118. }
  119. return valid
  120. }
  121. // POST /api/user/using/:id
  122. func UserSetUsingOrg(c *middleware.Context) Response {
  123. orgId := c.ParamsInt64(":id")
  124. if !validateUsingOrg(c.UserId, orgId) {
  125. return ApiError(401, "Not a valid organization", nil)
  126. }
  127. cmd := m.SetUsingOrgCommand{UserId: c.UserId, OrgId: orgId}
  128. if err := bus.Dispatch(&cmd); err != nil {
  129. return ApiError(500, "Failed to change active organization", err)
  130. }
  131. return ApiSuccess("Active organization changed")
  132. }
  133. // GET /profile/switch-org/:id
  134. func ChangeActiveOrgAndRedirectToHome(c *middleware.Context) {
  135. orgId := c.ParamsInt64(":id")
  136. if !validateUsingOrg(c.UserId, orgId) {
  137. NotFoundHandler(c)
  138. }
  139. cmd := m.SetUsingOrgCommand{UserId: c.UserId, OrgId: orgId}
  140. if err := bus.Dispatch(&cmd); err != nil {
  141. NotFoundHandler(c)
  142. }
  143. c.Redirect(setting.AppSubUrl + "/")
  144. }
  145. func ChangeUserPassword(c *middleware.Context, cmd m.ChangeUserPasswordCommand) Response {
  146. if setting.LdapEnabled || setting.AuthProxyEnabled {
  147. return ApiError(400, "Not allowed to change password when LDAP or Auth Proxy is enabled", nil)
  148. }
  149. userQuery := m.GetUserByIdQuery{Id: c.UserId}
  150. if err := bus.Dispatch(&userQuery); err != nil {
  151. return ApiError(500, "Could not read user from database", err)
  152. }
  153. passwordHashed := util.EncodePassword(cmd.OldPassword, userQuery.Result.Salt)
  154. if passwordHashed != userQuery.Result.Password {
  155. return ApiError(401, "Invalid old password", nil)
  156. }
  157. password := m.Password(cmd.NewPassword)
  158. if password.IsWeak() {
  159. return ApiError(400, "New password is too short", nil)
  160. }
  161. cmd.UserId = c.UserId
  162. cmd.NewPassword = util.EncodePassword(cmd.NewPassword, userQuery.Result.Salt)
  163. if err := bus.Dispatch(&cmd); err != nil {
  164. return ApiError(500, "Failed to change user password", err)
  165. }
  166. return ApiSuccess("User password changed")
  167. }
  168. // GET /api/users
  169. func SearchUsers(c *middleware.Context) Response {
  170. query, err := searchUser(c)
  171. if err != nil {
  172. return ApiError(500, "Failed to fetch users", err)
  173. }
  174. return Json(200, query.Result.Users)
  175. }
  176. // GET /api/users/search
  177. func SearchUsersWithPaging(c *middleware.Context) Response {
  178. query, err := searchUser(c)
  179. if err != nil {
  180. return ApiError(500, "Failed to fetch users", err)
  181. }
  182. return Json(200, query.Result)
  183. }
  184. func searchUser(c *middleware.Context) (*m.SearchUsersQuery, error) {
  185. perPage := c.QueryInt("perpage")
  186. if perPage <= 0 {
  187. perPage = 1000
  188. }
  189. page := c.QueryInt("page")
  190. if page < 1 {
  191. page = 1
  192. }
  193. searchQuery := c.Query("query")
  194. query := &m.SearchUsersQuery{Query: searchQuery, Page: page, Limit: perPage}
  195. if err := bus.Dispatch(query); err != nil {
  196. return nil, err
  197. }
  198. for _, user := range query.Result.Users {
  199. user.AvatarUrl = dtos.GetGravatarUrl(user.Email)
  200. }
  201. query.Result.Page = page
  202. query.Result.PerPage = perPage
  203. return query, nil
  204. }
  205. func SetHelpFlag(c *middleware.Context) Response {
  206. flag := c.ParamsInt64(":id")
  207. bitmask := &c.HelpFlags1
  208. bitmask.AddFlag(m.HelpFlags1(flag))
  209. cmd := m.SetUserHelpFlagCommand{
  210. UserId: c.UserId,
  211. HelpFlags1: *bitmask,
  212. }
  213. if err := bus.Dispatch(&cmd); err != nil {
  214. return ApiError(500, "Failed to update help flag", err)
  215. }
  216. return Json(200, &util.DynMap{"message": "Help flag set", "helpFlags1": cmd.HelpFlags1})
  217. }
  218. func ClearHelpFlags(c *middleware.Context) Response {
  219. cmd := m.SetUserHelpFlagCommand{
  220. UserId: c.UserId,
  221. HelpFlags1: m.HelpFlags1(0),
  222. }
  223. if err := bus.Dispatch(&cmd); err != nil {
  224. return ApiError(500, "Failed to update help flag", err)
  225. }
  226. return Json(200, &util.DynMap{"message": "Help flag set", "helpFlags1": cmd.HelpFlags1})
  227. }