signup.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134
  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/events"
  6. "github.com/grafana/grafana/pkg/infra/metrics"
  7. m "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/setting"
  9. "github.com/grafana/grafana/pkg/util"
  10. )
  11. // GET /api/user/signup/options
  12. func GetSignUpOptions(c *m.ReqContext) Response {
  13. return JSON(200, util.DynMap{
  14. "verifyEmailEnabled": setting.VerifyEmailEnabled,
  15. "autoAssignOrg": setting.AutoAssignOrg,
  16. })
  17. }
  18. // POST /api/user/signup
  19. func SignUp(c *m.ReqContext, form dtos.SignUpForm) Response {
  20. if !setting.AllowUserSignUp {
  21. return Error(401, "User signup is disabled", nil)
  22. }
  23. existing := m.GetUserByLoginQuery{LoginOrEmail: form.Email}
  24. if err := bus.Dispatch(&existing); err == nil {
  25. return Error(422, "User with same email address already exists", nil)
  26. }
  27. cmd := m.CreateTempUserCommand{}
  28. cmd.OrgId = -1
  29. cmd.Email = form.Email
  30. cmd.Status = m.TmpUserSignUpStarted
  31. cmd.InvitedByUserId = c.UserId
  32. cmd.Code = util.GetRandomString(20)
  33. cmd.RemoteAddr = c.Req.RemoteAddr
  34. if err := bus.Dispatch(&cmd); err != nil {
  35. return Error(500, "Failed to create signup", err)
  36. }
  37. bus.Publish(&events.SignUpStarted{
  38. Email: form.Email,
  39. Code: cmd.Code,
  40. })
  41. metrics.M_Api_User_SignUpStarted.Inc()
  42. return JSON(200, util.DynMap{"status": "SignUpCreated"})
  43. }
  44. func (hs *HTTPServer) SignUpStep2(c *m.ReqContext, form dtos.SignUpStep2Form) Response {
  45. if !setting.AllowUserSignUp {
  46. return Error(401, "User signup is disabled", nil)
  47. }
  48. createUserCmd := m.CreateUserCommand{
  49. Email: form.Email,
  50. Login: form.Username,
  51. Name: form.Name,
  52. Password: form.Password,
  53. OrgName: form.OrgName,
  54. }
  55. // verify email
  56. if setting.VerifyEmailEnabled {
  57. if ok, rsp := verifyUserSignUpEmail(form.Email, form.Code); !ok {
  58. return rsp
  59. }
  60. createUserCmd.EmailVerified = true
  61. }
  62. // check if user exists
  63. existing := m.GetUserByLoginQuery{LoginOrEmail: form.Email}
  64. if err := bus.Dispatch(&existing); err == nil {
  65. return Error(401, "User with same email address already exists", nil)
  66. }
  67. // dispatch create command
  68. if err := bus.Dispatch(&createUserCmd); err != nil {
  69. return Error(500, "Failed to create user", err)
  70. }
  71. // publish signup event
  72. user := &createUserCmd.Result
  73. bus.Publish(&events.SignUpCompleted{
  74. Email: user.Email,
  75. Name: user.NameOrFallback(),
  76. })
  77. // mark temp user as completed
  78. if ok, rsp := updateTempUserStatus(form.Code, m.TmpUserCompleted); !ok {
  79. return rsp
  80. }
  81. // check for pending invites
  82. invitesQuery := m.GetTempUsersQuery{Email: form.Email, Status: m.TmpUserInvitePending}
  83. if err := bus.Dispatch(&invitesQuery); err != nil {
  84. return Error(500, "Failed to query database for invites", err)
  85. }
  86. apiResponse := util.DynMap{"message": "User sign up completed successfully", "code": "redirect-to-landing-page"}
  87. for _, invite := range invitesQuery.Result {
  88. if ok, rsp := applyUserInvite(user, invite, false); !ok {
  89. return rsp
  90. }
  91. apiResponse["code"] = "redirect-to-select-org"
  92. }
  93. hs.loginUserWithUser(user, c)
  94. metrics.M_Api_User_SignUpCompleted.Inc()
  95. return JSON(200, apiResponse)
  96. }
  97. func verifyUserSignUpEmail(email string, code string) (bool, Response) {
  98. query := m.GetTempUserByCodeQuery{Code: code}
  99. if err := bus.Dispatch(&query); err != nil {
  100. if err == m.ErrTempUserNotFound {
  101. return false, Error(404, "Invalid email verification code", nil)
  102. }
  103. return false, Error(500, "Failed to read temp user", err)
  104. }
  105. tempUser := query.Result
  106. if tempUser.Email != email {
  107. return false, Error(404, "Email verification code does not match email", nil)
  108. }
  109. return true, nil
  110. }