diff --git a/pkg/api/org_invite.go b/pkg/api/org_invite.go index 674c0d1f922..841ab359697 100644 --- a/pkg/api/org_invite.go +++ b/pkg/api/org_invite.go @@ -15,6 +15,7 @@ import ( "github.com/grafana/grafana/pkg/models" ac "github.com/grafana/grafana/pkg/services/accesscontrol" "github.com/grafana/grafana/pkg/services/org" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -31,17 +32,18 @@ import ( // 403: forbiddenError // 500: internalServerError func (hs *HTTPServer) GetPendingOrgInvites(c *models.ReqContext) response.Response { - query := models.GetTempUsersQuery{OrgId: c.OrgID, Status: models.TmpUserInvitePending} + query := tempuser.GetTempUsersQuery{OrgID: c.OrgID, Status: tempuser.TmpUserInvitePending} - if err := hs.tempUserService.GetTempUsersQuery(c.Req.Context(), &query); err != nil { + queryResult, err := hs.tempUserService.GetTempUsersQuery(c.Req.Context(), &query) + if err != nil { return response.Error(500, "Failed to get invites from db", err) } - for _, invite := range query.Result { - invite.Url = setting.ToAbsUrl("invite/" + invite.Code) + for _, invite := range queryResult { + invite.URL = setting.ToAbsUrl("invite/" + invite.Code) } - return response.JSON(http.StatusOK, query.Result) + return response.JSON(http.StatusOK, queryResult) } // swagger:route POST /org/invites org_invites addOrgInvite @@ -91,12 +93,12 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response { return response.Error(400, "Cannot invite when login is disabled.", nil) } - cmd := models.CreateTempUserCommand{} - cmd.OrgId = c.OrgID + cmd := tempuser.CreateTempUserCommand{} + cmd.OrgID = c.OrgID cmd.Email = inviteDto.LoginOrEmail cmd.Name = inviteDto.Name - cmd.Status = models.TmpUserInvitePending - cmd.InvitedByUserId = c.UserID + cmd.Status = tempuser.TmpUserInvitePending + cmd.InvitedByUserID = c.UserID cmd.Code, err = util.GetRandomString(30) if err != nil { return response.Error(500, "Could not generate random string", err) @@ -104,7 +106,8 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response { cmd.Role = inviteDto.Role cmd.RemoteAddr = c.RemoteAddr() - if err := hs.tempUserService.CreateTempUser(c.Req.Context(), &cmd); err != nil { + cmdResult, err := hs.tempUserService.CreateTempUser(c.Req.Context(), &cmd) + if err != nil { return response.Error(500, "Failed to save invite to database", err) } @@ -130,7 +133,7 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response { return response.Error(500, "Failed to send email invite", err) } - emailSentCmd := models.UpdateTempUserWithEmailSentCommand{Code: cmd.Result.Code} + emailSentCmd := tempuser.UpdateTempUserWithEmailSentCommand{Code: cmdResult.Code} if err := hs.tempUserService.UpdateTempUserWithEmailSent(c.Req.Context(), &emailSentCmd); err != nil { return response.Error(500, "Failed to update invite with email sent info", err) } @@ -184,7 +187,7 @@ func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *user.U // 404: notFoundError // 500: internalServerError func (hs *HTTPServer) RevokeInvite(c *models.ReqContext) response.Response { - if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), web.Params(c.Req)[":code"], models.TmpUserRevoked); !ok { + if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), web.Params(c.Req)[":code"], tempuser.TmpUserRevoked); !ok { return rsp } @@ -195,16 +198,17 @@ func (hs *HTTPServer) RevokeInvite(c *models.ReqContext) response.Response { // A response containing an InviteInfo object is returned if the invite is found. // If a (pending) invite is not found, 404 is returned. func (hs *HTTPServer) GetInviteInfoByCode(c *models.ReqContext) response.Response { - query := models.GetTempUserByCodeQuery{Code: web.Params(c.Req)[":code"]} - if err := hs.tempUserService.GetTempUserByCode(c.Req.Context(), &query); err != nil { - if errors.Is(err, models.ErrTempUserNotFound) { + query := tempuser.GetTempUserByCodeQuery{Code: web.Params(c.Req)[":code"]} + queryResult, err := hs.tempUserService.GetTempUserByCode(c.Req.Context(), &query) + if err != nil { + if errors.Is(err, tempuser.ErrTempUserNotFound) { return response.Error(404, "Invite not found", nil) } return response.Error(500, "Failed to get invite", err) } - invite := query.Result - if invite.Status != models.TmpUserInvitePending { + invite := queryResult + if invite.Status != tempuser.TmpUserInvitePending { return response.Error(404, "Invite not found", nil) } @@ -230,16 +234,17 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response { completeInvite.Username = strings.TrimSpace(completeInvite.Username) - query := models.GetTempUserByCodeQuery{Code: completeInvite.InviteCode} - if err := hs.tempUserService.GetTempUserByCode(c.Req.Context(), &query); err != nil { - if errors.Is(err, models.ErrTempUserNotFound) { + query := tempuser.GetTempUserByCodeQuery{Code: completeInvite.InviteCode} + queryResult, err := hs.tempUserService.GetTempUserByCode(c.Req.Context(), &query) + if err != nil { + if errors.Is(err, tempuser.ErrTempUserNotFound) { return response.Error(http.StatusNotFound, "Invite not found", nil) } return response.Error(http.StatusInternalServerError, "Failed to get invite", err) } - invite := query.Result - if invite.Status != models.TmpUserInvitePending { + invite := queryResult + if invite.Status != tempuser.TmpUserInvitePending { return response.Error(http.StatusPreconditionFailed, fmt.Sprintf("Invite cannot be used in status %s", invite.Status), nil) } @@ -293,9 +298,9 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response { }) } -func (hs *HTTPServer) updateTempUserStatus(ctx context.Context, code string, status models.TempUserStatus) (bool, response.Response) { +func (hs *HTTPServer) updateTempUserStatus(ctx context.Context, code string, status tempuser.TempUserStatus) (bool, response.Response) { // update temp user status - updateTmpUserCmd := models.UpdateTempUserStatusCommand{Code: code, Status: status} + updateTmpUserCmd := tempuser.UpdateTempUserStatusCommand{Code: code, Status: status} if err := hs.tempUserService.UpdateTempUserStatus(ctx, &updateTmpUserCmd); err != nil { return false, response.Error(500, "Failed to update invite status", err) } @@ -303,9 +308,9 @@ func (hs *HTTPServer) updateTempUserStatus(ctx context.Context, code string, sta return true, nil } -func (hs *HTTPServer) applyUserInvite(ctx context.Context, usr *user.User, invite *models.TempUserDTO, setActive bool) (bool, response.Response) { +func (hs *HTTPServer) applyUserInvite(ctx context.Context, usr *user.User, invite *tempuser.TempUserDTO, setActive bool) (bool, response.Response) { // add to org - addOrgUserCmd := org.AddOrgUserCommand{OrgID: invite.OrgId, UserID: usr.ID, Role: invite.Role} + addOrgUserCmd := org.AddOrgUserCommand{OrgID: invite.OrgID, UserID: usr.ID, Role: invite.Role} if err := hs.orgService.AddOrgUser(ctx, &addOrgUserCmd); err != nil { if !errors.Is(err, models.ErrOrgUserAlreadyAdded) { return false, response.Error(500, "Error while trying to create org user", err) @@ -313,13 +318,13 @@ func (hs *HTTPServer) applyUserInvite(ctx context.Context, usr *user.User, invit } // update temp user status - if ok, rsp := hs.updateTempUserStatus(ctx, invite.Code, models.TmpUserCompleted); !ok { + if ok, rsp := hs.updateTempUserStatus(ctx, invite.Code, tempuser.TmpUserCompleted); !ok { return false, rsp } if setActive { // set org to active - if err := hs.userService.SetUsingOrg(ctx, &user.SetUsingOrgCommand{OrgID: invite.OrgId, UserID: usr.ID}); err != nil { + if err := hs.userService.SetUsingOrg(ctx, &user.SetUsingOrgCommand{OrgID: invite.OrgID, UserID: usr.ID}); err != nil { return false, response.Error(500, "Failed to set org as active", err) } } @@ -345,5 +350,5 @@ type RevokeInviteParams struct { type GetPendingOrgInvitesResponse struct { // The response message // in: body - Body []*models.TempUserDTO `json:"body"` + Body []*tempuser.TempUserDTO `json:"body"` } diff --git a/pkg/api/signup.go b/pkg/api/signup.go index c0bc0b02c68..221749cb690 100644 --- a/pkg/api/signup.go +++ b/pkg/api/signup.go @@ -11,6 +11,7 @@ import ( "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/models" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -47,18 +48,18 @@ func (hs *HTTPServer) SignUp(c *models.ReqContext) response.Response { return response.Error(422, "User with same email address already exists", nil) } - cmd := models.CreateTempUserCommand{} - cmd.OrgId = -1 + cmd := tempuser.CreateTempUserCommand{} + cmd.OrgID = -1 cmd.Email = form.Email - cmd.Status = models.TmpUserSignUpStarted - cmd.InvitedByUserId = c.UserID + cmd.Status = tempuser.TmpUserSignUpStarted + cmd.InvitedByUserID = c.UserID cmd.Code, err = util.GetRandomString(20) if err != nil { return response.Error(500, "Failed to generate random string", err) } cmd.RemoteAddr = c.RemoteAddr() - if err := hs.tempUserService.CreateTempUser(c.Req.Context(), &cmd); err != nil { + if _, err := hs.tempUserService.CreateTempUser(c.Req.Context(), &cmd); err != nil { return response.Error(500, "Failed to create signup", err) } @@ -120,18 +121,19 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response { } // mark temp user as completed - if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), form.Code, models.TmpUserCompleted); !ok { + if ok, rsp := hs.updateTempUserStatus(c.Req.Context(), form.Code, tempuser.TmpUserCompleted); !ok { return rsp } // check for pending invites - invitesQuery := models.GetTempUsersQuery{Email: form.Email, Status: models.TmpUserInvitePending} - if err := hs.tempUserService.GetTempUsersQuery(c.Req.Context(), &invitesQuery); err != nil { + invitesQuery := tempuser.GetTempUsersQuery{Email: form.Email, Status: tempuser.TmpUserInvitePending} + invitesQueryResult, err := hs.tempUserService.GetTempUsersQuery(c.Req.Context(), &invitesQuery) + if err != nil { return response.Error(500, "Failed to query database for invites", err) } apiResponse := util.DynMap{"message": "User sign up completed successfully", "code": "redirect-to-landing-page"} - for _, invite := range invitesQuery.Result { + for _, invite := range invitesQueryResult { if ok, rsp := hs.applyUserInvite(c.Req.Context(), usr, invite, false); !ok { return rsp } @@ -149,16 +151,17 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response { } func (hs *HTTPServer) verifyUserSignUpEmail(ctx context.Context, email string, code string) (bool, response.Response) { - query := models.GetTempUserByCodeQuery{Code: code} + query := tempuser.GetTempUserByCodeQuery{Code: code} - if err := hs.tempUserService.GetTempUserByCode(ctx, &query); err != nil { - if errors.Is(err, models.ErrTempUserNotFound) { + queryResult, err := hs.tempUserService.GetTempUserByCode(ctx, &query) + if err != nil { + if errors.Is(err, tempuser.ErrTempUserNotFound) { return false, response.Error(404, "Invalid email verification code", nil) } return false, response.Error(500, "Failed to read temp user", err) } - tempUser := query.Result + tempUser := queryResult if tempUser.Email != email { return false, response.Error(404, "Email verification code does not match email", nil) } diff --git a/pkg/infra/db/dbtest/dbtest.go b/pkg/infra/db/dbtest/dbtest.go index 142626189e2..730d08bfe91 100644 --- a/pkg/infra/db/dbtest/dbtest.go +++ b/pkg/infra/db/dbtest/dbtest.go @@ -5,10 +5,10 @@ import ( "xorm.io/core" - "github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/services/sqlstore" "github.com/grafana/grafana/pkg/services/sqlstore/migrator" "github.com/grafana/grafana/pkg/services/sqlstore/session" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" ) type FakeDB struct { @@ -52,6 +52,6 @@ func (f *FakeDB) Quote(value string) string { } // TODO: service-specific methods not yet split out ; to be removed -func (f *FakeDB) UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error { +func (f *FakeDB) UpdateTempUserWithEmailSent(ctx context.Context, cmd *tempuser.UpdateTempUserWithEmailSentCommand) error { return f.ExpectedError } diff --git a/pkg/services/cleanup/cleanup.go b/pkg/services/cleanup/cleanup.go index a04dfdd125a..8d6840a90f2 100644 --- a/pkg/services/cleanup/cleanup.go +++ b/pkg/services/cleanup/cleanup.go @@ -227,7 +227,7 @@ func (srv *CleanUpService) expireOldUserInvites(ctx context.Context) { logger := srv.log.FromContext(ctx) maxInviteLifetime := srv.Cfg.UserInviteMaxLifetime - cmd := models.ExpireTempUsersCommand{ + cmd := tempuser.ExpireTempUsersCommand{ OlderThan: time.Now().Add(-maxInviteLifetime), } diff --git a/pkg/services/notifications/notifications.go b/pkg/services/notifications/notifications.go index ab93cee5c21..c8d544a6458 100644 --- a/pkg/services/notifications/notifications.go +++ b/pkg/services/notifications/notifications.go @@ -14,6 +14,7 @@ import ( "github.com/grafana/grafana/pkg/events" "github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/models" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" "github.com/grafana/grafana/pkg/services/user" "github.com/grafana/grafana/pkg/setting" "github.com/grafana/grafana/pkg/util" @@ -75,7 +76,7 @@ func ProvideService(bus bus.Bus, cfg *setting.Cfg, mailer Mailer, store TempUser } type TempUserStore interface { - UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error + UpdateTempUserWithEmailSent(ctx context.Context, cmd *tempuser.UpdateTempUserWithEmailSentCommand) error } type NotificationService struct { @@ -235,7 +236,7 @@ func (ns *NotificationService) signUpStartedHandler(ctx context.Context, evt *ev return err } - emailSentCmd := models.UpdateTempUserWithEmailSentCommand{Code: evt.Code} + emailSentCmd := tempuser.UpdateTempUserWithEmailSentCommand{Code: evt.Code} return ns.store.UpdateTempUserWithEmailSent(ctx, &emailSentCmd) } diff --git a/pkg/models/temp_user.go b/pkg/services/temp_user/model.go similarity index 82% rename from pkg/models/temp_user.go rename to pkg/services/temp_user/model.go index 116e37cd754..60e520a7eb2 100644 --- a/pkg/models/temp_user.go +++ b/pkg/services/temp_user/model.go @@ -1,4 +1,4 @@ -package models +package tempuser import ( "errors" @@ -24,13 +24,13 @@ const ( // TempUser holds data for org invites and unconfirmed sign ups type TempUser struct { - Id int64 - OrgId int64 + ID int64 `xorm:"id"` + OrgID int64 `xorm:"org_id"` Version int Email string Name string Role org.RoleType - InvitedByUserId int64 + InvitedByUserID int64 `xorm:"invited_by_user_id"` Status TempUserStatus EmailSent bool @@ -48,14 +48,12 @@ type TempUser struct { type CreateTempUserCommand struct { Email string Name string - OrgId int64 - InvitedByUserId int64 + OrgID int64 `xorm:"org_id"` + InvitedByUserID int64 `xorm:"invited_by_user_id"` Status TempUserStatus Code string Role org.RoleType RemoteAddr string - - Result *TempUser } type UpdateTempUserStatusCommand struct { @@ -74,22 +72,18 @@ type UpdateTempUserWithEmailSentCommand struct { } type GetTempUsersQuery struct { - OrgId int64 + OrgID int64 `xorm:"org_id"` Email string Status TempUserStatus - - Result []*TempUserDTO } type GetTempUserByCodeQuery struct { Code string - - Result *TempUserDTO } type TempUserDTO struct { - Id int64 `json:"id"` - OrgId int64 `json:"orgId"` + ID int64 `json:"id" xorm:"id"` + OrgID int64 `json:"orgId" xorm:"org_id"` Name string `json:"name"` Email string `json:"email"` Role org.RoleType `json:"role"` @@ -98,7 +92,7 @@ type TempUserDTO struct { InvitedByName string `json:"invitedByName"` Code string `json:"code"` Status TempUserStatus `json:"status"` - Url string `json:"url"` + URL string `json:"url"` EmailSent bool `json:"emailSent"` EmailSentOn time.Time `json:"emailSentOn"` Created time.Time `json:"createdOn"` diff --git a/pkg/services/temp_user/temp_user.go b/pkg/services/temp_user/temp_user.go index e1f9ee844e2..91b7e49801d 100644 --- a/pkg/services/temp_user/temp_user.go +++ b/pkg/services/temp_user/temp_user.go @@ -2,15 +2,13 @@ package tempuser import ( "context" - - "github.com/grafana/grafana/pkg/models" ) type Service interface { - UpdateTempUserStatus(ctx context.Context, cmd *models.UpdateTempUserStatusCommand) error - CreateTempUser(ctx context.Context, cmd *models.CreateTempUserCommand) error - UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error - GetTempUsersQuery(ctx context.Context, query *models.GetTempUsersQuery) error - GetTempUserByCode(ctx context.Context, query *models.GetTempUserByCodeQuery) error - ExpireOldUserInvites(ctx context.Context, cmd *models.ExpireTempUsersCommand) error + UpdateTempUserStatus(ctx context.Context, cmd *UpdateTempUserStatusCommand) error + CreateTempUser(ctx context.Context, cmd *CreateTempUserCommand) (*TempUser, error) + UpdateTempUserWithEmailSent(ctx context.Context, cmd *UpdateTempUserWithEmailSentCommand) error + GetTempUsersQuery(ctx context.Context, query *GetTempUsersQuery) ([]*TempUserDTO, error) + GetTempUserByCode(ctx context.Context, query *GetTempUserByCodeQuery) (*TempUserDTO, error) + ExpireOldUserInvites(ctx context.Context, cmd *ExpireTempUsersCommand) error } diff --git a/pkg/services/temp_user/tempuserimpl/store.go b/pkg/services/temp_user/tempuserimpl/store.go index 7f5fcd576c3..c66f702a8a9 100644 --- a/pkg/services/temp_user/tempuserimpl/store.go +++ b/pkg/services/temp_user/tempuserimpl/store.go @@ -5,23 +5,23 @@ import ( "time" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/models" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" ) type store interface { - UpdateTempUserStatus(ctx context.Context, cmd *models.UpdateTempUserStatusCommand) error - CreateTempUser(ctx context.Context, cmd *models.CreateTempUserCommand) error - UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error - GetTempUsersQuery(ctx context.Context, query *models.GetTempUsersQuery) error - GetTempUserByCode(ctx context.Context, query *models.GetTempUserByCodeQuery) error - ExpireOldUserInvites(ctx context.Context, cmd *models.ExpireTempUsersCommand) error + UpdateTempUserStatus(ctx context.Context, cmd *tempuser.UpdateTempUserStatusCommand) error + CreateTempUser(ctx context.Context, cmd *tempuser.CreateTempUserCommand) (*tempuser.TempUser, error) + UpdateTempUserWithEmailSent(ctx context.Context, cmd *tempuser.UpdateTempUserWithEmailSentCommand) error + GetTempUsersQuery(ctx context.Context, query *tempuser.GetTempUsersQuery) ([]*tempuser.TempUserDTO, error) + GetTempUserByCode(ctx context.Context, query *tempuser.GetTempUserByCodeQuery) (*tempuser.TempUserDTO, error) + ExpireOldUserInvites(ctx context.Context, cmd *tempuser.ExpireTempUsersCommand) error } type xormStore struct { db db.DB } -func (ss *xormStore) UpdateTempUserStatus(ctx context.Context, cmd *models.UpdateTempUserStatusCommand) error { +func (ss *xormStore) UpdateTempUserStatus(ctx context.Context, cmd *tempuser.UpdateTempUserStatusCommand) error { return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { var rawSQL = "UPDATE temp_user SET status=? WHERE code=?" _, err := sess.Exec(rawSQL, string(cmd.Status), cmd.Code) @@ -29,18 +29,19 @@ func (ss *xormStore) UpdateTempUserStatus(ctx context.Context, cmd *models.Updat }) } -func (ss *xormStore) CreateTempUser(ctx context.Context, cmd *models.CreateTempUserCommand) error { - return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { +func (ss *xormStore) CreateTempUser(ctx context.Context, cmd *tempuser.CreateTempUserCommand) (*tempuser.TempUser, error) { + var queryResult *tempuser.TempUser + err := ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { // create user - user := &models.TempUser{ + user := &tempuser.TempUser{ Email: cmd.Email, Name: cmd.Name, - OrgId: cmd.OrgId, + OrgID: cmd.OrgID, Code: cmd.Code, Role: cmd.Role, Status: cmd.Status, RemoteAddr: cmd.RemoteAddr, - InvitedByUserId: cmd.InvitedByUserId, + InvitedByUserID: cmd.InvitedByUserID, EmailSentOn: time.Now(), Created: time.Now().Unix(), Updated: time.Now().Unix(), @@ -50,15 +51,19 @@ func (ss *xormStore) CreateTempUser(ctx context.Context, cmd *models.CreateTempU return err } - cmd.Result = user + queryResult = user return nil }) + if err != nil { + return nil, err + } + return queryResult, nil } -func (ss *xormStore) UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error { +func (ss *xormStore) UpdateTempUserWithEmailSent(ctx context.Context, cmd *tempuser.UpdateTempUserWithEmailSentCommand) error { return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { - user := &models.TempUser{ + user := &tempuser.TempUser{ EmailSent: true, EmailSentOn: time.Now(), } @@ -69,8 +74,9 @@ func (ss *xormStore) UpdateTempUserWithEmailSent(ctx context.Context, cmd *model }) } -func (ss *xormStore) GetTempUsersQuery(ctx context.Context, query *models.GetTempUsersQuery) error { - return ss.db.WithDbSession(ctx, func(dbSess *db.Session) error { +func (ss *xormStore) GetTempUsersQuery(ctx context.Context, query *tempuser.GetTempUsersQuery) ([]*tempuser.TempUserDTO, error) { + queryResult := make([]*tempuser.TempUserDTO, 0) + err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error { rawSQL := `SELECT tu.id as id, tu.org_id as org_id, @@ -90,9 +96,9 @@ func (ss *xormStore) GetTempUsersQuery(ctx context.Context, query *models.GetTem WHERE tu.status=?` params := []interface{}{string(query.Status)} - if query.OrgId > 0 { + if query.OrgID > 0 { rawSQL += ` AND tu.org_id=?` - params = append(params, query.OrgId) + params = append(params, query.OrgID) } if query.Email != "" { @@ -102,15 +108,19 @@ func (ss *xormStore) GetTempUsersQuery(ctx context.Context, query *models.GetTem rawSQL += " ORDER BY tu.created desc" - query.Result = make([]*models.TempUserDTO, 0) sess := dbSess.SQL(rawSQL, params...) - err := sess.Find(&query.Result) + err := sess.Find(&queryResult) return err }) + if err != nil { + return nil, err + } + return queryResult, nil } -func (ss *xormStore) GetTempUserByCode(ctx context.Context, query *models.GetTempUserByCodeQuery) error { - return ss.db.WithDbSession(ctx, func(dbSess *db.Session) error { +func (ss *xormStore) GetTempUserByCode(ctx context.Context, query *tempuser.GetTempUserByCodeQuery) (*tempuser.TempUserDTO, error) { + var queryResult *tempuser.TempUserDTO + err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error { var rawSQL = `SELECT tu.id as id, tu.org_id as org_id, @@ -129,25 +139,29 @@ func (ss *xormStore) GetTempUserByCode(ctx context.Context, query *models.GetTem LEFT OUTER JOIN ` + ss.db.GetDialect().Quote("user") + ` as u on u.id = tu.invited_by_user_id WHERE tu.code=?` - var tempUser models.TempUserDTO + var tempUser tempuser.TempUserDTO sess := dbSess.SQL(rawSQL, query.Code) has, err := sess.Get(&tempUser) if err != nil { return err } else if !has { - return models.ErrTempUserNotFound + return tempuser.ErrTempUserNotFound } - query.Result = &tempUser + queryResult = &tempUser return err }) + if err != nil { + return nil, err + } + return queryResult, nil } -func (ss *xormStore) ExpireOldUserInvites(ctx context.Context, cmd *models.ExpireTempUsersCommand) error { +func (ss *xormStore) ExpireOldUserInvites(ctx context.Context, cmd *tempuser.ExpireTempUsersCommand) error { return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error { var rawSQL = "UPDATE temp_user SET status = ?, updated = ? WHERE created <= ? AND status in (?, ?)" - if result, err := sess.Exec(rawSQL, string(models.TmpUserExpired), time.Now().Unix(), cmd.OlderThan.Unix(), string(models.TmpUserSignUpStarted), string(models.TmpUserInvitePending)); err != nil { + if result, err := sess.Exec(rawSQL, string(tempuser.TmpUserExpired), time.Now().Unix(), cmd.OlderThan.Unix(), string(tempuser.TmpUserSignUpStarted), string(tempuser.TmpUserInvitePending)); err != nil { return err } else if cmd.NumExpired, err = result.RowsAffected(); err != nil { return err diff --git a/pkg/services/temp_user/tempuserimpl/store_test.go b/pkg/services/temp_user/tempuserimpl/store_test.go index 724628068bf..7de6f1c40dc 100644 --- a/pkg/services/temp_user/tempuserimpl/store_test.go +++ b/pkg/services/temp_user/tempuserimpl/store_test.go @@ -8,7 +8,7 @@ import ( "github.com/stretchr/testify/require" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/models" + tempuser "github.com/grafana/grafana/pkg/services/temp_user" ) func TestIntegrationTempUserCommandsAndQueries(t *testing.T) { @@ -16,79 +16,81 @@ func TestIntegrationTempUserCommandsAndQueries(t *testing.T) { t.Skip("skipping integration test") } var store store - cmd := models.CreateTempUserCommand{ - OrgId: 2256, + var tempUser *tempuser.TempUser + var err error + cmd := tempuser.CreateTempUserCommand{ + OrgID: 2256, Name: "hello", Code: "asd", Email: "e@as.co", - Status: models.TmpUserInvitePending, + Status: tempuser.TmpUserInvitePending, } setup := func(t *testing.T) { db := db.InitTestDB(t) store = &xormStore{db: db} - err := store.CreateTempUser(context.Background(), &cmd) + tempUser, err = store.CreateTempUser(context.Background(), &cmd) require.Nil(t, err) } t.Run("Should be able to get temp users by org id", func(t *testing.T) { setup(t) - query := models.GetTempUsersQuery{OrgId: 2256, Status: models.TmpUserInvitePending} - err := store.GetTempUsersQuery(context.Background(), &query) + query := tempuser.GetTempUsersQuery{OrgID: 2256, Status: tempuser.TmpUserInvitePending} + queryResult, err := store.GetTempUsersQuery(context.Background(), &query) require.Nil(t, err) - require.Equal(t, 1, len(query.Result)) + require.Equal(t, 1, len(queryResult)) }) t.Run("Should be able to get temp users by email", func(t *testing.T) { setup(t) - query := models.GetTempUsersQuery{Email: "e@as.co", Status: models.TmpUserInvitePending} - err := store.GetTempUsersQuery(context.Background(), &query) + query := tempuser.GetTempUsersQuery{Email: "e@as.co", Status: tempuser.TmpUserInvitePending} + queryResult, err := store.GetTempUsersQuery(context.Background(), &query) require.Nil(t, err) - require.Equal(t, 1, len(query.Result)) + require.Equal(t, 1, len(queryResult)) }) t.Run("Should be able to get temp users by code", func(t *testing.T) { setup(t) - query := models.GetTempUserByCodeQuery{Code: "asd"} - err := store.GetTempUserByCode(context.Background(), &query) + query := tempuser.GetTempUserByCodeQuery{Code: "asd"} + queryResult, err := store.GetTempUserByCode(context.Background(), &query) require.Nil(t, err) - require.Equal(t, "hello", query.Result.Name) + require.Equal(t, "hello", queryResult.Name) }) t.Run("Should be able update status", func(t *testing.T) { setup(t) - cmd2 := models.UpdateTempUserStatusCommand{Code: "asd", Status: models.TmpUserRevoked} + cmd2 := tempuser.UpdateTempUserStatusCommand{Code: "asd", Status: tempuser.TmpUserRevoked} err := store.UpdateTempUserStatus(context.Background(), &cmd2) require.Nil(t, err) }) t.Run("Should be able update email sent and email sent on", func(t *testing.T) { setup(t) - cmd2 := models.UpdateTempUserWithEmailSentCommand{Code: cmd.Result.Code} + cmd2 := tempuser.UpdateTempUserWithEmailSentCommand{Code: tempUser.Code} err := store.UpdateTempUserWithEmailSent(context.Background(), &cmd2) require.Nil(t, err) - query := models.GetTempUsersQuery{OrgId: 2256, Status: models.TmpUserInvitePending} - err = store.GetTempUsersQuery(context.Background(), &query) + query := tempuser.GetTempUsersQuery{OrgID: 2256, Status: tempuser.TmpUserInvitePending} + queryResult, err := store.GetTempUsersQuery(context.Background(), &query) require.Nil(t, err) - require.True(t, query.Result[0].EmailSent) - require.False(t, query.Result[0].EmailSentOn.UTC().Before(query.Result[0].Created.UTC())) + require.True(t, queryResult[0].EmailSent) + require.False(t, queryResult[0].EmailSentOn.UTC().Before(queryResult[0].Created.UTC())) }) t.Run("Should be able expire temp user", func(t *testing.T) { setup(t) - createdAt := time.Unix(cmd.Result.Created, 0) - cmd2 := models.ExpireTempUsersCommand{OlderThan: createdAt.Add(1 * time.Second)} + createdAt := time.Unix(tempUser.Created, 0) + cmd2 := tempuser.ExpireTempUsersCommand{OlderThan: createdAt.Add(1 * time.Second)} err := store.ExpireOldUserInvites(context.Background(), &cmd2) require.Nil(t, err) require.Equal(t, int64(1), cmd2.NumExpired) t.Run("Should do nothing when no temp users to expire", func(t *testing.T) { - createdAt := time.Unix(cmd.Result.Created, 0) - cmd2 := models.ExpireTempUsersCommand{OlderThan: createdAt.Add(1 * time.Second)} + createdAt := time.Unix(tempUser.Created, 0) + cmd2 := tempuser.ExpireTempUsersCommand{OlderThan: createdAt.Add(1 * time.Second)} err := store.ExpireOldUserInvites(context.Background(), &cmd2) require.Nil(t, err) require.Equal(t, int64(0), cmd2.NumExpired) diff --git a/pkg/services/temp_user/tempuserimpl/temp_user.go b/pkg/services/temp_user/tempuserimpl/temp_user.go index d6297a120ba..b46b3281ce8 100644 --- a/pkg/services/temp_user/tempuserimpl/temp_user.go +++ b/pkg/services/temp_user/tempuserimpl/temp_user.go @@ -4,7 +4,6 @@ import ( "context" "github.com/grafana/grafana/pkg/infra/db" - "github.com/grafana/grafana/pkg/models" tempuser "github.com/grafana/grafana/pkg/services/temp_user" ) @@ -20,7 +19,7 @@ func ProvideService( } } -func (s *Service) UpdateTempUserStatus(ctx context.Context, cmd *models.UpdateTempUserStatusCommand) error { +func (s *Service) UpdateTempUserStatus(ctx context.Context, cmd *tempuser.UpdateTempUserStatusCommand) error { err := s.store.UpdateTempUserStatus(ctx, cmd) if err != nil { return err @@ -28,15 +27,15 @@ func (s *Service) UpdateTempUserStatus(ctx context.Context, cmd *models.UpdateTe return nil } -func (s *Service) CreateTempUser(ctx context.Context, cmd *models.CreateTempUserCommand) error { - err := s.store.CreateTempUser(ctx, cmd) +func (s *Service) CreateTempUser(ctx context.Context, cmd *tempuser.CreateTempUserCommand) (*tempuser.TempUser, error) { + res, err := s.store.CreateTempUser(ctx, cmd) if err != nil { - return err + return nil, err } - return nil + return res, nil } -func (s *Service) UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.UpdateTempUserWithEmailSentCommand) error { +func (s *Service) UpdateTempUserWithEmailSent(ctx context.Context, cmd *tempuser.UpdateTempUserWithEmailSentCommand) error { err := s.store.UpdateTempUserWithEmailSent(ctx, cmd) if err != nil { return err @@ -44,23 +43,23 @@ func (s *Service) UpdateTempUserWithEmailSent(ctx context.Context, cmd *models.U return nil } -func (s *Service) GetTempUsersQuery(ctx context.Context, cmd *models.GetTempUsersQuery) error { - err := s.store.GetTempUsersQuery(ctx, cmd) +func (s *Service) GetTempUsersQuery(ctx context.Context, cmd *tempuser.GetTempUsersQuery) ([]*tempuser.TempUserDTO, error) { + res, err := s.store.GetTempUsersQuery(ctx, cmd) if err != nil { - return err + return nil, err } - return nil + return res, nil } -func (s *Service) GetTempUserByCode(ctx context.Context, cmd *models.GetTempUserByCodeQuery) error { - err := s.store.GetTempUserByCode(ctx, cmd) +func (s *Service) GetTempUserByCode(ctx context.Context, cmd *tempuser.GetTempUserByCodeQuery) (*tempuser.TempUserDTO, error) { + res, err := s.store.GetTempUserByCode(ctx, cmd) if err != nil { - return err + return nil, err } - return nil + return res, nil } -func (s *Service) ExpireOldUserInvites(ctx context.Context, cmd *models.ExpireTempUsersCommand) error { +func (s *Service) ExpireOldUserInvites(ctx context.Context, cmd *tempuser.ExpireTempUsersCommand) error { err := s.store.ExpireOldUserInvites(ctx, cmd) if err != nil { return err