Split Create User (#50502)

* Split Create User

* Use new create user and User from package user

* Add service to wire

* Making create user work

* Replace user from user pkg

* One more

* Move Insert to orguser Service/Store

* Remove unnecessary conversion

* Cleaunp

* Fix Get User and add fakes

* Fixing get org id for user logic, adding fakes and other adjustments

* Add some tests for ourguser service and store

* Fix insert org logic

* Add comment about deprecation

* Fix after merge with main

* Move orguser service/store to org service/store

* Remove orguser from wire

* Unimplement new Create user and use User from pkg user

* Fix wire generation

* Fix lint

* Fix lint - use only User and CrateUserCommand from user pkg

* Remove User and CreateUserCommand from models

* Fix lint 2
This commit is contained in:
idafurjes 2022-06-28 14:32:25 +02:00 committed by GitHub
parent 2429fe1c70
commit 6c43eb0b4d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
105 changed files with 1524 additions and 701 deletions

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
)
@ -19,12 +20,12 @@ func (hs *HTTPServer) AdminCreateUser(c *models.ReqContext) response.Response {
if err := web.Bind(c.Req, &form); err != nil {
return response.Error(http.StatusBadRequest, "bad request data", err)
}
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Login: form.Login,
Email: form.Email,
Password: form.Password,
Name: form.Name,
OrgId: form.OrgId,
OrgID: form.OrgId,
}
if len(cmd.Login) == 0 {
@ -55,7 +56,7 @@ func (hs *HTTPServer) AdminCreateUser(c *models.ReqContext) response.Response {
result := models.UserIdDTO{
Message: "User created",
Id: user.Id,
Id: user.ID,
}
return response.JSON(http.StatusOK, result)

View File

@ -179,7 +179,7 @@ func (hs *HTTPServer) PostSyncUserWithLDAP(c *models.ReqContext) response.Respon
return response.Error(500, "Failed to get user", err)
}
authModuleQuery := &models.GetAuthInfoQuery{UserId: query.Result.Id, AuthModule: models.AuthModuleLDAP}
authModuleQuery := &models.GetAuthInfoQuery{UserId: query.Result.ID, AuthModule: models.AuthModuleLDAP}
if err := hs.authInfoService.GetAuthInfo(c.Req.Context(), authModuleQuery); err != nil { // validate the userId comes from LDAP
if errors.Is(err, models.ErrUserNotFound) {
return response.Error(404, models.ErrUserNotFound.Error(), nil)

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/api/routing"
@ -403,7 +404,7 @@ func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(*
func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
sqlstoremock := mockstore.SQLStoreMock{}
sqlstoremock.ExpectedUser = &models.User{Login: "ldap-daniel", Id: 34}
sqlstoremock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
@ -453,7 +454,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
}
func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
sqlstoremock := mockstore.SQLStoreMock{ExpectedUser: &models.User{Login: "ldap-daniel", Id: 34}}
sqlstoremock := mockstore.SQLStoreMock{ExpectedUser: &user.User{Login: "ldap-daniel", ID: 34}}
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
return &ldap.Config{}, nil
@ -477,7 +478,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
}
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
sqlstoremock := mockstore.SQLStoreMock{ExpectedUser: &models.User{Login: "ldap-daniel", Id: 34}}
sqlstoremock := mockstore.SQLStoreMock{ExpectedUser: &user.User{Login: "ldap-daniel", ID: 34}}
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
sc.authInfoService.ExpectedExternalUser = &models.ExternalUserInfo{IsDisabled: true, UserId: 34}
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
@ -601,7 +602,7 @@ func TestLDAP_AccessControl(t *testing.T) {
cfg := setting.NewCfg()
cfg.LDAPEnabled = true
sc, hs := setupAccessControlScenarioContext(t, cfg, test.url, test.permissions)
hs.SQLStore = &mockstore.SQLStoreMock{ExpectedUser: &models.User{}}
hs.SQLStore = &mockstore.SQLStoreMock{ExpectedUser: &user.User{}}
hs.authInfoService = &logintest.AuthInfoServiceFake{}
hs.Login = &loginservice.LoginServiceMock{}
sc.resp = httptest.NewRecorder()

View File

@ -17,6 +17,7 @@ import (
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -120,7 +121,7 @@ func (hs *HTTPServer) LoginView(c *models.ReqContext) {
if c.IsSignedIn {
// Assign login token to auth proxy users if enable_login_token = true
if hs.Cfg.AuthProxyEnabled && hs.Cfg.AuthProxyEnableLoginToken {
user := &models.User{Id: c.SignedInUser.UserId, Email: c.SignedInUser.Email, Login: c.SignedInUser.Login}
user := &user.User{ID: c.SignedInUser.UserId, Email: c.SignedInUser.Email, Login: c.SignedInUser.Login}
err := hs.loginUserWithUser(user, c)
if err != nil {
c.Handle(hs.Cfg, 500, "Failed to sign in user", err)
@ -179,7 +180,7 @@ func (hs *HTTPServer) LoginPost(c *models.ReqContext) response.Response {
return response.Error(http.StatusBadRequest, "bad login data", err)
}
authModule := ""
var user *models.User
var user *user.User
var resp *response.NormalResponse
defer func() {
@ -260,7 +261,7 @@ func (hs *HTTPServer) LoginPost(c *models.ReqContext) response.Response {
return resp
}
func (hs *HTTPServer) loginUserWithUser(user *models.User, c *models.ReqContext) error {
func (hs *HTTPServer) loginUserWithUser(user *user.User, c *models.ReqContext) error {
if user == nil {
return errors.New("could not login user")
}

View File

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/middleware/cookies"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -297,7 +298,7 @@ func (hs *HTTPServer) SyncUser(
ctx *models.ReqContext,
extUser *models.ExternalUserInfo,
connect social.SocialConnector,
) (*models.User, error) {
) (*user.User, error) {
oauthLogger.Debug("Syncing Grafana user with corresponding OAuth profile")
// add/update user in Grafana
cmd := &models.UpsertUserCommand{

View File

@ -30,6 +30,7 @@ import (
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/secrets/fakes"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -331,8 +332,8 @@ func TestLoginPostRedirect(t *testing.T) {
return hs.LoginPost(c)
})
user := &models.User{
Id: 42,
user := &user.User{
ID: 42,
Email: "",
}
@ -614,14 +615,14 @@ func TestLoginPostRunLokingHook(t *testing.T) {
testHook := loginHookTest{}
hookService.AddLoginHook(testHook.LoginHook)
testUser := &models.User{
Id: 42,
testUser := &user.User{
ID: 42,
Email: "",
}
testCases := []struct {
desc string
authUser *models.User
authUser *user.User
authModule string
authErr error
info models.LoginInfo
@ -680,7 +681,7 @@ func TestLoginPostRunLokingHook(t *testing.T) {
if c.info.User != nil {
require.NotEmpty(t, info.User)
assert.Equal(t, c.info.User.Id, info.User.Id)
assert.Equal(t, c.info.User.ID, info.User.ID)
}
})
}
@ -716,7 +717,7 @@ func (m *mockSocialService) GetConnector(string) (social.SocialConnector, error)
}
type fakeAuthenticator struct {
ExpectedUser *models.User
ExpectedUser *user.User
ExpectedAuthModule string
ExpectedError error
}

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -107,9 +108,9 @@ func (hs *HTTPServer) AddOrgInvite(c *models.ReqContext) response.Response {
return response.Success(fmt.Sprintf("Created invite for %s", inviteDto.LoginOrEmail))
}
func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *models.User, inviteDto *dtos.AddInviteForm) response.Response {
func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *user.User, inviteDto *dtos.AddInviteForm) response.Response {
// user exists, add org role
createOrgUserCmd := models.AddOrgUserCommand{OrgId: c.OrgId, UserId: user.Id, Role: inviteDto.Role}
createOrgUserCmd := models.AddOrgUserCommand{OrgId: c.OrgId, UserId: user.ID, Role: inviteDto.Role}
if err := hs.SQLStore.AddOrgUser(c.Req.Context(), &createOrgUserCmd); err != nil {
if errors.Is(err, models.ErrOrgUserAlreadyAdded) {
return response.Error(412, fmt.Sprintf("User %s is already added to organization", inviteDto.LoginOrEmail), err)
@ -135,7 +136,7 @@ func (hs *HTTPServer) inviteExistingUserToOrg(c *models.ReqContext, user *models
return response.JSON(http.StatusOK, util.DynMap{
"message": fmt.Sprintf("Existing Grafana user %s added to org %s", user.NameOrFallback(), c.OrgName),
"userId": user.Id,
"userId": user.ID,
})
}
@ -191,7 +192,7 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
return response.Error(412, fmt.Sprintf("Invite cannot be used in status %s", invite.Status), nil)
}
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: completeInvite.Email,
Name: completeInvite.Name,
Login: completeInvite.Username,
@ -199,7 +200,7 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
SkipOrgSetup: true,
}
user, err := hs.Login.CreateUser(cmd)
usr, err := hs.Login.CreateUser(cmd)
if err != nil {
if errors.Is(err, models.ErrUserAlreadyExists) {
return response.Error(412, fmt.Sprintf("User with email '%s' or username '%s' already exists", completeInvite.Email, completeInvite.Username), err)
@ -209,17 +210,17 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
}
if err := hs.bus.Publish(c.Req.Context(), &events.SignUpCompleted{
Name: user.NameOrFallback(),
Email: user.Email,
Name: usr.NameOrFallback(),
Email: usr.Email,
}); err != nil {
return response.Error(500, "failed to publish event", err)
}
if ok, rsp := hs.applyUserInvite(c.Req.Context(), user, invite, true); !ok {
if ok, rsp := hs.applyUserInvite(c.Req.Context(), usr, invite, true); !ok {
return rsp
}
err = hs.loginUserWithUser(user, c)
err = hs.loginUserWithUser(usr, c)
if err != nil {
return response.Error(500, "failed to accept invite", err)
}
@ -229,7 +230,7 @@ func (hs *HTTPServer) CompleteInvite(c *models.ReqContext) response.Response {
return response.JSON(http.StatusOK, util.DynMap{
"message": "User created and logged in",
"id": user.Id,
"id": usr.ID,
})
}
@ -243,9 +244,9 @@ func (hs *HTTPServer) updateTempUserStatus(ctx context.Context, code string, sta
return true, nil
}
func (hs *HTTPServer) applyUserInvite(ctx context.Context, user *models.User, invite *models.TempUserDTO, setActive bool) (bool, response.Response) {
func (hs *HTTPServer) applyUserInvite(ctx context.Context, user *user.User, invite *models.TempUserDTO, setActive bool) (bool, response.Response) {
// add to org
addOrgUserCmd := models.AddOrgUserCommand{OrgId: invite.OrgId, UserId: user.Id, Role: invite.Role}
addOrgUserCmd := models.AddOrgUserCommand{OrgId: invite.OrgId, UserId: user.ID, Role: invite.Role}
if err := hs.SQLStore.AddOrgUser(ctx, &addOrgUserCmd); err != nil {
if !errors.Is(err, models.ErrOrgUserAlreadyAdded) {
return false, response.Error(500, "Error while trying to create org user", err)
@ -259,7 +260,7 @@ func (hs *HTTPServer) applyUserInvite(ctx context.Context, user *models.User, in
if setActive {
// set org to active
if err := hs.SQLStore.SetUsingOrg(ctx, &models.SetUsingOrgCommand{OrgId: invite.OrgId, UserId: user.Id}); err != nil {
if err := hs.SQLStore.SetUsingOrg(ctx, &models.SetUsingOrgCommand{OrgId: invite.OrgId, UserId: user.ID}); err != nil {
return false, response.Error(500, "Failed to set org as active", err)
}
}

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -185,17 +186,17 @@ func TestAPIEndpoint_PutCurrentOrgAddress_AccessControl(t *testing.T) {
// `/api/orgs/` endpoints test
// setupOrgsDBForAccessControlTests stores users and create specified number of orgs
func setupOrgsDBForAccessControlTests(t *testing.T, db sqlstore.Store, user models.SignedInUser, orgsCount int) {
func setupOrgsDBForAccessControlTests(t *testing.T, db sqlstore.Store, usr models.SignedInUser, orgsCount int) {
t.Helper()
_, err := db.CreateUser(context.Background(), models.CreateUserCommand{Email: user.Email, SkipOrgSetup: true, Login: user.Login})
_, err := db.CreateUser(context.Background(), user.CreateUserCommand{Email: usr.Email, SkipOrgSetup: true, Login: usr.Login})
require.NoError(t, err)
// Create `orgsCount` orgs
for i := 1; i <= orgsCount; i++ {
_, err = db.CreateOrgWithMember(fmt.Sprintf("TestOrg%v", i), 0)
require.NoError(t, err)
err = db.AddOrgUser(context.Background(), &models.AddOrgUserCommand{LoginOrEmail: user.Login, Role: user.OrgRole, OrgId: int64(i), UserId: user.UserId})
err = db.AddOrgUser(context.Background(), &models.AddOrgUserCommand{LoginOrEmail: usr.Login, Role: usr.OrgRole, OrgId: int64(i), UserId: usr.UserId})
require.NoError(t, err)
}
}

View File

@ -55,7 +55,7 @@ func (hs *HTTPServer) addOrgUserHelper(c *models.ReqContext, cmd models.AddOrgUs
userToAdd := userQuery.Result
cmd.UserId = userToAdd.Id
cmd.UserId = userToAdd.ID
if err := hs.SQLStore.AddOrgUser(c.Req.Context(), &cmd); err != nil {
if errors.Is(err, models.ErrOrgUserAlreadyAdded) {

View File

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/featuremgmt"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
)
@ -26,11 +27,11 @@ func setUpGetOrgUsersDB(t *testing.T, sqlStore *sqlstore.SQLStore) {
sqlStore.Cfg.AutoAssignOrg = true
sqlStore.Cfg.AutoAssignOrgId = int(testOrgID)
_, err := sqlStore.CreateUser(context.Background(), models.CreateUserCommand{Email: "testUser@grafana.com", Login: testUserLogin})
_, err := sqlStore.CreateUser(context.Background(), user.CreateUserCommand{Email: "testUser@grafana.com", Login: testUserLogin})
require.NoError(t, err)
_, err = sqlStore.CreateUser(context.Background(), models.CreateUserCommand{Email: "user1@grafana.com", Login: "user1"})
_, err = sqlStore.CreateUser(context.Background(), user.CreateUserCommand{Email: "user1@grafana.com", Login: "user1"})
require.NoError(t, err)
_, err = sqlStore.CreateUser(context.Background(), models.CreateUserCommand{Email: "user2@grafana.com", Login: "user2"})
_, err = sqlStore.CreateUser(context.Background(), user.CreateUserCommand{Email: "user2@grafana.com", Login: "user2"})
require.NoError(t, err)
}
@ -280,11 +281,11 @@ func setupOrgUsersDBForAccessControlTests(t *testing.T, db sqlstore.Store) {
var err error
_, err = db.CreateUser(context.Background(), models.CreateUserCommand{Email: testServerAdminViewer.Email, SkipOrgSetup: true, Login: testServerAdminViewer.Login})
_, err = db.CreateUser(context.Background(), user.CreateUserCommand{Email: testServerAdminViewer.Email, SkipOrgSetup: true, Login: testServerAdminViewer.Login})
require.NoError(t, err)
_, err = db.CreateUser(context.Background(), models.CreateUserCommand{Email: testAdminOrg2.Email, SkipOrgSetup: true, Login: testAdminOrg2.Login})
_, err = db.CreateUser(context.Background(), user.CreateUserCommand{Email: testAdminOrg2.Email, SkipOrgSetup: true, Login: testAdminOrg2.Login})
require.NoError(t, err)
_, err = db.CreateUser(context.Background(), models.CreateUserCommand{Email: testEditorOrg1.Email, SkipOrgSetup: true, Login: testEditorOrg1.Login})
_, err = db.CreateUser(context.Background(), user.CreateUserCommand{Email: testEditorOrg1.Email, SkipOrgSetup: true, Login: testEditorOrg1.Login})
require.NoError(t, err)
// Create both orgs with server admin

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/api/response"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -47,7 +48,7 @@ func (hs *HTTPServer) ResetPassword(c *models.ReqContext) response.Response {
}
query := models.ValidateResetPasswordCodeQuery{Code: form.Code}
getUserByLogin := func(ctx context.Context, login string) (*models.User, error) {
getUserByLogin := func(ctx context.Context, login string) (*user.User, error) {
userQuery := models.GetUserByLoginQuery{LoginOrEmail: login}
err := hs.SQLStore.GetUserByLogin(ctx, &userQuery)
return userQuery.Result, err
@ -70,7 +71,7 @@ func (hs *HTTPServer) ResetPassword(c *models.ReqContext) response.Response {
}
cmd := models.ChangeUserPasswordCommand{}
cmd.UserId = query.Result.Id
cmd.UserId = query.Result.ID
var err error
cmd.NewPassword, err = util.EncodePassword(form.NewPassword, query.Result.Salt)
if err != nil {

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -75,7 +76,7 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
return response.Error(401, "User signup is disabled", nil)
}
createUserCmd := models.CreateUserCommand{
createUserCmd := user.CreateUserCommand{
Email: form.Email,
Login: form.Username,
Name: form.Name,
@ -91,7 +92,7 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
createUserCmd.EmailVerified = true
}
user, err := hs.Login.CreateUser(createUserCmd)
usr, err := hs.Login.CreateUser(createUserCmd)
if err != nil {
if errors.Is(err, models.ErrUserAlreadyExists) {
return response.Error(401, "User with same email address already exists", nil)
@ -102,8 +103,8 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
// publish signup event
if err := hs.bus.Publish(c.Req.Context(), &events.SignUpCompleted{
Email: user.Email,
Name: user.NameOrFallback(),
Email: usr.Email,
Name: usr.NameOrFallback(),
}); err != nil {
return response.Error(500, "Failed to publish event", err)
}
@ -121,13 +122,13 @@ func (hs *HTTPServer) SignUpStep2(c *models.ReqContext) response.Response {
apiResponse := util.DynMap{"message": "User sign up completed successfully", "code": "redirect-to-landing-page"}
for _, invite := range invitesQuery.Result {
if ok, rsp := hs.applyUserInvite(c.Req.Context(), user, invite, false); !ok {
if ok, rsp := hs.applyUserInvite(c.Req.Context(), usr, invite, false); !ok {
return rsp
}
apiResponse["code"] = "redirect-to-select-org"
}
err = hs.loginUserWithUser(user, c)
err = hs.loginUserWithUser(usr, c)
if err != nil {
return response.Error(500, "failed to login user", err)
}

View File

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/teamguardian/database"
"github.com/grafana/grafana/pkg/services/teamguardian/manager"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -32,11 +33,11 @@ func (t *TeamGuardianMock) CanAdmin(ctx context.Context, orgId int64, teamId int
func setUpGetTeamMembersHandler(t *testing.T, sqlStore *sqlstore.SQLStore) {
const testOrgID int64 = 1
var userCmd models.CreateUserCommand
var userCmd user.CreateUserCommand
team, err := sqlStore.CreateTeam("group1 name", "test1@test.com", testOrgID)
require.NoError(t, err)
for i := 0; i < 3; i++ {
userCmd = models.CreateUserCommand{
userCmd = user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -44,7 +45,7 @@ func setUpGetTeamMembersHandler(t *testing.T, sqlStore *sqlstore.SQLStore) {
// user
user, err := sqlStore.CreateUser(context.Background(), userCmd)
require.NoError(t, err)
err = sqlStore.AddTeamMember(user.Id, testOrgID, team.Id, false, 1)
err = sqlStore.AddTeamMember(user.ID, testOrgID, team.Id, false, 1)
require.NoError(t, err)
}
}
@ -103,20 +104,20 @@ func TestTeamMembersAPIEndpoint_userLoggedIn(t *testing.T) {
}
func createUser(db sqlstore.Store, orgId int64, t *testing.T) int64 {
user, err := db.CreateUser(context.Background(), models.CreateUserCommand{
user, err := db.CreateUser(context.Background(), user.CreateUserCommand{
Login: fmt.Sprintf("TestUser%d", rand.Int()),
OrgId: orgId,
OrgID: orgId,
Password: "password",
})
require.NoError(t, err)
return user.Id
return user.ID
}
func setupTeamTestScenario(userCount int, db sqlstore.Store, t *testing.T) int64 {
user, err := db.CreateUser(context.Background(), models.CreateUserCommand{SkipOrgSetup: true, Login: testUserLogin})
user, err := db.CreateUser(context.Background(), user.CreateUserCommand{SkipOrgSetup: true, Login: testUserLogin})
require.NoError(t, err)
testOrg, err := db.CreateOrgWithMember("TestOrg", user.Id)
testOrg, err := db.CreateOrgWithMember("TestOrg", user.ID)
require.NoError(t, err)
team, err := db.CreateTeam("test", "test@test.com", testOrg.Id)

View File

@ -63,13 +63,13 @@ func (hs *HTTPServer) GetUserByLoginOrEmail(c *models.ReqContext) response.Respo
}
user := query.Result
result := models.UserProfileDTO{
Id: user.Id,
Id: user.ID,
Name: user.Name,
Email: user.Email,
Login: user.Login,
Theme: user.Theme,
IsGrafanaAdmin: user.IsAdmin,
OrgId: user.OrgId,
OrgId: user.OrgID,
UpdatedAt: user.Updated,
CreatedAt: user.Created,
}

View File

@ -25,6 +25,7 @@ import (
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -56,7 +57,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
)
hs.authInfoService = srv
createUserCmd := models.CreateUserCommand{
createUserCmd := user.CreateUserCommand{
Email: fmt.Sprint("user", "@test.com"),
Name: "user",
Login: "loginuser",
@ -77,7 +78,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
token = token.WithExtra(map[string]interface{}{"id_token": idToken})
query := &models.GetUserByAuthInfoQuery{Login: "loginuser", AuthModule: "test", AuthId: "test"}
cmd := &models.UpdateAuthInfoCommand{
UserId: user.Id,
UserId: user.ID,
AuthId: query.AuthId,
AuthModule: query.AuthModule,
OAuthToken: token,
@ -85,7 +86,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
err = srv.UpdateAuthInfo(context.Background(), cmd)
require.NoError(t, err)
avatarUrl := dtos.GetGravatarUrl("@test.com")
sc.fakeReqWithParams("GET", sc.url, map[string]string{"id": fmt.Sprintf("%v", user.Id)}).exec()
sc.fakeReqWithParams("GET", sc.url, map[string]string{"id": fmt.Sprintf("%v", user.ID)}).exec()
expected := models.UserProfileDTO{
Id: 1,
@ -111,7 +112,7 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
}, mock)
loggedInUserScenario(t, "When calling GET on", "/api/users/lookup", "/api/users/lookup", func(sc *scenarioContext) {
createUserCmd := models.CreateUserCommand{
createUserCmd := user.CreateUserCommand{
Email: fmt.Sprint("admin", "@test.com"),
Name: "admin",
Login: "admin",

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/auth"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
)
@ -29,7 +30,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
t.Run("When current user gets auth tokens for a non-existing user", func(t *testing.T) {
mock := &mockstore.SQLStoreMock{
ExpectedUser: &models.User{Id: 200},
ExpectedUser: &user.User{ID: 200},
ExpectedError: models.ErrUserNotFound,
}
getUserAuthTokensScenario(t, "Should return not found when calling GET on", "/api/user/auth-tokens", "/api/user/auth-tokens", 200, func(sc *scenarioContext) {
@ -40,7 +41,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
t.Run("When logging out an existing user from all devices", func(t *testing.T) {
mock := &mockstore.SQLStoreMock{
ExpectedUser: &models.User{Id: 200},
ExpectedUser: &user.User{ID: 200},
}
logoutUserFromAllDevicesInternalScenario(t, "Should be successful", 1, func(sc *scenarioContext) {
sc.fakeReqWithParams("POST", sc.url, map[string]string{}).exec()
@ -61,7 +62,7 @@ func TestUserTokenAPIEndpoint(t *testing.T) {
cmd := models.RevokeAuthTokenCmd{AuthTokenId: 2}
token := &models.UserToken{Id: 1}
mock := &mockstore.SQLStoreMock{
ExpectedUser: &models.User{Id: 200},
ExpectedUser: &user.User{ID: 200},
}
revokeUserAuthTokenInternalScenario(t, "Should be successful", cmd, 200, token, func(sc *scenarioContext) {

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -96,7 +97,7 @@ func mockPasswordValidation(valid bool, sc *grafanaLoginScenarioContext) {
}
}
func (sc *grafanaLoginScenarioContext) getUserByLoginQueryReturns(user *models.User) {
func (sc *grafanaLoginScenarioContext) getUserByLoginQueryReturns(user *user.User) {
sc.store.ExpectedUser = user
if user == nil {
sc.store.ExpectedError = models.ErrUserNotFound
@ -104,8 +105,8 @@ func (sc *grafanaLoginScenarioContext) getUserByLoginQueryReturns(user *models.U
}
func (sc *grafanaLoginScenarioContext) withValidCredentials() {
sc.getUserByLoginQueryReturns(&models.User{
Id: 1,
sc.getUserByLoginQueryReturns(&user.User{
ID: 1,
Login: sc.loginUserQuery.Username,
Password: sc.loginUserQuery.Password,
Salt: "salt",
@ -118,7 +119,7 @@ func (sc *grafanaLoginScenarioContext) withNonExistingUser() {
}
func (sc *grafanaLoginScenarioContext) withInvalidPassword() {
sc.getUserByLoginQueryReturns(&models.User{
sc.getUserByLoginQueryReturns(&user.User{
Password: sc.loginUserQuery.Password,
Salt: "salt",
})
@ -126,7 +127,7 @@ func (sc *grafanaLoginScenarioContext) withInvalidPassword() {
}
func (sc *grafanaLoginScenarioContext) withDisabledUser() {
sc.getUserByLoginQueryReturns(&models.User{
sc.getUserByLoginQueryReturns(&user.User{
IsDisabled: true,
})
}

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/contexthandler"
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/stretchr/testify/assert"
@ -59,7 +60,7 @@ func TestMiddlewareBasicAuth(t *testing.T) {
encoded, err := util.EncodePassword(password, salt)
require.NoError(t, err)
sc.mockSQLStore.ExpectedUser = &models.User{Password: encoded, Id: id, Salt: salt}
sc.mockSQLStore.ExpectedUser = &user.User{Password: encoded, ID: id, Salt: salt}
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{UserId: id}
login.ProvideService(sc.mockSQLStore, &logintest.LoginServiceFake{})

View File

@ -27,6 +27,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
"github.com/grafana/grafana/pkg/web"
@ -365,7 +366,7 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should respect auto signup option", func(t *testing.T, sc *scenarioContext) {
var actualAuthProxyAutoSignUp *bool = nil
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *models.User {
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *user.User {
actualAuthProxyAutoSignUp = &cmd.SignupAllowed
return nil
}
@ -386,7 +387,7 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should create an user from a header", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &models.User{Id: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
@ -403,10 +404,10 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should assign role from header to default org", func(t *testing.T, sc *scenarioContext) {
var storedRoleInfo map[int64]models.RoleType = nil
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *models.User {
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *user.User {
storedRoleInfo = cmd.ExternalUser.OrgRoles
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: defaultOrgId, UserId: userID, OrgRole: storedRoleInfo[defaultOrgId]}
return &models.User{Id: userID}
return &user.User{ID: userID}
}
sc.fakeReq("GET", "/")
@ -426,10 +427,10 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should NOT assign role from header to non-default org", func(t *testing.T, sc *scenarioContext) {
var storedRoleInfo map[int64]models.RoleType = nil
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *models.User {
sc.loginService.ExpectedUserFunc = func(cmd *models.UpsertUserCommand) *user.User {
storedRoleInfo = cmd.ExternalUser.OrgRoles
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID, OrgRole: storedRoleInfo[orgID]}
return &models.User{Id: userID}
return &user.User{ID: userID}
}
sc.fakeReq("GET", "/")
@ -453,7 +454,7 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should use organisation specified by targetOrgId parameter", func(t *testing.T, sc *scenarioContext) {
var targetOrgID int64 = 123
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: targetOrgID, UserId: userID}
sc.loginService.ExpectedUser = &models.User{Id: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", fmt.Sprintf("/?targetOrgId=%d", targetOrgID))
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
@ -497,7 +498,7 @@ func TestMiddlewareContext(t *testing.T) {
const orgID int64 = 2
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &models.User{Id: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
@ -513,7 +514,7 @@ func TestMiddlewareContext(t *testing.T) {
middlewareScenario(t, "Should allow the request from whitelist IP", func(t *testing.T, sc *scenarioContext) {
sc.mockSQLStore.ExpectedSignedInUser = &models.SignedInUser{OrgId: orgID, UserId: userID}
sc.loginService.ExpectedUser = &models.User{Id: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
@ -530,7 +531,7 @@ func TestMiddlewareContext(t *testing.T) {
})
middlewareScenario(t, "Should not allow the request from whitelisted IP", func(t *testing.T, sc *scenarioContext) {
sc.loginService.ExpectedUser = &models.User{Id: userID}
sc.loginService.ExpectedUser = &user.User{ID: userID}
sc.fakeReq("GET", "/")
sc.req.Header.Set(sc.cfg.AuthProxyHeaderName, hdrName)
@ -642,7 +643,7 @@ func getContextHandler(t *testing.T, cfg *setting.Cfg, mockSQLStore *mockstore.S
authJWTSvc := models.NewFakeJWTService()
tracer := tracing.InitializeTracerForTest()
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginService, mockSQLStore)
authenticator := &logintest.AuthenticatorFake{ExpectedUser: &models.User{}}
authenticator := &logintest.AuthenticatorFake{ExpectedUser: &user.User{}}
return contexthandler.ProvideService(cfg, userAuthTokenSvc, authJWTSvc, remoteCacheSvc, renderSvc, mockSQLStore, tracer, authProxy, loginService, authenticator)
}

View File

@ -1,6 +1,10 @@
package models
import "errors"
import (
"errors"
"github.com/grafana/grafana/pkg/services/user"
)
var ErrInvalidEmailCode = errors.New("invalid or expired email code")
var ErrSmtpNotEnabled = errors.New("SMTP not configured, check your grafana.ini config file's [smtp] section")
@ -40,10 +44,10 @@ type SendWebhookSync struct {
}
type SendResetPasswordEmailCommand struct {
User *User
User *user.User
}
type ValidateResetPasswordCodeQuery struct {
Code string
Result *User
Result *user.User
}

View File

@ -7,7 +7,7 @@ import (
// Typed errors
var (
ErrTeamMemberAlreadyAdded = errors.New("User is already added to this team")
ErrTeamMemberAlreadyAdded = errors.New("user is already added to this team")
)
// TeamMember model

View File

@ -7,7 +7,7 @@ import (
// Typed errors
var (
ErrTempUserNotFound = errors.New("User not found")
ErrTempUserNotFound = errors.New("user not found")
)
type TempUserStatus string

View File

@ -3,6 +3,8 @@ package models
import (
"errors"
"time"
"github.com/grafana/grafana/pkg/services/user"
)
// Typed errors
@ -20,61 +22,6 @@ func (p Password) IsWeak() bool {
return len(p) <= 4
}
type User struct {
Id int64
Version int
Email string
Name string
Login string
Password string
Salt string
Rands string
Company string
EmailVerified bool
Theme string
HelpFlags1 HelpFlags1
IsDisabled bool
IsAdmin bool
IsServiceAccount bool
OrgId int64
Created time.Time
Updated time.Time
LastSeenAt time.Time
}
func (u *User) NameOrFallback() string {
if u.Name != "" {
return u.Name
}
if u.Login != "" {
return u.Login
}
return u.Email
}
// ---------------------
// COMMANDS
type CreateUserCommand struct {
Email string
Login string
Name string
Company string
OrgId int64
OrgName string
Password string
EmailVerified bool
IsAdmin bool
IsDisabled bool
SkipOrgSetup bool
DefaultOrgRole string
IsServiceAccount bool
Result User
}
type UpdateUserCommand struct {
Name string `json:"name"`
Email string `json:"email"`
@ -115,17 +62,17 @@ type SetUsingOrgCommand struct {
type GetUserByLoginQuery struct {
LoginOrEmail string
Result *User
Result *user.User
}
type GetUserByEmailQuery struct {
Email string
Result *User
Result *user.User
}
type GetUserByIdQuery struct {
Id int64
Result *User
Result *user.User
}
type GetSignedInUserQuery struct {

View File

@ -3,7 +3,9 @@ package models
import (
"time"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"golang.org/x/oauth2"
)
@ -40,7 +42,7 @@ type ExternalUserInfo struct {
type LoginInfo struct {
AuthModule string
User *User
User *user.User
ExternalUser ExternalUserInfo
LoginUsername string
HTTPStatus int
@ -59,7 +61,7 @@ type UpsertUserCommand struct {
ExternalUser *ExternalUserInfo
SignupAllowed bool
Result *User
Result *user.User
}
type SetAuthInfoCommand struct {
@ -87,7 +89,7 @@ type LoginUserQuery struct {
ReqContext *ReqContext
Username string
Password string
User *User
User *user.User
IpAddress string
AuthModule string
Cfg *setting.Cfg

View File

@ -6,6 +6,7 @@ import (
"net"
"github.com/grafana/grafana/pkg/registry"
"github.com/grafana/grafana/pkg/services/user"
)
// Typed errors
@ -65,7 +66,7 @@ type RevokeAuthTokenCmd struct {
// UserTokenService are used for generating and validating user tokens
type UserTokenService interface {
CreateToken(ctx context.Context, user *User, clientIP net.IP, userAgent string) (*UserToken, error)
CreateToken(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*UserToken, error)
LookupToken(ctx context.Context, unhashedToken string) (*UserToken, error)
TryRotateToken(ctx context.Context, token *UserToken, clientIP net.IP, userAgent string) (bool, error)
RevokeToken(ctx context.Context, token *UserToken, soft bool) error

View File

@ -71,6 +71,7 @@ import (
ngmetrics "github.com/grafana/grafana/pkg/services/ngalert/metrics"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/oauthtoken"
"github.com/grafana/grafana/pkg/services/org/orgimpl"
"github.com/grafana/grafana/pkg/services/plugindashboards"
plugindashboardsservice "github.com/grafana/grafana/pkg/services/plugindashboards/service"
"github.com/grafana/grafana/pkg/services/pluginsettings"
@ -99,6 +100,7 @@ import (
teamguardianManager "github.com/grafana/grafana/pkg/services/teamguardian/manager"
"github.com/grafana/grafana/pkg/services/thumbs"
"github.com/grafana/grafana/pkg/services/updatechecker"
"github.com/grafana/grafana/pkg/services/user/userimpl"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/azuremonitor"
"github.com/grafana/grafana/pkg/tsdb/cloudmonitoring"
@ -270,6 +272,8 @@ var wireBasicSet = wire.NewSet(
wire.Bind(new(accesscontrol.DashboardPermissionsService), new(*ossaccesscontrol.DashboardPermissionsService)),
starimpl.ProvideService,
dashverimpl.ProvideService,
userimpl.ProvideService,
orgimpl.ProvideService,
)
var wireSet = wire.NewSet(

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type getUserPermissionsTestCase struct {
@ -81,7 +82,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
user, team := createUserAndTeam(t, sql, tt.orgID)
for _, id := range tt.userPermissions {
_, err := store.SetUserResourcePermission(context.Background(), tt.orgID, accesscontrol.User{ID: user.Id}, types.SetResourcePermissionCommand{
_, err := store.SetUserResourcePermission(context.Background(), tt.orgID, accesscontrol.User{ID: user.ID}, types.SetResourcePermissionCommand{
Actions: []string{"dashboards:write"},
Resource: "dashboards",
ResourceID: id,
@ -119,7 +120,7 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
permissions, err := store.GetUserPermissions(context.Background(), accesscontrol.GetUserPermissionsQuery{
OrgID: tt.orgID,
UserID: user.Id,
UserID: user.ID,
Roles: roles,
Actions: tt.actions,
})
@ -130,19 +131,19 @@ func TestAccessControlStore_GetUserPermissions(t *testing.T) {
}
}
func createUserAndTeam(t *testing.T, sql *sqlstore.SQLStore, orgID int64) (*models.User, models.Team) {
func createUserAndTeam(t *testing.T, sql *sqlstore.SQLStore, orgID int64) (*user.User, models.Team) {
t.Helper()
user, err := sql.CreateUser(context.Background(), models.CreateUserCommand{
user, err := sql.CreateUser(context.Background(), user.CreateUserCommand{
Login: "user",
OrgId: orgID,
OrgID: orgID,
})
require.NoError(t, err)
team, err := sql.CreateTeam("team", "", orgID)
require.NoError(t, err)
err = sql.AddTeamMember(user.Id, orgID, team.Id, false, models.PERMISSION_VIEW)
err = sql.AddTeamMember(user.ID, orgID, team.Id, false, models.PERMISSION_VIEW)
require.NoError(t, err)
return user, team

View File

@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
const (
@ -150,11 +151,11 @@ func generateTeamsAndUsers(b *testing.B, db *sqlstore.SQLStore, users int) ([]in
for u := 0; u < UsersPerTeam; u++ {
userName := fmt.Sprintf("%s%v", "user", globalUserId)
userEmail := fmt.Sprintf("%s@example.org", userName)
createUserCmd := models.CreateUserCommand{Email: userEmail, Name: userName, Login: userName, OrgId: 1}
createUserCmd := user.CreateUserCommand{Email: userEmail, Name: userName, Login: userName, OrgID: 1}
user, err := db.CreateUser(context.Background(), createUserCmd)
require.NoError(b, err)
userId := user.Id
userId := user.ID
globalUserId++
userIds = append(userIds, userId)

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/resourcepermissions/types"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type setUserResourcePermissionTest struct {
@ -448,13 +449,13 @@ func seedResourcePermissions(t *testing.T, store *AccessControlStore, sql *sqlst
org = &addedOrg
}
u, err := sql.CreateUser(context.Background(), models.CreateUserCommand{
u, err := sql.CreateUser(context.Background(), user.CreateUserCommand{
Login: fmt.Sprintf("user:%s%d", resourceID, i),
OrgId: org.Id,
OrgID: org.Id,
})
require.NoError(t, err)
_, err = store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: u.Id}, types.SetResourcePermissionCommand{
_, err = store.SetUserResourcePermission(context.Background(), 1, accesscontrol.User{ID: u.ID}, types.SetResourcePermissionCommand{
Actions: actions,
Resource: resource,
ResourceID: resourceID,

View File

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/contexthandler/ctxkey"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -400,7 +401,7 @@ func TestApi_setUserPermission(t *testing.T) {
server := setupTestServer(t, &models.SignedInUser{OrgId: 1, Permissions: map[int64]map[string][]string{1: accesscontrol.GroupScopesByAction(tt.permissions)}}, service)
// seed user
_, err := sql.CreateUser(context.Background(), models.CreateUserCommand{Login: "test", OrgId: 1})
_, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "test", OrgID: 1})
require.NoError(t, err)
recorder := setPermission(t, server, testOptions.Resource, tt.resourceID, tt.permission, "users", strconv.Itoa(int(tt.userID)))
@ -502,9 +503,9 @@ func seedPermissions(t *testing.T, resourceID string, sql *sqlstore.SQLStore, se
_, err = service.SetTeamPermission(context.Background(), team.OrgId, team.Id, resourceID, "Edit")
require.NoError(t, err)
// seed user 1 with "View" permission on dashboard 1
u, err := sql.CreateUser(context.Background(), models.CreateUserCommand{Login: "test", OrgId: 1})
u, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "test", OrgID: 1})
require.NoError(t, err)
_, err = service.SetUserPermission(context.Background(), u.OrgId, accesscontrol.User{ID: u.Id}, resourceID, "View")
_, err = service.SetUserPermission(context.Background(), u.OrgID, accesscontrol.User{ID: u.ID}, resourceID, "View")
require.NoError(t, err)
// seed built in role Admin with "Edit" permission on dashboard 1
_, err = service.SetBuiltInRolePermission(context.Background(), 1, "Admin", resourceID, "Edit")

View File

@ -8,12 +8,12 @@ import (
"github.com/stretchr/testify/require"
"github.com/grafana/grafana/pkg/api/routing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/accesscontrol/database"
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/licensing/licensingtest"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -43,7 +43,7 @@ func TestService_SetUserPermission(t *testing.T) {
})
// seed user
user, err := sql.CreateUser(context.Background(), models.CreateUserCommand{Login: "test", OrgId: 1})
user, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "test", OrgID: 1})
require.NoError(t, err)
var hookCalled bool
@ -54,7 +54,7 @@ func TestService_SetUserPermission(t *testing.T) {
}
}
_, err = service.SetUserPermission(context.Background(), user.OrgId, accesscontrol.User{ID: user.Id}, "1", "")
_, err = service.SetUserPermission(context.Background(), user.OrgID, accesscontrol.User{ID: user.ID}, "1", "")
require.NoError(t, err)
assert.Equal(t, tt.callHook, hookCalled)
})
@ -200,7 +200,7 @@ func TestService_SetPermissions(t *testing.T) {
service, sql := setupTestEnvironment(t, []accesscontrol.Permission{}, tt.options)
// seed user
_, err := sql.CreateUser(context.Background(), models.CreateUserCommand{Login: "user", OrgId: 1})
_, err := sql.CreateUser(context.Background(), user.CreateUserCommand{Login: "user", OrgID: 1})
require.NoError(t, err)
_, err = sql.CreateTeam("team", "", 1)
require.NoError(t, err)

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@ -57,7 +58,7 @@ func (s *UserAuthTokenService) ActiveTokenCount(ctx context.Context) (int64, err
return count, err
}
func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *models.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
token, err := util.RandomHex(16)
if err != nil {
return nil, err
@ -72,7 +73,7 @@ func (s *UserAuthTokenService) CreateToken(ctx context.Context, user *models.Use
}
userAuthToken := userAuthToken{
UserId: user.Id,
UserId: user.ID,
AuthToken: hashedToken,
PrevAuthToken: hashedToken,
ClientIp: clientIPStr,

View File

@ -14,13 +14,14 @@ import (
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
func TestUserAuthToken(t *testing.T) {
ctx := createTestContext(t)
user := &models.User{Id: int64(10)}
user := &user.User{ID: int64(10)}
// userID := user.Id
now := time.Date(2018, 12, 13, 13, 45, 0, 0, time.UTC)
@ -49,7 +50,7 @@ func TestUserAuthToken(t *testing.T) {
userToken, err := ctx.tokenService.LookupToken(context.Background(), userToken.UnhashedToken)
require.Nil(t, err)
require.NotNil(t, userToken)
require.Equal(t, user.Id, userToken.UserId)
require.Equal(t, user.ID, userToken.UserId)
require.True(t, userToken.AuthTokenSeen)
storedAuthToken, err := ctx.getAuthTokenByID(userToken.Id)
@ -104,21 +105,21 @@ func TestUserAuthToken(t *testing.T) {
require.NotNil(t, userToken2)
t.Run("Can get first user token", func(t *testing.T) {
token, err := ctx.tokenService.GetUserToken(context.Background(), user.Id, userToken.Id)
token, err := ctx.tokenService.GetUserToken(context.Background(), user.ID, userToken.Id)
require.Nil(t, err)
require.NotNil(t, token)
require.Equal(t, userToken.Id, token.Id)
})
t.Run("Can get second user token", func(t *testing.T) {
token, err := ctx.tokenService.GetUserToken(context.Background(), user.Id, userToken2.Id)
token, err := ctx.tokenService.GetUserToken(context.Background(), user.ID, userToken2.Id)
require.Nil(t, err)
require.NotNil(t, token)
require.Equal(t, userToken2.Id, token.Id)
})
t.Run("Can get user tokens", func(t *testing.T) {
tokens, err := ctx.tokenService.GetUserTokens(context.Background(), user.Id)
tokens, err := ctx.tokenService.GetUserTokens(context.Background(), user.ID)
require.Nil(t, err)
require.Equal(t, 2, len(tokens))
require.Equal(t, userToken.Id, tokens[0].Id)
@ -126,7 +127,7 @@ func TestUserAuthToken(t *testing.T) {
})
t.Run("Can revoke all user tokens", func(t *testing.T) {
err := ctx.tokenService.RevokeAllUserTokens(context.Background(), user.Id)
err := ctx.tokenService.RevokeAllUserTokens(context.Background(), user.ID)
require.Nil(t, err)
model, err := ctx.getAuthTokenByID(userToken.Id)
@ -143,7 +144,7 @@ func TestUserAuthToken(t *testing.T) {
t.Run("Can revoke all users tokens", func(t *testing.T) {
userIds := []int64{}
for i := 0; i < 3; i++ {
userId := user.Id + int64(i+1)
userId := user.ID + int64(i+1)
userIds = append(userIds, userId)
_, err := ctx.tokenService.CreateToken(context.Background(), user,
net.ParseIP("192.168.10.11"), "some user agent")

View File

@ -5,10 +5,11 @@ import (
"net"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
type FakeUserAuthTokenService struct {
CreateTokenProvider func(ctx context.Context, user *models.User, clientIP net.IP, userAgent string) (*models.UserToken, error)
CreateTokenProvider func(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*models.UserToken, error)
TryRotateTokenProvider func(ctx context.Context, token *models.UserToken, clientIP net.IP, userAgent string) (bool, error)
LookupTokenProvider func(ctx context.Context, unhashedToken string) (*models.UserToken, error)
RevokeTokenProvider func(ctx context.Context, token *models.UserToken, soft bool) error
@ -22,7 +23,7 @@ type FakeUserAuthTokenService struct {
func NewFakeUserAuthTokenService() *FakeUserAuthTokenService {
return &FakeUserAuthTokenService{
CreateTokenProvider: func(ctx context.Context, user *models.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
CreateTokenProvider: func(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
return &models.UserToken{
UserId: 0,
UnhashedToken: "",
@ -64,7 +65,7 @@ func (s *FakeUserAuthTokenService) Init() error {
return nil
}
func (s *FakeUserAuthTokenService) CreateToken(ctx context.Context, user *models.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
func (s *FakeUserAuthTokenService) CreateToken(ctx context.Context, user *user.User, clientIP net.IP, userAgent string) (*models.UserToken, error) {
return s.CreateTokenProvider(context.Background(), user, clientIP, userAgent)
}

View File

@ -15,6 +15,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/rendering"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
@ -81,7 +82,7 @@ func getContextHandler(t *testing.T) *ContextHandler {
authJWTSvc := models.NewFakeJWTService()
tracer := tracing.InitializeTracerForTest()
loginService := loginservice.LoginServiceMock{ExpectedUser: &models.User{Id: userID}}
loginService := loginservice.LoginServiceMock{ExpectedUser: &user.User{ID: userID}}
authProxy := authproxy.ProvideAuthProxy(cfg, remoteCacheSvc, loginService, &FakeGetSignUserStore{})
authenticator := &fakeAuthenticator{}

View File

@ -246,7 +246,7 @@ func (auth *AuthProxy) LoginViaLDAP(reqCtx *models.ReqContext) (int64, error) {
return 0, err
}
return upsert.Result.Id, nil
return upsert.Result.ID, nil
}
// loginViaHeader logs in user from the header only
@ -305,7 +305,7 @@ func (auth *AuthProxy) loginViaHeader(reqCtx *models.ReqContext) (int64, error)
return 0, err
}
return upsert.Result.Id, nil
return upsert.Result.ID, nil
}
// getDecodedHeader gets decoded value of a header with given headerName

View File

@ -7,14 +7,15 @@ import (
"net/http"
"testing"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -42,8 +43,8 @@ func prepareMiddleware(t *testing.T, remoteCache *remotecache.RemoteCache, confi
}
loginService := loginservice.LoginServiceMock{
ExpectedUser: &models.User{
Id: id,
ExpectedUser: &user.User{
ID: id,
},
}

View File

@ -348,11 +348,11 @@ func (h *ContextHandler) initContextWithBasicAuth(reqContext *models.ReqContext,
user := authQuery.User
query := models.GetSignedInUserQuery{UserId: user.Id, OrgId: orgID}
query := models.GetSignedInUserQuery{UserId: user.ID, OrgId: orgID}
if err := h.SQLStore.GetSignedInUserWithCacheCtx(ctx, &query); err != nil {
reqContext.Logger.Error(
"Failed at user signed in",
"id", user.Id,
"id", user.ID,
"org", orgID,
)
reqContext.JsonApiErr(401, InvalidUsernamePassword, err)

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@ -14,7 +15,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
t.Skip("skipping integration test")
}
var sqlStore *sqlstore.SQLStore
var currentUser models.User
var currentUser user.User
var savedFolder, childDash *models.Dashboard
var dashboardStore *DashboardStore
@ -87,7 +88,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
setup(t)
err := updateDashboardAcl(t, dashboardStore, savedFolder.Id, models.DashboardAcl{
OrgID: 1,
UserID: currentUser.Id,
UserID: currentUser.ID,
DashboardID: savedFolder.Id,
Permission: models.PERMISSION_EDIT,
})
@ -106,7 +107,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
t.Run("Given child dashboard permission", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, childDash.Id, models.DashboardAcl{
OrgID: 1,
UserID: currentUser.Id,
UserID: currentUser.ID,
DashboardID: childDash.Id,
Permission: models.PERMISSION_EDIT,
})
@ -131,7 +132,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
setup(t)
err := updateDashboardAcl(t, dashboardStore, childDash.Id, models.DashboardAcl{
OrgID: 1,
UserID: currentUser.Id,
UserID: currentUser.ID,
DashboardID: childDash.Id,
Permission: models.PERMISSION_EDIT,
})
@ -158,7 +159,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
setup(t)
err := updateDashboardAcl(t, dashboardStore, savedFolder.Id, models.DashboardAcl{
OrgID: 1,
UserID: currentUser.Id,
UserID: currentUser.ID,
DashboardID: savedFolder.Id,
Permission: models.PERMISSION_EDIT,
})
@ -171,7 +172,7 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
require.Equal(t, savedFolder.Id, q1.Result[0].DashboardId)
require.Equal(t, models.PERMISSION_EDIT, q1.Result[0].Permission)
require.Equal(t, "Edit", q1.Result[0].PermissionName)
require.Equal(t, currentUser.Id, q1.Result[0].UserId)
require.Equal(t, currentUser.ID, q1.Result[0].UserId)
require.Equal(t, currentUser.Login, q1.Result[0].UserLogin)
require.Equal(t, currentUser.Email, q1.Result[0].UserEmail)
@ -248,15 +249,15 @@ func TestIntegrationDashboardAclDataAccess(t *testing.T) {
})
}
func createUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role string, isAdmin bool) models.User {
func createUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role string, isAdmin bool) user.User {
t.Helper()
sqlStore.Cfg.AutoAssignOrg = true
sqlStore.Cfg.AutoAssignOrgId = 1
sqlStore.Cfg.AutoAssignOrgRole = role
currentUserCmd := models.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin}
currentUserCmd := user.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin}
currentUser, err := sqlStore.CreateUser(context.Background(), currentUserCmd)
require.NoError(t, err)
q1 := models.GetUserOrgListQuery{UserId: currentUser.Id}
q1 := models.GetUserOrgListQuery{UserId: currentUser.ID}
err = sqlStore.GetUserOrgList(context.Background(), &q1)
require.NoError(t, err)
require.Equal(t, models.RoleType(role), q1.Result[0].Role)

View File

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
@ -18,7 +19,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Testing DB", func(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var folder, dashInRoot, childDash *models.Dashboard
var currentUser models.User
var currentUser user.User
var dashboardStore *DashboardStore
setup := func() {
@ -38,7 +39,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("and no acls are set", func(t *testing.T) {
t.Run("should return all dashboards", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
@ -62,7 +63,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1, DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
err := testSearchDashboards(dashboardStore, query)
@ -74,13 +75,13 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("when the user is given permission", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, folder.Id, models.DashboardAcl{
DashboardID: folder.Id, OrgID: 1, UserID: currentUser.Id, Permission: models.PERMISSION_EDIT,
DashboardID: folder.Id, OrgID: 1, UserID: currentUser.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
t.Run("should be able to access folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1,
DashboardIds: []int64{folder.Id, dashInRoot.Id},
}
@ -96,7 +97,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should be able to access folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
UserId: currentUser.Id,
UserId: currentUser.ID,
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
},
@ -123,7 +124,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder or child", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id},
}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
@ -133,12 +134,12 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("when the user is given permission to child", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, childDash.Id, models.DashboardAcl{
DashboardID: childDash.Id, OrgID: 1, UserID: currentUser.Id, Permission: models.PERMISSION_EDIT,
DashboardID: childDash.Id, OrgID: 1, UserID: currentUser.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
t.Run("should be able to search for child dashboard but not folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}}
query := &models.FindPersistedDashboardsQuery{SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER}, OrgId: 1, DashboardIds: []int64{folder.Id, childDash.Id, dashInRoot.Id}}
err := testSearchDashboards(dashboardStore, query)
require.NoError(t, err)
require.Equal(t, len(query.Result), 2)
@ -151,7 +152,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should be able to search for child dash and folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{
UserId: currentUser.Id,
UserId: currentUser.ID,
OrgId: 1,
OrgRole: models.ROLE_ADMIN,
},
@ -172,7 +173,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Given two dashboard folders with one dashboard each and one dashboard in the root folder", func(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var folder1, folder2, dashInRoot, childDash1, childDash2 *models.Dashboard
var currentUser models.User
var currentUser user.User
var rootFolderId int64 = 0
setup2 := func() {
@ -192,7 +193,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return dashboards in root and expanded folder", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
FolderIds: []int64{
rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.Id,
rootFolderId, folder1.Id}, SignedInUser: &models.SignedInUser{UserId: currentUser.ID,
OrgId: 1, OrgRole: models.ROLE_VIEWER,
},
OrgId: 1,
@ -219,7 +220,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not return folder with acl or its children", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1,
DashboardIds: []int64{folder1.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@ -235,7 +236,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return folder without acl and its children", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1,
DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@ -259,7 +260,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should return folder without acl but not the dashboard with acl", func(t *testing.T) {
query := &models.FindPersistedDashboardsQuery{
SignedInUser: &models.SignedInUser{UserId: currentUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: currentUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
OrgId: 1,
DashboardIds: []int64{folder2.Id, childDash1.Id, childDash2.Id, dashInRoot.Id},
}
@ -278,7 +279,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Given two dashboard folders", func(t *testing.T) {
var sqlStore *sqlstore.SQLStore
var folder1, folder2 *models.Dashboard
var adminUser, editorUser, viewerUser models.User
var adminUser, editorUser, viewerUser user.User
setup3 := func() {
sqlStore = sqlstore.InitTestDB(t)
@ -297,7 +298,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Should have write access to all dashboard folders in their org", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: adminUser.Id, OrgRole: models.ROLE_ADMIN, OrgId: 1},
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgRole: models.ROLE_ADMIN, OrgId: 1},
Permission: models.PERMISSION_VIEW,
Type: "dash-folder",
}
@ -312,7 +313,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.Id, OrgId: 1, OrgRole: models.ROLE_ADMIN},
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
require.NoError(t, err)
@ -321,7 +322,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.Id, OrgId: 1, OrgRole: models.ROLE_ADMIN},
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_ADMIN},
}
err := dashboardStore.HasAdminPermissionInFolders(context.Background(), query)
require.NoError(t, err)
@ -332,7 +333,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Editor users", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: editorUser.Id, OrgRole: models.ROLE_EDITOR, OrgId: 1},
SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgRole: models.ROLE_EDITOR, OrgId: 1},
Permission: models.PERMISSION_EDIT,
}
@ -347,7 +348,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Should have write access to one dashboard folder if default role changed to view for one folder", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, folder1.Id, models.DashboardAcl{
DashboardID: folder1.Id, OrgID: 1, UserID: editorUser.Id, Permission: models.PERMISSION_VIEW,
DashboardID: folder1.Id, OrgID: 1, UserID: editorUser.ID, Permission: models.PERMISSION_VIEW,
})
require.NoError(t, err)
@ -360,7 +361,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: editorUser.Id, OrgId: 1, OrgRole: models.ROLE_EDITOR},
SignedInUser: &models.SignedInUser{UserId: editorUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@ -369,7 +370,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.Id, OrgId: 1, OrgRole: models.ROLE_EDITOR},
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_EDITOR},
}
err := dashboardStore.HasAdminPermissionInFolders(context.Background(), query)
require.NoError(t, err)
@ -380,7 +381,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Viewer users", func(t *testing.T) {
query := models.FindPersistedDashboardsQuery{
OrgId: 1,
SignedInUser: &models.SignedInUser{UserId: viewerUser.Id, OrgRole: models.ROLE_VIEWER, OrgId: 1},
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgRole: models.ROLE_VIEWER, OrgId: 1},
Permission: models.PERMISSION_EDIT,
}
@ -393,7 +394,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("Should be able to get one dashboard folder if default role changed to edit for one folder", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, folder1.Id, models.DashboardAcl{
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_EDIT,
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
@ -408,7 +409,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
setup3()
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@ -417,7 +418,7 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("should not have admin permission in folders", func(t *testing.T) {
query := &models.HasAdminPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: adminUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: adminUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
}
err := dashboardStore.HasAdminPermissionInFolders(context.Background(), query)
require.NoError(t, err)
@ -426,13 +427,13 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("and admin permission is given for user with org role viewer in one dashboard folder", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, folder1.Id, models.DashboardAcl{
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_ADMIN,
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.ID, Permission: models.PERMISSION_ADMIN,
})
require.NoError(t, err)
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)
@ -442,13 +443,13 @@ func TestIntegrationDashboardFolderDataAccess(t *testing.T) {
t.Run("and edit permission is given for user with org role viewer in one dashboard folder", func(t *testing.T) {
err := updateDashboardAcl(t, dashboardStore, folder1.Id, models.DashboardAcl{
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.Id, Permission: models.PERMISSION_EDIT,
DashboardID: folder1.Id, OrgID: 1, UserID: viewerUser.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
t.Run("should have edit permission in folders", func(t *testing.T) {
query := &models.HasEditPermissionInFoldersQuery{
SignedInUser: &models.SignedInUser{UserId: viewerUser.Id, OrgId: 1, OrgRole: models.ROLE_VIEWER},
SignedInUser: &models.SignedInUser{UserId: viewerUser.ID, OrgId: 1, OrgRole: models.ROLE_VIEWER},
}
err := dashboardStore.HasEditPermissionInFolders(context.Background(), query)
go require.NoError(t, err)

View File

@ -18,6 +18,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/searchstore"
"github.com/grafana/grafana/pkg/services/star"
"github.com/grafana/grafana/pkg/services/star/starimpl"
"github.com/grafana/grafana/pkg/services/user"
)
func TestIntegrationDashboardDataAccess(t *testing.T) {
@ -666,15 +667,15 @@ func insertTestRule(t *testing.T, sqlStore *sqlstore.SQLStore, foderOrgID int64,
require.NoError(t, err)
}
func CreateUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role string, isAdmin bool) models.User {
func CreateUser(t *testing.T, sqlStore *sqlstore.SQLStore, name string, role string, isAdmin bool) user.User {
t.Helper()
sqlStore.Cfg.AutoAssignOrg = true
sqlStore.Cfg.AutoAssignOrgId = 1
sqlStore.Cfg.AutoAssignOrgRole = role
currentUserCmd := models.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin}
currentUserCmd := user.CreateUserCommand{Login: name, Email: name + "@test.com", Name: "a " + name, IsAdmin: isAdmin}
currentUser, err := sqlStore.CreateUser(context.Background(), currentUserCmd)
require.NoError(t, err)
q1 := models.GetUserOrgListQuery{UserId: currentUser.Id}
q1 := models.GetUserOrgListQuery{UserId: currentUser.ID}
err = sqlStore.GetUserOrgList(context.Background(), &q1)
require.NoError(t, err)
require.Equal(t, models.RoleType(role), q1.Result[0].Role)

View File

@ -25,6 +25,7 @@ import (
"github.com/grafana/grafana/pkg/services/guardian"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
)
@ -345,7 +346,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
),
}
user := models.SignedInUser{
usr := models.SignedInUser{
UserId: 1,
Name: "Signed In User",
Login: "signed_in_user",
@ -358,7 +359,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
// deliberate difference between signed in user and user in db to make it crystal clear
// what to expect in the tests
// In the real world these are identical
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "user.in.db@test.com",
Name: "User In DB",
Login: userInDbName,
@ -368,13 +369,13 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
require.NoError(t, err)
sc := scenarioContext{
user: user,
user: usr,
ctx: &ctx,
service: &service,
sqlStore: sqlStore,
reqContext: &models.ReqContext{
Context: &ctx,
SignedInUser: &user,
SignedInUser: &usr,
},
}

View File

@ -24,6 +24,7 @@ import (
"github.com/grafana/grafana/pkg/services/libraryelements"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -1507,7 +1508,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
LibraryElementService: elementService,
}
user := &models.SignedInUser{
usr := &models.SignedInUser{
UserId: 1,
Name: "Signed In User",
Login: "signed_in_user",
@ -1520,7 +1521,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
// deliberate difference between signed in user and user in db to make it crystal clear
// what to expect in the tests
// In the real world these are identical
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "user.in.db@test.com",
Name: "User In DB",
Login: userInDbName,
@ -1530,7 +1531,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
require.NoError(t, err)
sc := scenarioContext{
user: user,
user: usr,
ctx: context.Background(),
service: &service,
elementService: elementService,

View File

@ -4,10 +4,11 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
type AuthInfoService interface {
LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*models.User, error)
LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*user.User, error)
GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error
GetExternalUserInfoByLogin(ctx context.Context, query *models.GetExternalUserInfoByLoginQuery) error
SetAuthInfo(ctx context.Context, cmd *models.SetAuthInfoCommand) error

View File

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
var GetTime = time.Now
@ -35,13 +36,13 @@ func (s *AuthInfoStore) GetExternalUserInfoByLogin(ctx context.Context, query *m
return err
}
authInfoQuery := &models.GetAuthInfoQuery{UserId: userQuery.Result.Id}
authInfoQuery := &models.GetAuthInfoQuery{UserId: userQuery.Result.ID}
if err := s.GetAuthInfo(ctx, authInfoQuery); err != nil {
return err
}
query.Result = &models.ExternalUserInfo{
UserId: userQuery.Result.Id,
UserId: userQuery.Result.ID,
Login: userQuery.Result.Login,
Email: userQuery.Result.Email,
Name: userQuery.Result.Name,
@ -218,7 +219,7 @@ func (s *AuthInfoStore) DeleteAuthInfo(ctx context.Context, cmd *models.DeleteAu
})
}
func (s *AuthInfoStore) GetUserById(ctx context.Context, id int64) (*models.User, error) {
func (s *AuthInfoStore) GetUserById(ctx context.Context, id int64) (*user.User, error) {
query := models.GetUserByIdQuery{Id: id}
if err := s.sqlStore.GetUserById(ctx, &query); err != nil {
return nil, err
@ -227,7 +228,7 @@ func (s *AuthInfoStore) GetUserById(ctx context.Context, id int64) (*models.User
return query.Result, nil
}
func (s *AuthInfoStore) GetUserByLogin(ctx context.Context, login string) (*models.User, error) {
func (s *AuthInfoStore) GetUserByLogin(ctx context.Context, login string) (*user.User, error) {
query := models.GetUserByLoginQuery{LoginOrEmail: login}
if err := s.sqlStore.GetUserByLogin(ctx, &query); err != nil {
return nil, err
@ -236,7 +237,7 @@ func (s *AuthInfoStore) GetUserByLogin(ctx context.Context, login string) (*mode
return query.Result, nil
}
func (s *AuthInfoStore) GetUserByEmail(ctx context.Context, email string) (*models.User, error) {
func (s *AuthInfoStore) GetUserByEmail(ctx context.Context, email string) (*user.User, error) {
query := models.GetUserByEmailQuery{Email: email}
if err := s.sqlStore.GetUserByEmail(ctx, &query); err != nil {
return nil, err

View File

@ -8,6 +8,7 @@ import (
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/user"
)
const genericOAuthModule = "oauth_generic_oauth"
@ -28,7 +29,7 @@ func ProvideAuthInfoService(userProtectionService login.UserProtectionService, a
return s
}
func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUserByAuthInfoQuery) (bool, *models.User, *models.UserAuth, error) {
func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUserByAuthInfoQuery) (bool, *user.User, *models.UserAuth, error) {
authQuery := &models.GetAuthInfoQuery{}
// Try to find the user by auth module and id first
@ -77,8 +78,8 @@ func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUser
return false, nil, nil, models.ErrUserNotFound
}
func (s *Implementation) LookupByOneOf(ctx context.Context, userId int64, email string, login string) (*models.User, error) {
var user *models.User
func (s *Implementation) LookupByOneOf(ctx context.Context, userId int64, email string, login string) (*user.User, error) {
var user *user.User
var err error
// If not found, try to find the user by id
@ -128,7 +129,7 @@ func (s *Implementation) GenericOAuthLookup(ctx context.Context, authModule stri
return nil, nil
}
func (s *Implementation) LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*models.User, error) {
func (s *Implementation) LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*user.User, error) {
// 1. LookupAndFix = auth info, user, error
// TODO: Not a big fan of the fact that we are deleting auth info here, might want to move that
foundUser, user, authInfo, err := s.LookupAndFix(ctx, query)
@ -149,7 +150,7 @@ func (s *Implementation) LookupAndUpdate(ctx context.Context, query *models.GetU
}
// Special case for generic oauth duplicates
ai, err := s.GenericOAuthLookup(ctx, query.AuthModule, query.AuthId, user.Id)
ai, err := s.GenericOAuthLookup(ctx, query.AuthModule, query.AuthId, user.ID)
if !errors.Is(err, models.ErrUserNotFound) {
if err != nil {
return nil, err
@ -162,7 +163,7 @@ func (s *Implementation) LookupAndUpdate(ctx context.Context, query *models.GetU
if query.AuthModule != "" {
if authInfo == nil {
cmd := &models.SetAuthInfoCommand{
UserId: user.Id,
UserId: user.ID,
AuthModule: query.AuthModule,
AuthId: query.AuthId,
}

View File

@ -12,6 +12,7 @@ import (
secretstore "github.com/grafana/grafana/pkg/services/secrets/database"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
"golang.org/x/oauth2"
)
@ -29,7 +30,7 @@ func TestUserAuth(t *testing.T) {
t.Run("Given 5 users", func(t *testing.T) {
for i := 0; i < 5; i++ {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -49,12 +50,12 @@ func TestUserAuth(t *testing.T) {
require.Equal(t, user.Login, login)
// By ID
id := user.Id
id := user.ID
user, err = srv.LookupByOneOf(context.Background(), id, "", "")
require.Nil(t, err)
require.Equal(t, user.Id, id)
require.Equal(t, user.ID, id)
// By Email
email := "user1@test.com"
@ -98,7 +99,7 @@ func TestUserAuth(t *testing.T) {
require.Equal(t, user.Login, login)
// get with non-matching id
id := user.Id
id := user.ID
query.UserId = id + 1
user, err = srv.LookupAndUpdate(context.Background(), query)
@ -115,7 +116,7 @@ func TestUserAuth(t *testing.T) {
// remove user
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
_, err := sess.Exec("DELETE FROM "+sqlStore.Dialect.Quote("user")+" WHERE id=?", user.Id)
_, err := sess.Exec("DELETE FROM "+sqlStore.Dialect.Quote("user")+" WHERE id=?", user.ID)
return err
})
require.NoError(t, err)
@ -149,7 +150,7 @@ func TestUserAuth(t *testing.T) {
require.Equal(t, user.Login, login)
cmd := &models.UpdateAuthInfoCommand{
UserId: user.Id,
UserId: user.ID,
AuthId: query.AuthId,
AuthModule: query.AuthModule,
OAuthToken: token,
@ -159,7 +160,7 @@ func TestUserAuth(t *testing.T) {
require.Nil(t, err)
getAuthQuery := &models.GetAuthInfoQuery{
UserId: user.Id,
UserId: user.ID,
}
err = srv.authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
@ -176,7 +177,7 @@ func TestUserAuth(t *testing.T) {
sqlStore = sqlstore.InitTestDB(t)
for i := 0; i < 5; i++ {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -210,7 +211,7 @@ func TestUserAuth(t *testing.T) {
// Get the latest entry by not supply an authmodule or authid
getAuthQuery := &models.GetAuthInfoQuery{
UserId: user.Id,
UserId: user.ID,
}
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
@ -219,14 +220,14 @@ func TestUserAuth(t *testing.T) {
require.Equal(t, getAuthQuery.Result.AuthModule, "test2")
// "log in" again with the first auth module
updateAuthCmd := &models.UpdateAuthInfoCommand{UserId: user.Id, AuthModule: "test1", AuthId: "test1"}
updateAuthCmd := &models.UpdateAuthInfoCommand{UserId: user.ID, AuthModule: "test1", AuthId: "test1"}
err = authInfoStore.UpdateAuthInfo(context.Background(), updateAuthCmd)
require.Nil(t, err)
// Get the latest entry by not supply an authmodule or authid
getAuthQuery = &models.GetAuthInfoQuery{
UserId: user.Id,
UserId: user.ID,
}
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
@ -240,7 +241,7 @@ func TestUserAuth(t *testing.T) {
sqlStore = sqlstore.InitTestDB(t)
for i := 0; i < 5; i++ {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -273,7 +274,7 @@ func TestUserAuth(t *testing.T) {
// Get the latest entry by not supply an authmodule or authid
getAuthQuery := &models.GetAuthInfoQuery{
UserId: user.Id,
UserId: user.ID,
}
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
@ -285,7 +286,7 @@ func TestUserAuth(t *testing.T) {
database.GetTime = func() time.Time { return fixedTime }
// add oauth info to auth_info to make sure update date does not overwrite it
updateAuthCmd := &models.UpdateAuthInfoCommand{UserId: user.Id, AuthModule: "test1", AuthId: "test1", OAuthToken: &oauth2.Token{
updateAuthCmd := &models.UpdateAuthInfoCommand{UserId: user.ID, AuthModule: "test1", AuthId: "test1", OAuthToken: &oauth2.Token{
AccessToken: "access_token",
TokenType: "token_type",
RefreshToken: "refresh_token",
@ -317,7 +318,7 @@ func TestUserAuth(t *testing.T) {
// Ensure test 1 did not have its entry modified
getAuthQueryUnchanged := &models.GetAuthInfoQuery{
UserId: user.Id,
UserId: user.ID,
AuthModule: "test1",
}
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQueryUnchanged)
@ -354,11 +355,11 @@ func TestUserAuth(t *testing.T) {
sqlStore = sqlstore.InitTestDB(t)
for i := 0; i < 5; i++ {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
OrgId: 1,
OrgID: 1,
}
_, err := sqlStore.CreateUser(context.Background(), cmd)
require.Nil(t, err)
@ -366,7 +367,7 @@ func TestUserAuth(t *testing.T) {
// "Skipping duplicate users test for mysql as it does make unique constraint case insensitive by default
if sqlStore.GetDialect().DriverName() != "mysql" {
dupUserEmailcmd := models.CreateUserCommand{
dupUserEmailcmd := user.CreateUserCommand{
Email: "USERDUPLICATETEST1@TEST.COM",
Name: "user name 1",
Login: "USER_DUPLICATE_TEST_1_LOGIN",
@ -375,7 +376,7 @@ func TestUserAuth(t *testing.T) {
require.NoError(t, err)
// add additional user with duplicate login where DOMAIN is upper case
dupUserLogincmd := models.CreateUserCommand{
dupUserLogincmd := user.CreateUserCommand{
Email: "userduplicatetest1@test.com",
Name: "user name 1",
Login: "user_duplicate_test_1_login",

View File

@ -1,8 +1,6 @@
package authinfoservice
import (
"github.com/grafana/grafana/pkg/models"
)
import "github.com/grafana/grafana/pkg/services/user"
type OSSUserProtectionImpl struct {
}
@ -11,6 +9,6 @@ func ProvideOSSUserProtectionService() *OSSUserProtectionImpl {
return &OSSUserProtectionImpl{}
}
func (*OSSUserProtectionImpl) AllowUserMapping(_ *models.User, _ string) error {
func (*OSSUserProtectionImpl) AllowUserMapping(_ *user.User, _ string) error {
return nil
}

View File

@ -5,6 +5,7 @@ import (
"errors"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
var (
@ -14,10 +15,10 @@ var (
ErrSignupNotAllowed = errors.New("system administrator has disabled signup")
)
type TeamSyncFunc func(user *models.User, externalUser *models.ExternalUserInfo) error
type TeamSyncFunc func(user *user.User, externalUser *models.ExternalUserInfo) error
type Service interface {
CreateUser(cmd models.CreateUserCommand) (*models.User, error)
CreateUser(cmd user.CreateUserCommand) (*user.User, error)
UpsertUser(ctx context.Context, cmd *models.UpsertUserCommand) error
DisableExternalUser(ctx context.Context, username string) error
SetTeamSyncFunc(TeamSyncFunc)

View File

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
var (
@ -17,11 +18,13 @@ var (
func ProvideService(
sqlStore sqlstore.Store,
userService user.Service,
quotaService *quota.QuotaService,
authInfoService login.AuthInfoService,
) *Implementation {
s := &Implementation{
SQLStore: sqlStore,
userService: userService,
QuotaService: quotaService,
AuthInfoService: authInfoService,
}
@ -30,13 +33,14 @@ func ProvideService(
type Implementation struct {
SQLStore sqlstore.Store
userService user.Service
AuthInfoService login.AuthInfoService
QuotaService *quota.QuotaService
TeamSync login.TeamSyncFunc
}
// CreateUser creates inserts a new one.
func (ls *Implementation) CreateUser(cmd models.CreateUserCommand) (*models.User, error) {
func (ls *Implementation) CreateUser(cmd user.CreateUserCommand) (*user.User, error) {
return ls.SQLStore.CreateUser(context.Background(), cmd)
}
@ -44,7 +48,7 @@ func (ls *Implementation) CreateUser(cmd models.CreateUserCommand) (*models.User
func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUserCommand) error {
extUser := cmd.ExternalUser
user, err := ls.AuthInfoService.LookupAndUpdate(ctx, &models.GetUserByAuthInfoQuery{
usr, err := ls.AuthInfoService.LookupAndUpdate(ctx, &models.GetUserByAuthInfoQuery{
AuthModule: extUser.AuthModule,
AuthId: extUser.AuthId,
UserId: extUser.UserId,
@ -69,14 +73,36 @@ func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUser
return login.ErrUsersQuotaReached
}
cmd.Result, err = ls.createUser(extUser)
result, err := ls.createUser(extUser)
if err != nil {
return err
}
cmd.Result = &user.User{
ID: result.ID,
Version: result.Version,
Email: result.Email,
Name: result.Name,
Login: result.Login,
Password: result.Password,
Salt: result.Salt,
Rands: result.Rands,
Company: result.Company,
EmailVerified: result.EmailVerified,
Theme: result.Theme,
HelpFlags1: result.HelpFlags1,
IsDisabled: result.IsDisabled,
IsAdmin: result.IsAdmin,
IsServiceAccount: result.IsServiceAccount,
OrgID: result.OrgID,
Created: result.Created,
Updated: result.Updated,
LastSeenAt: result.LastSeenAt,
}
if extUser.AuthModule != "" {
cmd2 := &models.SetAuthInfoCommand{
UserId: cmd.Result.Id,
UserId: cmd.Result.ID,
AuthModule: extUser.AuthModule,
AuthId: extUser.AuthId,
OAuthToken: extUser.OAuthToken,
@ -86,7 +112,7 @@ func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUser
}
}
} else {
cmd.Result = user
cmd.Result = usr
err = ls.updateUser(ctx, cmd.Result, extUser)
if err != nil {
@ -101,9 +127,9 @@ func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUser
}
}
if extUser.AuthModule == models.AuthModuleLDAP && user.IsDisabled {
if extUser.AuthModule == models.AuthModuleLDAP && usr.IsDisabled {
// Re-enable user when it found in LDAP
if err := ls.SQLStore.DisableUser(ctx, &models.DisableUserCommand{UserId: cmd.Result.Id, IsDisabled: false}); err != nil {
if err := ls.SQLStore.DisableUser(ctx, &models.DisableUserCommand{UserId: cmd.Result.ID, IsDisabled: false}); err != nil {
return err
}
}
@ -115,7 +141,7 @@ func (ls *Implementation) UpsertUser(ctx context.Context, cmd *models.UpsertUser
// Sync isGrafanaAdmin permission
if extUser.IsGrafanaAdmin != nil && *extUser.IsGrafanaAdmin != cmd.Result.IsAdmin {
if err := ls.SQLStore.UpdateUserPermissions(cmd.Result.Id, *extUser.IsGrafanaAdmin); err != nil {
if err := ls.SQLStore.UpdateUserPermissions(cmd.Result.ID, *extUser.IsGrafanaAdmin); err != nil {
return err
}
}
@ -175,21 +201,20 @@ func (ls *Implementation) SetTeamSyncFunc(teamSyncFunc login.TeamSyncFunc) {
ls.TeamSync = teamSyncFunc
}
func (ls *Implementation) createUser(extUser *models.ExternalUserInfo) (*models.User, error) {
cmd := models.CreateUserCommand{
func (ls *Implementation) createUser(extUser *models.ExternalUserInfo) (*user.User, error) {
cmd := user.CreateUserCommand{
Login: extUser.Login,
Email: extUser.Email,
Name: extUser.Name,
SkipOrgSetup: len(extUser.OrgRoles) > 0,
}
return ls.CreateUser(cmd)
}
func (ls *Implementation) updateUser(ctx context.Context, user *models.User, extUser *models.ExternalUserInfo) error {
func (ls *Implementation) updateUser(ctx context.Context, user *user.User, extUser *models.ExternalUserInfo) error {
// sync user info
updateCmd := &models.UpdateUserCommand{
UserId: user.Id,
UserId: user.ID,
}
needsUpdate := false
@ -215,24 +240,24 @@ func (ls *Implementation) updateUser(ctx context.Context, user *models.User, ext
return nil
}
logger.Debug("Syncing user info", "id", user.Id, "update", updateCmd)
logger.Debug("Syncing user info", "id", user.ID, "update", updateCmd)
return ls.SQLStore.UpdateUser(ctx, updateCmd)
}
func (ls *Implementation) updateUserAuth(ctx context.Context, user *models.User, extUser *models.ExternalUserInfo) error {
func (ls *Implementation) updateUserAuth(ctx context.Context, user *user.User, extUser *models.ExternalUserInfo) error {
updateCmd := &models.UpdateAuthInfoCommand{
AuthModule: extUser.AuthModule,
AuthId: extUser.AuthId,
UserId: user.Id,
UserId: user.ID,
OAuthToken: extUser.OAuthToken,
}
logger.Debug("Updating user_auth info", "user_id", user.Id)
logger.Debug("Updating user_auth info", "user_id", user.ID)
return ls.AuthInfoService.UpdateAuthInfo(ctx, updateCmd)
}
func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, extUser *models.ExternalUserInfo) error {
logger.Debug("Syncing organization roles", "id", user.Id, "extOrgRoles", extUser.OrgRoles)
func (ls *Implementation) syncOrgRoles(ctx context.Context, user *user.User, extUser *models.ExternalUserInfo) error {
logger.Debug("Syncing organization roles", "id", user.ID, "extOrgRoles", extUser.OrgRoles)
// don't sync org roles if none is specified
if len(extUser.OrgRoles) == 0 {
@ -240,7 +265,7 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, e
return nil
}
orgsQuery := &models.GetUserOrgListQuery{UserId: user.Id}
orgsQuery := &models.GetUserOrgListQuery{UserId: user.ID}
if err := ls.SQLStore.GetUserOrgList(ctx, orgsQuery); err != nil {
return err
}
@ -257,7 +282,7 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, e
deleteOrgIds = append(deleteOrgIds, org.OrgId)
} else if extRole != org.Role {
// update role
cmd := &models.UpdateOrgUserCommand{OrgId: org.OrgId, UserId: user.Id, Role: extRole}
cmd := &models.UpdateOrgUserCommand{OrgId: org.OrgId, UserId: user.ID, Role: extRole}
if err := ls.SQLStore.UpdateOrgUser(ctx, cmd); err != nil {
return err
}
@ -271,7 +296,7 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, e
}
// add role
cmd := &models.AddOrgUserCommand{UserId: user.Id, Role: orgRole, OrgId: orgId}
cmd := &models.AddOrgUserCommand{UserId: user.ID, Role: orgRole, OrgId: orgId}
err := ls.SQLStore.AddOrgUser(ctx, cmd)
if err != nil && !errors.Is(err, models.ErrOrgNotFound) {
return err
@ -281,8 +306,8 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, e
// delete any removed org roles
for _, orgId := range deleteOrgIds {
logger.Debug("Removing user's organization membership as part of syncing with OAuth login",
"userId", user.Id, "orgId", orgId)
cmd := &models.RemoveOrgUserCommand{OrgId: orgId, UserId: user.Id}
"userId", user.ID, "orgId", orgId)
cmd := &models.RemoveOrgUserCommand{OrgId: orgId, UserId: user.ID}
if err := ls.SQLStore.RemoveOrgUser(ctx, cmd); err != nil {
if errors.Is(err, models.ErrLastOrgAdmin) {
logger.Error(err.Error(), "userId", cmd.UserId, "orgId", cmd.OrgId)
@ -294,15 +319,15 @@ func (ls *Implementation) syncOrgRoles(ctx context.Context, user *models.User, e
}
// update user's default org if needed
if _, ok := extUser.OrgRoles[user.OrgId]; !ok {
if _, ok := extUser.OrgRoles[user.OrgID]; !ok {
for orgId := range extUser.OrgRoles {
user.OrgId = orgId
user.OrgID = orgId
break
}
return ls.SQLStore.SetUsingOrg(ctx, &models.SetUsingOrgCommand{
UserId: user.Id,
OrgId: user.OrgId,
UserId: user.ID,
OrgId: user.OrgID,
})
}

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/user"
)
type LoginServiceMock struct {
@ -15,13 +16,13 @@ type LoginServiceMock struct {
NoExistingOrgId int64
AlreadyExitingLogin string
GeneratedUserId int64
ExpectedUser *models.User
ExpectedUserFunc func(cmd *models.UpsertUserCommand) *models.User
ExpectedUser *user.User
ExpectedUserFunc func(cmd *models.UpsertUserCommand) *user.User
ExpectedError error
}
func (s LoginServiceMock) CreateUser(cmd models.CreateUserCommand) (*models.User, error) {
if cmd.OrgId == s.NoExistingOrgId {
func (s LoginServiceMock) CreateUser(cmd user.CreateUserCommand) (*user.User, error) {
if cmd.OrgID == s.NoExistingOrgId {
return nil, models.ErrOrgNotFound
}
@ -30,8 +31,8 @@ func (s LoginServiceMock) CreateUser(cmd models.CreateUserCommand) (*models.User
}
if s.ExpectedUserForm.Login == cmd.Login && s.ExpectedUserForm.Email == cmd.Email &&
s.ExpectedUserForm.Password == cmd.Password && s.ExpectedUserForm.Name == cmd.Name && s.ExpectedUserForm.OrgId == cmd.OrgId {
return &models.User{Id: s.GeneratedUserId}, nil
s.ExpectedUserForm.Password == cmd.Password && s.ExpectedUserForm.Name == cmd.Name && s.ExpectedUserForm.OrgId == cmd.OrgID {
return &user.User{ID: s.GeneratedUserId}, nil
}
return nil, errors.New("unexpected cmd")

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/services/login/logintest"
"github.com/grafana/grafana/pkg/services/quota"
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -69,15 +70,15 @@ func Test_teamSync(t *testing.T) {
}
upserCmd := &models.UpsertUserCommand{ExternalUser: &models.ExternalUserInfo{Email: "test_user@example.org"}}
expectedUser := &models.User{
Id: 1,
expectedUser := &user.User{
ID: 1,
Email: "test_user@example.org",
Name: "test_user",
Login: "test_user",
}
authInfoMock.ExpectedUser = expectedUser
var actualUser *models.User
var actualUser *user.User
var actualExternalUser *models.ExternalUserInfo
t.Run("login.TeamSync should not be called when nil", func(t *testing.T) {
@ -87,7 +88,7 @@ func Test_teamSync(t *testing.T) {
assert.Nil(t, actualExternalUser)
t.Run("login.TeamSync should be called when not nil", func(t *testing.T) {
teamSyncFunc := func(user *models.User, externalUser *models.ExternalUserInfo) error {
teamSyncFunc := func(user *user.User, externalUser *models.ExternalUserInfo) error {
actualUser = user
actualExternalUser = externalUser
return nil
@ -100,7 +101,7 @@ func Test_teamSync(t *testing.T) {
})
t.Run("login.TeamSync should propagate its errors to the caller", func(t *testing.T) {
teamSyncFunc := func(user *models.User, externalUser *models.ExternalUserInfo) error {
teamSyncFunc := func(user *user.User, externalUser *models.ExternalUserInfo) error {
return errors.New("teamsync test error")
}
login.TeamSync = teamSyncFunc
@ -110,9 +111,9 @@ func Test_teamSync(t *testing.T) {
})
}
func createSimpleUser() models.User {
user := models.User{
Id: 1,
func createSimpleUser() user.User {
user := user.User{
ID: 1,
}
return user

View File

@ -5,11 +5,12 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/user"
)
type LoginServiceFake struct{}
func (l *LoginServiceFake) CreateUser(cmd models.CreateUserCommand) (*models.User, error) {
func (l *LoginServiceFake) CreateUser(cmd user.CreateUserCommand) (*user.User, error) {
return nil, nil
}
func (l *LoginServiceFake) UpsertUser(ctx context.Context, cmd *models.UpsertUserCommand) error {
@ -22,12 +23,12 @@ func (l *LoginServiceFake) SetTeamSyncFunc(login.TeamSyncFunc) {}
type AuthInfoServiceFake struct {
LatestUserID int64
ExpectedUser *models.User
ExpectedUser *user.User
ExpectedExternalUser *models.ExternalUserInfo
ExpectedError error
}
func (a *AuthInfoServiceFake) LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*models.User, error) {
func (a *AuthInfoServiceFake) LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*user.User, error) {
a.LatestUserID = query.UserId
return a.ExpectedUser, a.ExpectedError
}
@ -51,7 +52,7 @@ func (a *AuthInfoServiceFake) GetExternalUserInfoByLogin(ctx context.Context, qu
}
type AuthenticatorFake struct {
ExpectedUser *models.User
ExpectedUser *user.User
ExpectedError error
}

View File

@ -4,10 +4,11 @@ import (
"context"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
)
type UserProtectionService interface {
AllowUserMapping(user *models.User, authModule string) error
AllowUserMapping(user *user.User, authModule string) error
}
type Store interface {
@ -17,8 +18,8 @@ type Store interface {
UpdateAuthInfo(ctx context.Context, cmd *models.UpdateAuthInfoCommand) error
UpdateAuthInfoDate(ctx context.Context, authInfo *models.UserAuth) error
DeleteAuthInfo(ctx context.Context, cmd *models.DeleteAuthInfoCommand) error
GetUserById(ctx context.Context, id int64) (*models.User, error)
GetUserByLogin(ctx context.Context, login string) (*models.User, error)
GetUserByEmail(ctx context.Context, email string) (*models.User, error)
GetUserById(ctx context.Context, id int64) (*user.User, error)
GetUserByLogin(ctx context.Context, login string) (*user.User, error)
GetUserByEmail(ctx context.Context, email string) (*user.User, error)
CollectLoginStats(ctx context.Context) (map[string]interface{}, error)
}

View File

@ -3,6 +3,7 @@ package multildap
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/user"
)
type MultiLDAPmock struct {
@ -10,7 +11,7 @@ type MultiLDAPmock struct {
ID int64
UserCalled bool
LoginCalled bool
UserInfo *models.User
UserInfo *user.User
AuthModule string
ExpectedErr error
}

View File

@ -8,7 +8,7 @@ import (
"github.com/unknwon/com"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -49,7 +49,7 @@ func createTimeLimitCode(data string, minutes int, startInf interface{}) (string
}
// verify time limit code
func validateUserEmailCode(cfg *setting.Cfg, user *models.User, code string) (bool, error) {
func validateUserEmailCode(cfg *setting.Cfg, user *user.User, code string) (bool, error) {
if len(code) <= 18 {
return false, nil
}
@ -65,7 +65,7 @@ func validateUserEmailCode(cfg *setting.Cfg, user *models.User, code string) (bo
}
// right active code
data := com.ToStr(user.Id) + user.Email + user.Login + user.Password + user.Rands
data := com.ToStr(user.ID) + user.Email + user.Login + user.Password + user.Rands
retCode, err := createTimeLimitCode(data, minutes, start)
if err != nil {
return false, err
@ -93,9 +93,9 @@ func getLoginForEmailCode(code string) string {
return string(b)
}
func createUserEmailCode(cfg *setting.Cfg, u *models.User, startInf interface{}) (string, error) {
func createUserEmailCode(cfg *setting.Cfg, u *user.User, startInf interface{}) (string, error) {
minutes := cfg.EmailCodeValidMinutes
data := com.ToStr(u.Id) + u.Email + u.Login + u.Password + u.Rands
data := com.ToStr(u.ID) + u.Email + u.Login + u.Password + u.Rands
code, err := createTimeLimitCode(data, minutes, startInf)
if err != nil {
return "", err

View File

@ -3,7 +3,7 @@ package notifications
import (
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
@ -14,7 +14,7 @@ func TestEmailCodes(t *testing.T) {
cfg := setting.NewCfg()
cfg.EmailCodeValidMinutes = 120
user := &models.User{Id: 10, Email: "t@a.com", Login: "asd", Password: "1", Rands: "2"}
user := &user.User{ID: 10, Email: "t@a.com", Login: "asd", Password: "1", Rands: "2"}
code, err := createUserEmailCode(cfg, user, nil)
require.NoError(t, err)

View File

@ -1,7 +1,7 @@
package notifications
import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
)
@ -24,7 +24,7 @@ type Message struct {
AttachedFiles []*AttachedFile
}
func setDefaultTemplateData(cfg *setting.Cfg, data map[string]interface{}, u *models.User) {
func setDefaultTemplateData(cfg *setting.Cfg, data map[string]interface{}, u *user.User) {
data["AppUrl"] = setting.AppUrl
data["BuildVersion"] = setting.BuildVersion
data["BuildStamp"] = setting.BuildStamp

View File

@ -13,6 +13,7 @@ import (
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@ -181,7 +182,7 @@ func (ns *NotificationService) SendResetPasswordEmail(ctx context.Context, cmd *
})
}
type GetUserByLoginFunc = func(c context.Context, login string) (*models.User, error)
type GetUserByLoginFunc = func(c context.Context, login string) (*user.User, error)
func (ns *NotificationService) ValidateResetPasswordCode(ctx context.Context, query *models.ValidateResetPasswordCodeQuery, userByLogin GetUserByLoginFunc) error {
login := getLoginForEmailCode(query.Code)

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -184,7 +185,7 @@ func TestSendEmailAsync(t *testing.T) {
t.Run("When sending reset email password", func(t *testing.T) {
sut, _ := createSut(t, bus)
err := sut.SendResetPasswordEmail(context.Background(), &models.SendResetPasswordEmailCommand{User: &models.User{Email: "asd@asd.com"}})
err := sut.SendResetPasswordEmail(context.Background(), &models.SendResetPasswordEmailCommand{User: &user.User{Email: "asd@asd.com"}})
require.NoError(t, err)
sentMsg := <-sut.mailQueue

60
pkg/services/org/model.go Normal file
View File

@ -0,0 +1,60 @@
package org
import (
"errors"
"time"
)
// Typed errors
var (
ErrOrgNotFound = errors.New("organization not found")
ErrOrgNameTaken = errors.New("organization name is taken")
)
type Org struct {
ID int64 `xorm:"pk autoincr 'id'"`
Version int
Name string
Address1 string
Address2 string
City string
ZipCode string
State string
Country string
Created time.Time
Updated time.Time
}
type OrgUser struct {
ID int64 `xorm:"pk autoincr 'id'"`
OrgID int64 `xorm:"org_id"`
UserID int64 `xorm:"user_id"`
Role RoleType
Created time.Time
Updated time.Time
}
// swagger:enum RoleType
type RoleType string
const (
ROLE_VIEWER RoleType = "Viewer"
ROLE_EDITOR RoleType = "Editor"
ROLE_ADMIN RoleType = "Admin"
)
type CreateOrgCommand struct {
Name string `json:"name" binding:"Required"`
// initial admin user for account
UserID int64 `json:"-"`
}
type GetOrgIDForNewUserCommand struct {
Email string
Login string
OrgID int64
OrgName string
SkipOrgSetup bool
}

10
pkg/services/org/org.go Normal file
View File

@ -0,0 +1,10 @@
package org
import (
"context"
)
type Service interface {
GetIDForNewUser(context.Context, GetOrgIDForNewUserCommand) (int64, error)
InsertUser(context.Context, *OrgUser) (int64, error)
}

View File

@ -0,0 +1,78 @@
package orgimpl
import (
"context"
"fmt"
"time"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
type Service struct {
store store
cfg *setting.Cfg
log log.Logger
}
func ProvideService(db db.DB, cfg *setting.Cfg) org.Service {
return &Service{
store: &sqlStore{
db: db,
dialect: db.GetDialect(),
},
cfg: cfg,
log: log.New("org service"),
}
}
func (s *Service) GetIDForNewUser(ctx context.Context, cmd org.GetOrgIDForNewUserCommand) (int64, error) {
var orga org.Org
if cmd.SkipOrgSetup {
return -1, nil
}
if setting.AutoAssignOrg && cmd.OrgID != 0 {
_, err := s.store.Get(ctx, cmd.OrgID)
if err != nil {
return -1, err
}
return cmd.OrgID, nil
}
orgName := cmd.OrgName
if len(orgName) == 0 {
orgName = util.StringsFallback2(cmd.Email, cmd.Login)
}
if setting.AutoAssignOrg {
orga, err := s.store.Get(ctx, int64(s.cfg.AutoAssignOrgId))
if err != nil {
return 0, err
}
if orga.ID != 0 {
return orga.ID, nil
}
if setting.AutoAssignOrgId != 1 {
s.log.Error("Could not create user: organization ID does not exist", "orgID",
setting.AutoAssignOrgId)
return 0, fmt.Errorf("could not create user: organization ID %d does not exist",
setting.AutoAssignOrgId)
}
orga.Name = MainOrgName
orga.ID = int64(setting.AutoAssignOrgId)
} else {
orga.Name = orgName
}
orga.Created = time.Now()
orga.Updated = time.Now()
return s.store.Insert(ctx, &orga)
}
func (s *Service) InsertUser(ctx context.Context, orguser *org.OrgUser) (int64, error) {
return s.store.InsertUser(ctx, orguser)
}

View File

@ -0,0 +1,72 @@
package orgimpl
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/require"
)
func TestOrgService(t *testing.T) {
orgStore := newOrgStoreFake()
orgService := Service{
store: orgStore,
cfg: setting.NewCfg(),
}
t.Run("create org", func(t *testing.T) {
_, err := orgService.GetIDForNewUser(context.Background(), org.GetOrgIDForNewUserCommand{})
require.NoError(t, err)
})
t.Run("create org", func(t *testing.T) {
_, err := orgService.GetIDForNewUser(context.Background(), org.GetOrgIDForNewUserCommand{})
require.NoError(t, err)
})
t.Run("create org with auto assign org ID", func(t *testing.T) {
setting.AutoAssignOrg = true
setting.AutoAssignOrgId = 1
orgStore.ExpectedOrgID = 1
orgStore.ExpectedOrg = &org.Org{}
_, err := orgService.GetIDForNewUser(context.Background(), org.GetOrgIDForNewUserCommand{})
require.NoError(t, err)
})
t.Run("create org with auto assign org ID and orgID", func(t *testing.T) {
setting.AutoAssignOrg = true
setting.AutoAssignOrgId = 1
orgStore.ExpectedOrgID = 1
orgStore.ExpectedOrg = &org.Org{}
_, err := orgService.GetIDForNewUser(context.Background(), org.GetOrgIDForNewUserCommand{OrgID: 1})
require.NoError(t, err)
})
setting.AutoAssignOrg = false
setting.AutoAssignOrgId = 0
}
type FakeOrgStore struct {
ExpectedOrg *org.Org
ExpectedOrgID int64
ExpectedUserID int64
ExpectedError error
}
func newOrgStoreFake() *FakeOrgStore {
return &FakeOrgStore{}
}
func (f *FakeOrgStore) Get(ctx context.Context, orgID int64) (*org.Org, error) {
return f.ExpectedOrg, f.ExpectedError
}
func (f *FakeOrgStore) Insert(ctx context.Context, org *org.Org) (int64, error) {
return f.ExpectedOrgID, f.ExpectedError
}
func (f *FakeOrgStore) InsertUser(ctx context.Context, org *org.OrgUser) (int64, error) {
return f.ExpectedUserID, f.ExpectedError
}

View File

@ -0,0 +1,83 @@
package orgimpl
import (
"context"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
)
const MainOrgName = "Main Org."
type store interface {
Get(context.Context, int64) (*org.Org, error)
Insert(context.Context, *org.Org) (int64, error)
InsertUser(context.Context, *org.OrgUser) (int64, error)
}
type sqlStore struct {
db db.DB
dialect migrator.Dialect
}
func (ss *sqlStore) Get(ctx context.Context, orgID int64) (*org.Org, error) {
var orga org.Org
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
has, err := sess.Where("id=?", orgID).Get(&orga)
if err != nil {
return err
}
if !has {
return org.ErrOrgNotFound
}
return nil
})
if err != nil {
return nil, err
}
return &orga, nil
}
func (ss *sqlStore) Insert(ctx context.Context, org *org.Org) (int64, error) {
var orgID int64
var err error
err = ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
if orgID, err = sess.InsertOne(org); err != nil {
return err
}
if org.ID != 0 {
// it sets the setval in the sequence
if err := ss.dialect.PostInsertId("org", sess.Session); err != nil {
return err
}
}
sess.PublishAfterCommit(&events.OrgCreated{
Timestamp: org.Created,
Id: org.ID,
Name: org.Name,
})
return nil
})
if err != nil {
return 0, err
}
return orgID, nil
}
func (ss *sqlStore) InsertUser(ctx context.Context, cmd *org.OrgUser) (int64, error) {
var orgID int64
var err error
err = ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
if orgID, err = sess.Insert(cmd); err != nil {
return err
}
return nil
})
if err != nil {
return 0, err
}
return orgID, nil
}

View File

@ -0,0 +1,73 @@
package orgimpl
import (
"context"
"testing"
"time"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/stretchr/testify/require"
)
func TestIntegrationOrgDataAccess(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
ss := sqlstore.InitTestDB(t)
orgStore := sqlStore{
db: ss,
dialect: ss.GetDialect(),
}
t.Run("org not found", func(t *testing.T) {
_, err := orgStore.Get(context.Background(), 1)
require.Error(t, err, org.ErrOrgNotFound)
})
t.Run("org inserted", func(t *testing.T) {
_, err := orgStore.Insert(context.Background(), &org.Org{
Version: 1,
Name: "test1",
Created: time.Now(),
Updated: time.Now(),
})
require.NoError(t, err)
})
t.Run("org inserted with next available org ID", func(t *testing.T) {
orgID, err := orgStore.Insert(context.Background(), &org.Org{
ID: 55,
Version: 1,
Name: "test2",
Created: time.Now(),
Updated: time.Now(),
})
require.NoError(t, err)
_, err = orgStore.Get(context.Background(), orgID)
require.NoError(t, err)
})
}
func TestIntegrationOrgUserDataAccess(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
ss := sqlstore.InitTestDB(t)
orgUserStore := sqlStore{
db: ss,
}
t.Run("org user inserted", func(t *testing.T) {
_, err := orgUserStore.InsertUser(context.Background(), &org.OrgUser{
ID: 1,
OrgID: 1,
UserID: 1,
Created: time.Now(),
Updated: time.Now(),
})
require.NoError(t, err)
})
}

View File

@ -0,0 +1,28 @@
package orgtest
import (
"context"
"github.com/grafana/grafana/pkg/services/org"
)
type FakeOrgService struct {
ExpectedOrgUserID int64
ExpectedError error
}
func NewOrgServiceFake() *FakeOrgService {
return &FakeOrgService{}
}
func (f *FakeOrgService) GetIDForNewUser(ctx context.Context, cmd org.GetOrgIDForNewUserCommand) (int64, error) {
return f.ExpectedOrgUserID, f.ExpectedError
}
func (f *FakeOrgService) Insert(ctx context.Context, cmd *org.OrgUser) (int64, error) {
return f.ExpectedOrgUserID, f.ExpectedError
}
func (f *FakeOrgService) InsertUser(ctx context.Context, cmd *org.OrgUser) (int64, error) {
return f.ExpectedOrgUserID, f.ExpectedError
}

View File

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/web"
"github.com/stretchr/testify/require"
@ -51,7 +52,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
service.Cfg.QueryHistoryEnabled = true
user := models.SignedInUser{
usr := models.SignedInUser{
UserId: testUserID,
Name: "Signed In User",
Login: "signed_in_user",
@ -61,7 +62,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
LastSeenAt: time.Now(),
}
_, err := sqlStore.CreateUser(context.Background(), models.CreateUserCommand{
_, err := sqlStore.CreateUser(context.Background(), user.CreateUserCommand{
Email: "signed.in.user@test.com",
Name: "Signed In User",
Login: "signed_in_user",
@ -74,7 +75,7 @@ func testScenario(t *testing.T, desc string, fn func(t *testing.T, sc scenarioCo
sqlStore: sqlStore,
reqContext: &models.ReqContext{
Context: &ctx,
SignedInUser: &user,
SignedInUser: &usr,
},
}
fn(t, sc)

View File

@ -185,7 +185,7 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) {
serviceAccountRequestScenario(t, http.MethodDelete, serviceAccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
createduser := tests.SetupUserServiceAccount(t, store, testcase.user)
server, _ := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock, store, saStore)
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, fmt.Sprint(createduser.Id))).Code
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, fmt.Sprint(createduser.ID))).Code
require.Equal(t, testcase.expectedCode, actual)
})
})
@ -209,7 +209,7 @@ func TestServiceAccountsAPI_DeleteServiceAccount(t *testing.T) {
serviceAccountRequestScenario(t, http.MethodDelete, serviceAccountIDPath, &testcase.user, func(httpmethod string, endpoint string, user *tests.TestUser) {
createduser := tests.SetupUserServiceAccount(t, store, testcase.user)
server, _ := setupTestServer(t, &svcmock, routing.NewRouteRegister(), testcase.acmock, store, saStore)
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, createduser.Id)).Code
actual := requestResponse(server, httpmethod, fmt.Sprintf(endpoint, createduser.ID)).Code
require.Equal(t, testcase.expectedCode, actual)
})
})
@ -314,7 +314,7 @@ func TestServiceAccountsAPI_RetrieveServiceAccount(t *testing.T) {
scopeID := tc.Id
if tc.user != nil {
createdUser := tests.SetupUserServiceAccount(t, store, *tc.user)
scopeID = int(createdUser.Id)
scopeID = int(createdUser.ID)
}
server, _ := setupTestServer(t, &svcmock, routing.NewRouteRegister(), tc.acmock, store, saStore)
@ -440,7 +440,7 @@ func TestServiceAccountsAPI_UpdateServiceAccount(t *testing.T) {
scopeID := tc.Id
if tc.user != nil {
createdUser := tests.SetupUserServiceAccount(t, store, *tc.user)
scopeID = int(createdUser.Id)
scopeID = int(createdUser.ID)
}
var rawBody io.Reader = http.NoBody

View File

@ -125,7 +125,7 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
endpoint := fmt.Sprintf(serviceaccountIDTokensPath, sa.Id)
endpoint := fmt.Sprintf(serviceaccountIDTokensPath, sa.ID)
bodyString := ""
if tc.body != nil {
b, err := json.Marshal(tc.body)
@ -146,12 +146,12 @@ func TestServiceAccountsAPI_CreateToken(t *testing.T) {
if actualCode == http.StatusOK {
assert.Equal(t, tc.body["name"], actualBody["name"])
query := models.GetApiKeyByNameQuery{KeyName: tc.body["name"].(string), OrgId: sa.OrgId}
query := models.GetApiKeyByNameQuery{KeyName: tc.body["name"].(string), OrgId: sa.OrgID}
err = store.GetApiKeyByName(context.Background(), &query)
require.NoError(t, err)
assert.Equal(t, sa.Id, *query.Result.ServiceAccountId)
assert.Equal(t, sa.OrgId, query.Result.OrgId)
assert.Equal(t, sa.ID, *query.Result.ServiceAccountId)
assert.Equal(t, sa.OrgID, query.Result.OrgId)
assert.True(t, strings.HasPrefix(actualBody["key"].(string), "glsa"))
keyInfo, err := apikeygenprefix.Decode(actualBody["key"].(string))
@ -229,9 +229,9 @@ func TestServiceAccountsAPI_DeleteToken(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
token := createTokenforSA(t, saStore, tc.keyName, sa.OrgId, sa.Id, 1)
token := createTokenforSA(t, saStore, tc.keyName, sa.OrgID, sa.ID, 1)
endpoint := fmt.Sprintf(serviceaccountIDTokensDetailPath, sa.Id, token.Id)
endpoint := fmt.Sprintf(serviceaccountIDTokensDetailPath, sa.ID, token.Id)
bodyString := ""
server, _ := setupTestServer(t, svcMock, routing.NewRouteRegister(), tc.acmock, store, saStore)
actual := requestResponse(server, http.MethodDelete, endpoint, strings.NewReader(bodyString))
@ -242,7 +242,7 @@ func TestServiceAccountsAPI_DeleteToken(t *testing.T) {
_ = json.Unmarshal(actual.Body.Bytes(), &actualBody)
require.Equal(t, tc.expectedCode, actualCode, endpoint, actualBody)
query := models.GetApiKeyByNameQuery{KeyName: tc.keyName, OrgId: sa.OrgId}
query := models.GetApiKeyByNameQuery{KeyName: tc.keyName, OrgId: sa.OrgID}
err := store.GetApiKeyByName(context.Background(), &query)
if actualCode == http.StatusOK {
require.Error(t, err)
@ -354,7 +354,7 @@ func TestServiceAccountsAPI_ListTokens(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
endpoint := fmt.Sprintf(serviceAccountIDPath+"/tokens", sa.Id)
endpoint := fmt.Sprintf(serviceAccountIDPath+"/tokens", sa.ID)
server, _ := setupTestServer(t, &svcmock, routing.NewRouteRegister(), tc.acmock, store, &saStoreMockTokens{saAPIKeys: tc.tokens})
actual := requestResponse(server, http.MethodGet, endpoint, http.NoBody)

View File

@ -14,6 +14,7 @@ import (
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
)
type ServiceAccountsStoreImpl struct {
@ -34,9 +35,9 @@ func NewServiceAccountsStore(store *sqlstore.SQLStore, kvStore kvstore.KVStore)
func (s *ServiceAccountsStoreImpl) CreateServiceAccount(ctx context.Context, orgId int64, name string) (saDTO *serviceaccounts.ServiceAccountDTO, err error) {
generatedLogin := "sa-" + strings.ToLower(name)
generatedLogin = strings.ReplaceAll(generatedLogin, " ", "-")
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Login: generatedLogin,
OrgId: orgId,
OrgID: orgId,
Name: name,
IsServiceAccount: true,
}
@ -50,10 +51,10 @@ func (s *ServiceAccountsStoreImpl) CreateServiceAccount(ctx context.Context, org
}
return &serviceaccounts.ServiceAccountDTO{
Id: newuser.Id,
Id: newuser.ID,
Name: newuser.Name,
Login: newuser.Login,
OrgId: newuser.OrgId,
OrgId: newuser.OrgID,
Tokens: 0,
}, nil
}
@ -89,7 +90,7 @@ func (s *ServiceAccountsStoreImpl) UpdateServiceAccount(ctx context.Context,
}
if saForm.Name != nil || saForm.IsDisabled != nil {
user := models.User{
user := user.User{
Updated: updateTime,
}
@ -131,7 +132,7 @@ func (s *ServiceAccountsStoreImpl) DeleteServiceAccount(ctx context.Context, org
}
func (s *ServiceAccountsStoreImpl) deleteServiceAccount(sess *sqlstore.DBSession, orgId, serviceAccountId int64) error {
user := models.User{}
user := user.User{}
has, err := sess.Where(`org_id = ? and id = ? and is_service_account = ?`,
orgId, serviceAccountId, s.sqlStore.Dialect.BooleanStr(true)).Get(&user)
if err != nil {
@ -141,7 +142,7 @@ func (s *ServiceAccountsStoreImpl) deleteServiceAccount(sess *sqlstore.DBSession
return serviceaccounts.ErrServiceAccountNotFound
}
for _, sql := range ServiceAccountDeletions() {
_, err := sess.Exec(sql, user.Id)
_, err := sess.Exec(sql, user.ID)
if err != nil {
return err
}
@ -405,10 +406,10 @@ func (s *ServiceAccountsStoreImpl) MigrateApiKey(ctx context.Context, orgId int6
func (s *ServiceAccountsStoreImpl) CreateServiceAccountFromApikey(ctx context.Context, key *models.ApiKey) error {
prefix := "sa-autogen"
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Login: fmt.Sprintf("%v-%v-%v", prefix, key.OrgId, key.Name),
Name: fmt.Sprintf("%v-%v", prefix, key.Name),
OrgId: key.OrgId,
OrgID: key.OrgId,
DefaultOrgRole: string(key.Role),
IsServiceAccount: true,
}
@ -419,8 +420,8 @@ func (s *ServiceAccountsStoreImpl) CreateServiceAccountFromApikey(ctx context.Co
return fmt.Errorf("failed to create service account: %w", errCreateSA)
}
if err := s.assignApiKeyToServiceAccount(sess, key.Id, newSA.Id); err != nil {
if err := s.sqlStore.DeleteUser(ctx, &models.DeleteUserCommand{UserId: newSA.Id}); err != nil {
if err := s.assignApiKeyToServiceAccount(sess, key.Id, newSA.ID); err != nil {
if err := s.sqlStore.DeleteUser(ctx, &models.DeleteUserCommand{UserId: newSA.ID}); err != nil {
s.log.Error("Error deleting service account", "error", err)
}
return fmt.Errorf("failed to migrate API key to service account token: %w", err)
@ -451,7 +452,7 @@ func (s *ServiceAccountsStoreImpl) RevertApiKey(ctx context.Context, keyId int64
}
err = s.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
user := models.User{}
user := user.User{}
has, err := sess.Where(`org_id = ? and id = ? and is_service_account = ?`,
key.OrgId, *key.ServiceAccountId, s.sqlStore.Dialect.BooleanStr(true)).Get(&user)
if err != nil {

View File

@ -59,7 +59,7 @@ func TestStore_DeleteServiceAccount(t *testing.T) {
t.Run(c.desc, func(t *testing.T) {
db, store := setupTestDatabase(t)
user := tests.SetupUserServiceAccount(t, db, c.user)
err := store.DeleteServiceAccount(context.Background(), user.OrgId, user.Id)
err := store.DeleteServiceAccount(context.Background(), user.OrgID, user.ID)
if c.expectedErr != nil {
require.ErrorIs(t, err, c.expectedErr)
} else {
@ -98,7 +98,7 @@ func TestStore_RetrieveServiceAccount(t *testing.T) {
t.Run(c.desc, func(t *testing.T) {
db, store := setupTestDatabase(t)
user := tests.SetupUserServiceAccount(t, db, c.user)
dto, err := store.RetrieveServiceAccount(context.Background(), user.OrgId, user.Id)
dto, err := store.RetrieveServiceAccount(context.Background(), user.OrgID, user.ID)
if c.expectedErr != nil {
require.ErrorIs(t, err, c.expectedErr)
} else {

View File

@ -18,18 +18,18 @@ func TestStore_UsageStats(t *testing.T) {
sa := tests.SetupUserServiceAccount(t, db, saToCreate)
keyName := t.Name()
key, err := apikeygen.New(sa.OrgId, keyName)
key, err := apikeygen.New(sa.OrgID, keyName)
require.NoError(t, err)
cmd := serviceaccounts.AddServiceAccountTokenCommand{
Name: keyName,
OrgId: sa.OrgId,
OrgId: sa.OrgID,
Key: key.HashedKey,
SecondsToLive: 0,
Result: &models.ApiKey{},
}
err = store.AddServiceAccountToken(context.Background(), sa.Id, &cmd)
err = store.AddServiceAccountToken(context.Background(), sa.ID, &cmd)
require.NoError(t, err)
stats, err := store.GetUsageMetrics(context.Background())

View File

@ -26,18 +26,18 @@ func TestStore_AddServiceAccountToken(t *testing.T) {
for _, tc := range testCases {
t.Run(tc.desc, func(t *testing.T) {
keyName := t.Name()
key, err := apikeygen.New(user.OrgId, keyName)
key, err := apikeygen.New(user.OrgID, keyName)
require.NoError(t, err)
cmd := serviceaccounts.AddServiceAccountTokenCommand{
Name: keyName,
OrgId: user.OrgId,
OrgId: user.OrgID,
Key: key.HashedKey,
SecondsToLive: tc.secondsToLive,
Result: &models.ApiKey{},
}
err = store.AddServiceAccountToken(context.Background(), user.Id, &cmd)
err = store.AddServiceAccountToken(context.Background(), user.ID, &cmd)
if tc.secondsToLive < 0 {
require.Error(t, err)
return
@ -48,7 +48,7 @@ func TestStore_AddServiceAccountToken(t *testing.T) {
require.Equal(t, t.Name(), newKey.Name)
// Verify against DB
keys, errT := store.ListTokens(context.Background(), user.OrgId, user.Id)
keys, errT := store.ListTokens(context.Background(), user.OrgID, user.ID)
require.NoError(t, errT)
@ -76,18 +76,18 @@ func TestStore_AddServiceAccountToken_WrongServiceAccount(t *testing.T) {
sa := tests.SetupUserServiceAccount(t, db, saToCreate)
keyName := t.Name()
key, err := apikeygen.New(sa.OrgId, keyName)
key, err := apikeygen.New(sa.OrgID, keyName)
require.NoError(t, err)
cmd := serviceaccounts.AddServiceAccountTokenCommand{
Name: keyName,
OrgId: sa.OrgId,
OrgId: sa.OrgID,
Key: key.HashedKey,
SecondsToLive: 0,
Result: &models.ApiKey{},
}
err = store.AddServiceAccountToken(context.Background(), sa.Id+1, &cmd)
err = store.AddServiceAccountToken(context.Background(), sa.ID+1, &cmd)
require.Error(t, err, "It should not be possible to add token to non-existing service account")
}
@ -97,34 +97,34 @@ func TestStore_DeleteServiceAccountToken(t *testing.T) {
sa := tests.SetupUserServiceAccount(t, db, userToCreate)
keyName := t.Name()
key, err := apikeygen.New(sa.OrgId, keyName)
key, err := apikeygen.New(sa.OrgID, keyName)
require.NoError(t, err)
cmd := serviceaccounts.AddServiceAccountTokenCommand{
Name: keyName,
OrgId: sa.OrgId,
OrgId: sa.OrgID,
Key: key.HashedKey,
SecondsToLive: 0,
Result: &models.ApiKey{},
}
err = store.AddServiceAccountToken(context.Background(), sa.Id, &cmd)
err = store.AddServiceAccountToken(context.Background(), sa.ID, &cmd)
require.NoError(t, err)
newKey := cmd.Result
// Delete key from wrong service account
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgId, sa.Id+2, newKey.Id)
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgID, sa.ID+2, newKey.Id)
require.Error(t, err)
// Delete key from wrong org
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgId+2, sa.Id, newKey.Id)
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgID+2, sa.ID, newKey.Id)
require.Error(t, err)
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgId, sa.Id, newKey.Id)
err = store.DeleteServiceAccountToken(context.Background(), sa.OrgID, sa.ID, newKey.Id)
require.NoError(t, err)
// Verify against DB
keys, errT := store.ListTokens(context.Background(), sa.OrgId, sa.Id)
keys, errT := store.ListTokens(context.Background(), sa.OrgID, sa.ID)
require.NoError(t, errT)
for _, k := range keys {

View File

@ -9,6 +9,7 @@ import (
accesscontrolmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
@ -27,13 +28,13 @@ type TestApiKey struct {
IsExpired bool
}
func SetupUserServiceAccount(t *testing.T, sqlStore *sqlstore.SQLStore, testUser TestUser) *models.User {
func SetupUserServiceAccount(t *testing.T, sqlStore *sqlstore.SQLStore, testUser TestUser) *user.User {
role := string(models.ROLE_VIEWER)
if testUser.Role != "" {
role = testUser.Role
}
u1, err := sqlStore.CreateUser(context.Background(), models.CreateUserCommand{
u1, err := sqlStore.CreateUser(context.Background(), user.CreateUserCommand{
Login: testUser.Login,
IsServiceAccount: testUser.IsServiceAccount,
DefaultOrgRole: role,

View File

@ -15,7 +15,9 @@ import (
acmig "github.com/grafana/grafana/pkg/services/sqlstore/migrations/accesscontrol"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -38,49 +40,49 @@ func (rp *rawPermission) toPermission(roleID int64, ts time.Time) accesscontrol.
var (
now = time.Now()
users = []models.User{
users = []user.User{
{
Id: 1,
ID: 1,
Email: "viewer1@example.org",
Name: "viewer1",
Login: "viewer1",
OrgId: 1,
OrgID: 1,
Created: now,
Updated: now,
},
{
Id: 2,
ID: 2,
Email: "viewer2@example.org",
Name: "viewer2",
Login: "viewer2",
OrgId: 1,
OrgID: 1,
Created: now,
Updated: now,
},
{
Id: 3,
ID: 3,
Email: "editor1@example.org",
Name: "editor1",
Login: "editor1",
OrgId: 1,
OrgID: 1,
Created: now,
Updated: now,
},
{
Id: 4,
ID: 4,
Email: "admin1@example.org",
Name: "admin1",
Login: "admin1",
OrgId: 1,
OrgID: 1,
Created: now,
Updated: now,
},
{
Id: 5,
ID: 5,
Email: "editor2@example.org",
Name: "editor2",
Login: "editor2",
OrgId: 2,
OrgID: 2,
Created: now,
Updated: now,
},
@ -213,9 +215,9 @@ func TestMigrations(t *testing.T) {
for _, user := range users {
// Check managed roles exist
roleName := fmt.Sprintf("managed:users:%d:permissions", user.Id)
roleName := fmt.Sprintf("managed:users:%d:permissions", user.ID)
role := accesscontrol.Role{}
hasRole, errManagedRoleSearch := x.Table("role").Where("org_id = ? AND name = ?", user.OrgId, roleName).Get(&role)
hasRole, errManagedRoleSearch := x.Table("role").Where("org_id = ? AND name = ?", user.OrgID, roleName).Get(&role)
require.NoError(t, errManagedRoleSearch)
assert.True(t, hasRole, "expected role to be granted to user", user, roleName)
@ -234,7 +236,7 @@ func TestMigrations(t *testing.T) {
// Check assignment of the roles
assign := accesscontrol.UserRole{}
has, errAssignmentSearch := x.Table("user_role").Where("role_id = ? AND user_id = ?", role.ID, user.Id).Get(&assign)
has, errAssignmentSearch := x.Table("user_role").Where("role_id = ? AND user_id = ?", role.ID, user.ID).Get(&assign)
require.NoError(t, errAssignmentSearch)
assert.True(t, has, "expected assignment of role to user", role, user)
}

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/user"
)
type OrgListResponse []struct {
@ -18,7 +19,7 @@ type SQLStoreMock struct {
LastLoginAttemptCommand *models.CreateLoginAttemptCommand
LatestUserId int64
ExpectedUser *models.User
ExpectedUser *user.User
ExpectedDatasource *datasources.DataSource
ExpectedAlert *models.Alert
ExpectedPluginSetting *models.PluginSetting
@ -132,7 +133,7 @@ func (m *SQLStoreMock) DeleteOldLoginAttempts(ctx context.Context, cmd *models.D
return m.ExpectedError
}
func (m *SQLStoreMock) CreateUser(ctx context.Context, cmd models.CreateUserCommand) (*models.User, error) {
func (m *SQLStoreMock) CreateUser(ctx context.Context, cmd user.CreateUserCommand) (*user.User, error) {
return nil, m.ExpectedError
}

View File

@ -12,6 +12,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
dashver "github.com/grafana/grafana/pkg/services/dashboardversion"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
)
@ -86,16 +87,16 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
sqlStore.Cfg.AutoAssignOrgRole = "Viewer"
t.Run("Users should be added to default organization", func(t *testing.T) {
ac1cmd := models.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := models.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
ac1cmd := user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := user.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
ac1, err := sqlStore.CreateUser(context.Background(), ac1cmd)
require.NoError(t, err)
ac2, err := sqlStore.CreateUser(context.Background(), ac2cmd)
require.NoError(t, err)
q1 := models.GetUserOrgListQuery{UserId: ac1.Id}
q2 := models.GetUserOrgListQuery{UserId: ac2.Id}
q1 := models.GetUserOrgListQuery{UserId: ac1.ID}
q2 := models.GetUserOrgListQuery{UserId: ac2.ID}
err = sqlStore.GetUserOrgList(context.Background(), &q1)
require.NoError(t, err)
err = sqlStore.GetUserOrgList(context.Background(), &q2)
@ -112,18 +113,18 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
sqlStore.Cfg.AutoAssignOrgId = 1
sqlStore.Cfg.AutoAssignOrgRole = "Viewer"
ac1cmd := models.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := models.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
ac1cmd := user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := user.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name"}
ac1, err := sqlStore.CreateUser(context.Background(), ac1cmd)
testUser.OrgId = ac1.OrgId
testUser.OrgId = ac1.OrgID
require.NoError(t, err)
_, err = sqlStore.CreateUser(context.Background(), ac2cmd)
require.NoError(t, err)
t.Run("Can get organization users paginated with query", func(t *testing.T) {
query := models.SearchOrgUsersQuery{
OrgID: ac1.OrgId,
OrgID: ac1.OrgID,
Page: 1,
User: testUser,
}
@ -135,7 +136,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
t.Run("Can get organization users paginated and limited", func(t *testing.T) {
query := models.SearchOrgUsersQuery{
OrgID: ac1.OrgId,
OrgID: ac1.OrgID,
Limit: 1,
Page: 1,
User: testUser,
@ -151,9 +152,9 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
sqlStore = InitTestDB(t)
sqlStore.Cfg.AutoAssignOrg = false
ac1cmd := models.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := models.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name", IsAdmin: true}
serviceaccountcmd := models.CreateUserCommand{Login: "serviceaccount", Email: "service@test.com", Name: "serviceaccount name", IsAdmin: true, IsServiceAccount: true}
ac1cmd := user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
ac2cmd := user.CreateUserCommand{Login: "ac2", Email: "ac2@test.com", Name: "ac2 name", IsAdmin: true}
serviceaccountcmd := user.CreateUserCommand{Login: "serviceaccount", Email: "service@test.com", Name: "serviceaccount name", IsAdmin: true, IsServiceAccount: true}
ac1, err := sqlStore.CreateUser(context.Background(), ac1cmd)
require.NoError(t, err)
@ -164,7 +165,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
require.NoError(t, err)
t.Run("Should be able to read user info projection", func(t *testing.T) {
query := models.GetUserProfileQuery{UserId: ac1.Id}
query := models.GetUserProfileQuery{UserId: ac1.ID}
err = sqlStore.GetUserProfile(context.Background(), &query)
require.NoError(t, err)
@ -189,8 +190,8 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
t.Run("Given an added org user", func(t *testing.T) {
cmd := models.AddOrgUserCommand{
OrgId: ac1.OrgId,
UserId: ac2.Id,
OrgId: ac1.OrgID,
UserId: ac2.ID,
Role: models.ROLE_VIEWER,
}
@ -200,15 +201,15 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Can update org user role", func(t *testing.T) {
updateCmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgId, UserId: ac2.Id, Role: models.ROLE_ADMIN}
updateCmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID, Role: models.ROLE_ADMIN}
err = sqlStore.UpdateOrgUser(context.Background(), &updateCmd)
require.NoError(t, err)
orgUsersQuery := models.GetOrgUsersQuery{
OrgId: ac1.OrgId,
OrgId: ac1.OrgID,
User: &models.SignedInUser{
OrgId: ac1.OrgId,
Permissions: map[int64]map[string][]string{ac1.OrgId: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
OrgId: ac1.OrgID,
Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
}
err = sqlStore.GetOrgUsers(context.Background(), &orgUsersQuery)
@ -218,12 +219,12 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Can get logged in user projection", func(t *testing.T) {
query := models.GetSignedInUserQuery{UserId: ac2.Id}
query := models.GetSignedInUserQuery{UserId: ac2.ID}
err := sqlStore.GetSignedInUser(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.Email, "ac2@test.com")
require.Equal(t, query.Result.OrgId, ac2.OrgId)
require.Equal(t, query.Result.OrgId, ac2.OrgID)
require.Equal(t, query.Result.Name, "ac2 name")
require.Equal(t, query.Result.Login, "ac2")
require.EqualValues(t, query.Result.OrgRole, "Admin")
@ -232,7 +233,7 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Can get user organizations", func(t *testing.T) {
query := models.GetUserOrgListQuery{UserId: ac2.Id}
query := models.GetUserOrgListQuery{UserId: ac2.ID}
err := sqlStore.GetUserOrgList(context.Background(), &query)
require.NoError(t, err)
@ -241,10 +242,10 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
t.Run("Can get organization users", func(t *testing.T) {
query := models.GetOrgUsersQuery{
OrgId: ac1.OrgId,
OrgId: ac1.OrgID,
User: &models.SignedInUser{
OrgId: ac1.OrgId,
Permissions: map[int64]map[string][]string{ac1.OrgId: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
OrgId: ac1.OrgID,
Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
}
err := sqlStore.GetOrgUsers(context.Background(), &query)
@ -256,11 +257,11 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
t.Run("Can get organization users with query", func(t *testing.T) {
query := models.GetOrgUsersQuery{
OrgId: ac1.OrgId,
OrgId: ac1.OrgID,
Query: "ac1",
User: &models.SignedInUser{
OrgId: ac1.OrgId,
Permissions: map[int64]map[string][]string{ac1.OrgId: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
OrgId: ac1.OrgID,
Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
}
err := sqlStore.GetOrgUsers(context.Background(), &query)
@ -272,12 +273,12 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
t.Run("Can get organization users with query and limit", func(t *testing.T) {
query := models.GetOrgUsersQuery{
OrgId: ac1.OrgId,
OrgId: ac1.OrgID,
Query: "ac",
Limit: 1,
User: &models.SignedInUser{
OrgId: ac1.OrgId,
Permissions: map[int64]map[string][]string{ac1.OrgId: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
OrgId: ac1.OrgID,
Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
}
err := sqlStore.GetOrgUsers(context.Background(), &query)
@ -288,16 +289,16 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Can set using org", func(t *testing.T) {
cmd := models.SetUsingOrgCommand{UserId: ac2.Id, OrgId: ac1.OrgId}
cmd := models.SetUsingOrgCommand{UserId: ac2.ID, OrgId: ac1.OrgID}
err := sqlStore.SetUsingOrg(context.Background(), &cmd)
require.NoError(t, err)
t.Run("SignedInUserQuery with a different org", func(t *testing.T) {
query := models.GetSignedInUserQuery{UserId: ac2.Id}
query := models.GetSignedInUserQuery{UserId: ac2.ID}
err := sqlStore.GetSignedInUser(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.OrgId, ac1.OrgId)
require.Equal(t, query.Result.OrgId, ac1.OrgID)
require.Equal(t, query.Result.Email, "ac2@test.com")
require.Equal(t, query.Result.Name, "ac2 name")
require.Equal(t, query.Result.Login, "ac2")
@ -305,53 +306,53 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Should set last org as current when removing user from current", func(t *testing.T) {
remCmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac2.Id}
remCmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID}
err := sqlStore.RemoveOrgUser(context.Background(), &remCmd)
require.NoError(t, err)
query := models.GetSignedInUserQuery{UserId: ac2.Id}
query := models.GetSignedInUserQuery{UserId: ac2.ID}
err = sqlStore.GetSignedInUser(context.Background(), &query)
require.NoError(t, err)
require.Equal(t, query.Result.OrgId, ac2.OrgId)
require.Equal(t, query.Result.OrgId, ac2.OrgID)
})
})
t.Run("Removing user from org should delete user completely if in no other org", func(t *testing.T) {
// make sure ac2 has no org
err := sqlStore.DeleteOrg(context.Background(), &models.DeleteOrgCommand{Id: ac2.OrgId})
err := sqlStore.DeleteOrg(context.Background(), &models.DeleteOrgCommand{Id: ac2.OrgID})
require.NoError(t, err)
// remove ac2 user from ac1 org
remCmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac2.Id, ShouldDeleteOrphanedUser: true}
remCmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgID, UserId: ac2.ID, ShouldDeleteOrphanedUser: true}
err = sqlStore.RemoveOrgUser(context.Background(), &remCmd)
require.NoError(t, err)
require.True(t, remCmd.UserWasDeleted)
err = sqlStore.GetSignedInUser(context.Background(), &models.GetSignedInUserQuery{UserId: ac2.Id})
err = sqlStore.GetSignedInUser(context.Background(), &models.GetSignedInUserQuery{UserId: ac2.ID})
require.Equal(t, err, models.ErrUserNotFound)
})
t.Run("Cannot delete last admin org user", func(t *testing.T) {
cmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac1.Id}
cmd := models.RemoveOrgUserCommand{OrgId: ac1.OrgID, UserId: ac1.ID}
err := sqlStore.RemoveOrgUser(context.Background(), &cmd)
require.Equal(t, err, models.ErrLastOrgAdmin)
})
t.Run("Cannot update role so no one is admin user", func(t *testing.T) {
cmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgId, UserId: ac1.Id, Role: models.ROLE_VIEWER}
cmd := models.UpdateOrgUserCommand{OrgId: ac1.OrgID, UserId: ac1.ID, Role: models.ROLE_VIEWER}
err := sqlStore.UpdateOrgUser(context.Background(), &cmd)
require.Equal(t, err, models.ErrLastOrgAdmin)
})
t.Run("Given an org user with dashboard permissions", func(t *testing.T) {
ac3cmd := models.CreateUserCommand{Login: "ac3", Email: "ac3@test.com", Name: "ac3 name", IsAdmin: false}
ac3cmd := user.CreateUserCommand{Login: "ac3", Email: "ac3@test.com", Name: "ac3 name", IsAdmin: false}
ac3, err := sqlStore.CreateUser(context.Background(), ac3cmd)
require.NoError(t, err)
orgUserCmd := models.AddOrgUserCommand{
OrgId: ac1.OrgId,
UserId: ac3.Id,
OrgId: ac1.OrgID,
UserId: ac3.ID,
Role: models.ROLE_VIEWER,
}
@ -359,36 +360,36 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
require.NoError(t, err)
query := models.GetOrgUsersQuery{
OrgId: ac1.OrgId,
OrgId: ac1.OrgID,
User: &models.SignedInUser{
OrgId: ac1.OrgId,
Permissions: map[int64]map[string][]string{ac1.OrgId: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
OrgId: ac1.OrgID,
Permissions: map[int64]map[string][]string{ac1.OrgID: {accesscontrol.ActionOrgUsersRead: {accesscontrol.ScopeUsersAll}}},
},
}
err = sqlStore.GetOrgUsers(context.Background(), &query)
require.NoError(t, err)
// require.Equal(t, len(query.Result), 3)
dash1 := insertTestDashboard(t, sqlStore, "1 test dash", ac1.OrgId, 0, false, "prod", "webapp")
dash2 := insertTestDashboard(t, sqlStore, "2 test dash", ac3.OrgId, 0, false, "prod", "webapp")
dash1 := insertTestDashboard(t, sqlStore, "1 test dash", ac1.OrgID, 0, false, "prod", "webapp")
dash2 := insertTestDashboard(t, sqlStore, "2 test dash", ac3.OrgID, 0, false, "prod", "webapp")
err = updateDashboardAcl(t, sqlStore, dash1.Id, &models.DashboardAcl{
DashboardID: dash1.Id, OrgID: ac1.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT,
DashboardID: dash1.Id, OrgID: ac1.OrgID, UserID: ac3.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
err = updateDashboardAcl(t, sqlStore, dash2.Id, &models.DashboardAcl{
DashboardID: dash2.Id, OrgID: ac3.OrgId, UserID: ac3.Id, Permission: models.PERMISSION_EDIT,
DashboardID: dash2.Id, OrgID: ac3.OrgID, UserID: ac3.ID, Permission: models.PERMISSION_EDIT,
})
require.NoError(t, err)
t.Run("When org user is deleted", func(t *testing.T) {
cmdRemove := models.RemoveOrgUserCommand{OrgId: ac1.OrgId, UserId: ac3.Id}
cmdRemove := models.RemoveOrgUserCommand{OrgId: ac1.OrgID, UserId: ac3.ID}
err := sqlStore.RemoveOrgUser(context.Background(), &cmdRemove)
require.NoError(t, err)
t.Run("Should remove dependent permissions for deleted org user", func(t *testing.T) {
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash1.Id, OrgID: ac1.OrgId}
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash1.Id, OrgID: ac1.OrgID}
err = getDashboardAclInfoList(sqlStore, permQuery)
require.NoError(t, err)
@ -397,14 +398,14 @@ func TestIntegrationAccountDataAccess(t *testing.T) {
})
t.Run("Should not remove dashboard permissions for same user in another org", func(t *testing.T) {
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash2.Id, OrgID: ac3.OrgId}
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: dash2.Id, OrgID: ac3.OrgID}
err = getDashboardAclInfoList(sqlStore, permQuery)
require.NoError(t, err)
require.Equal(t, len(permQuery.Result), 1)
require.Equal(t, permQuery.Result[0].OrgId, ac3.OrgId)
require.Equal(t, permQuery.Result[0].UserId, ac3.Id)
require.Equal(t, permQuery.Result[0].OrgId, ac3.OrgID)
require.Equal(t, permQuery.Result[0].UserId, ac3.ID)
})
})
})

View File

@ -8,20 +8,21 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
)
func (ss *SQLStore) AddOrgUser(ctx context.Context, cmd *models.AddOrgUserCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
// check if user exists
var user models.User
var user user.User
if exists, err := sess.ID(cmd.UserId).Where(notServiceAccountFilter(ss)).Get(&user); err != nil {
return err
} else if !exists {
return models.ErrUserNotFound
}
if res, err := sess.Query("SELECT 1 from org_user WHERE org_id=? and user_id=?", cmd.OrgId, user.Id); err != nil {
if res, err := sess.Query("SELECT 1 from org_user WHERE org_id=? and user_id=?", cmd.OrgId, user.ID); err != nil {
return err
} else if len(res) == 1 {
return models.ErrOrgUserAlreadyAdded
@ -49,7 +50,7 @@ func (ss *SQLStore) AddOrgUser(ctx context.Context, cmd *models.AddOrgUserComman
var userOrgs []*models.UserOrgDTO
sess.Table("org_user")
sess.Join("INNER", "org", "org_user.org_id=org.id")
sess.Where("org_user.user_id=? AND org_user.org_id=?", user.Id, user.OrgId)
sess.Where("org_user.user_id=? AND org_user.org_id=?", user.ID, user.OrgID)
sess.Cols("org.name", "org_user.role", "org_user.org_id")
err = sess.Find(&userOrgs)
@ -58,7 +59,7 @@ func (ss *SQLStore) AddOrgUser(ctx context.Context, cmd *models.AddOrgUserComman
}
if len(userOrgs) == 0 {
return setUsingOrgInTransaction(sess, user.Id, cmd.OrgId)
return setUsingOrgInTransaction(sess, user.ID, cmd.OrgId)
}
return nil
@ -243,7 +244,7 @@ func (ss *SQLStore) SearchOrgUsers(ctx context.Context, query *models.SearchOrgU
func (ss *SQLStore) RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUserCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
// check if user exists
var user models.User
var user user.User
if exists, err := sess.ID(cmd.UserId).Where(notServiceAccountFilter(ss)).Get(&user); err != nil {
return err
} else if !exists {
@ -273,7 +274,7 @@ func (ss *SQLStore) RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUser
var userOrgs []*models.UserOrgDTO
sess.Table("org_user")
sess.Join("INNER", "org", "org_user.org_id=org.id")
sess.Where("org_user.user_id=?", user.Id)
sess.Where("org_user.user_id=?", user.ID)
sess.Cols("org.name", "org_user.role", "org_user.org_id")
err := sess.Find(&userOrgs)
@ -284,28 +285,28 @@ func (ss *SQLStore) RemoveOrgUser(ctx context.Context, cmd *models.RemoveOrgUser
if len(userOrgs) > 0 {
hasCurrentOrgSet := false
for _, userOrg := range userOrgs {
if user.OrgId == userOrg.OrgId {
if user.OrgID == userOrg.OrgId {
hasCurrentOrgSet = true
break
}
}
if !hasCurrentOrgSet {
err = setUsingOrgInTransaction(sess, user.Id, userOrgs[0].OrgId)
err = setUsingOrgInTransaction(sess, user.ID, userOrgs[0].OrgId)
if err != nil {
return err
}
}
} else if cmd.ShouldDeleteOrphanedUser {
// no other orgs, delete the full user
if err := deleteUserInTransaction(ss, sess, &models.DeleteUserCommand{UserId: user.Id}); err != nil {
if err := deleteUserInTransaction(ss, sess, &models.DeleteUserCommand{UserId: user.ID}); err != nil {
return err
}
cmd.UserWasDeleted = true
} else {
// no orgs, but keep the user -> clean up orgId
err = removeUserOrg(sess, user.Id)
err = removeUserOrg(sess, user.ID)
if err != nil {
return err
}

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
)
type getOrgUsersTestCase struct {
@ -151,16 +152,16 @@ func TestSQLStore_RemoveOrgUser(t *testing.T) {
store := InitTestDB(t)
// create org and admin
_, err := store.CreateUser(context.Background(), models.CreateUserCommand{
_, err := store.CreateUser(context.Background(), user.CreateUserCommand{
Login: "admin",
OrgId: 1,
OrgID: 1,
})
require.NoError(t, err)
// create a user with no org
_, err = store.CreateUser(context.Background(), models.CreateUserCommand{
_, err = store.CreateUser(context.Background(), user.CreateUserCommand{
Login: "user",
OrgId: 1,
OrgID: 1,
SkipOrgSetup: true,
})
require.NoError(t, err)
@ -177,7 +178,7 @@ func TestSQLStore_RemoveOrgUser(t *testing.T) {
user := &models.GetUserByIdQuery{Id: 2}
err = store.GetUserById(context.Background(), user)
require.NoError(t, err)
require.Equal(t, user.Result.OrgId, int64(1))
require.Equal(t, user.Result.OrgID, int64(1))
// remove the user org
err = store.RemoveOrgUser(context.Background(), &models.RemoveOrgUserCommand{
@ -191,16 +192,16 @@ func TestSQLStore_RemoveOrgUser(t *testing.T) {
user = &models.GetUserByIdQuery{Id: 2}
err = store.GetUserById(context.Background(), user)
require.NoError(t, err)
require.Equal(t, user.Result.OrgId, int64(0))
require.Equal(t, user.Result.OrgID, int64(0))
}
func seedOrgUsers(t *testing.T, store *SQLStore, numUsers int) {
t.Helper()
// Seed users
for i := 1; i <= numUsers; i++ {
user, err := store.CreateUser(context.Background(), models.CreateUserCommand{
user, err := store.CreateUser(context.Background(), user.CreateUserCommand{
Login: fmt.Sprintf("user-%d", i),
OrgId: 1,
OrgID: 1,
})
require.NoError(t, err)
@ -208,7 +209,7 @@ func seedOrgUsers(t *testing.T, store *SQLStore, numUsers int) {
err = store.AddOrgUser(context.Background(), &models.AddOrgUserCommand{
Role: "Viewer",
OrgId: 1,
UserId: user.Id,
UserId: user.ID,
})
require.NoError(t, err)
}

View File

@ -23,6 +23,10 @@ func (sess *DBSession) publishAfterCommit(msg interface{}) {
sess.events = append(sess.events, msg)
}
func (sess *DBSession) PublishAfterCommit(msg interface{}) {
sess.events = append(sess.events, msg)
}
// NewSession returns a new DBSession
func (ss *SQLStore) NewSession(ctx context.Context) *DBSession {
sess := &DBSession{Session: ss.engine.NewSession()}

View File

@ -9,6 +9,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -190,11 +191,11 @@ func test(t *testing.T, dashboardProps DashboardProps, dashboardPermission *Dash
})
}
func createDummyUser(t *testing.T, sqlStore *SQLStore) *models.User {
func createDummyUser(t *testing.T, sqlStore *SQLStore) *user.User {
t.Helper()
uid := strconv.Itoa(rand.Intn(9999999))
createUserCmd := models.CreateUserCommand{
createUserCmd := user.CreateUserCommand{
Email: uid + "@example.com",
Login: uid,
Name: uid,
@ -262,12 +263,12 @@ func createDummyACL(t *testing.T, sqlStore *SQLStore, dashboardPermission *Dashb
DashboardID: dashboardID,
}
var user *models.User
var user *user.User
if dashboardPermission.User {
t.Logf("Creating user")
user = createDummyUser(t, sqlStore)
acl.UserID = user.Id
acl.UserID = user.ID
}
if dashboardPermission.Team {
@ -275,9 +276,9 @@ func createDummyACL(t *testing.T, sqlStore *SQLStore, dashboardPermission *Dashb
team := createDummyTeam(t, sqlStore)
if search.UserFromACL {
user = createDummyUser(t, sqlStore)
err := sqlStore.AddTeamMember(user.Id, 1, team.Id, false, 0)
err := sqlStore.AddTeamMember(user.ID, 1, team.Id, false, 0)
require.NoError(t, err)
t.Logf("Created team member with ID %d", user.Id)
t.Logf("Created team member with ID %d", user.ID)
}
acl.TeamID = team.Id
@ -290,7 +291,7 @@ func createDummyACL(t *testing.T, sqlStore *SQLStore, dashboardPermission *Dashb
err := updateDashboardAcl(t, sqlStore, dashboardID, acl)
require.NoError(t, err)
if user != nil {
return user.Id
return user.ID
}
return 0
}

View File

@ -27,6 +27,7 @@ import (
"github.com/grafana/grafana/pkg/services/sqlstore/migrations"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/sqlstore/sqlutil"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
@ -180,7 +181,7 @@ func (ss *SQLStore) ensureMainOrgAndAdminUser() error {
// ensure admin user
if !ss.Cfg.DisableInitAdminCreation {
ss.log.Debug("Creating default admin user")
if _, err := ss.createUser(ctx, sess, models.CreateUserCommand{
if _, err := ss.createUser(ctx, sess, user.CreateUserCommand{
Login: ss.Cfg.AdminUser,
Email: ss.Cfg.AdminUser + "@localhost",
Password: ss.Cfg.AdminPassword,

View File

@ -6,6 +6,7 @@ import (
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -64,9 +65,9 @@ func TestIntegrationStatsDataAccess(t *testing.T) {
func populateDB(t *testing.T, sqlStore *SQLStore) {
t.Helper()
users := make([]models.User, 3)
users := make([]user.User, 3)
for i := range users {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: fmt.Sprintf("usertest%v@test.com", i),
Name: fmt.Sprintf("user name %v", i),
Login: fmt.Sprintf("user_test_%v_login", i),
@ -78,7 +79,7 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
}
// get 1st user's organisation
getOrgByIdQuery := &models.GetOrgByIdQuery{Id: users[0].OrgId}
getOrgByIdQuery := &models.GetOrgByIdQuery{Id: users[0].OrgID}
err := sqlStore.GetOrgById(context.Background(), getOrgByIdQuery)
require.NoError(t, err)
org := getOrgByIdQuery.Result
@ -86,7 +87,7 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
// add 2nd user as editor
cmd := &models.AddOrgUserCommand{
OrgId: org.Id,
UserId: users[1].Id,
UserId: users[1].ID,
Role: models.ROLE_EDITOR,
}
err = sqlStore.AddOrgUser(context.Background(), cmd)
@ -95,14 +96,14 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
// add 3rd user as viewer
cmd = &models.AddOrgUserCommand{
OrgId: org.Id,
UserId: users[2].Id,
UserId: users[2].ID,
Role: models.ROLE_VIEWER,
}
err = sqlStore.AddOrgUser(context.Background(), cmd)
require.NoError(t, err)
// get 2nd user's organisation
getOrgByIdQuery = &models.GetOrgByIdQuery{Id: users[1].OrgId}
getOrgByIdQuery = &models.GetOrgByIdQuery{Id: users[1].OrgID}
err = sqlStore.GetOrgById(context.Background(), getOrgByIdQuery)
require.NoError(t, err)
org = getOrgByIdQuery.Result
@ -110,7 +111,7 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
// add 1st user as admin
cmd = &models.AddOrgUserCommand{
OrgId: org.Id,
UserId: users[0].Id,
UserId: users[0].ID,
Role: models.ROLE_ADMIN,
}
err = sqlStore.AddOrgUser(context.Background(), cmd)
@ -118,7 +119,7 @@ func populateDB(t *testing.T, sqlStore *SQLStore) {
// update 1st user last seen at
updateUserLastSeenAtCmd := &models.UpdateUserLastSeenAtCommand{
UserId: users[0].Id,
UserId: users[0].ID,
}
err = sqlStore.UpdateUserLastSeenAt(context.Background(), updateUserLastSeenAtCmd)
require.NoError(t, err)

View File

@ -6,6 +6,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/datasources"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/user"
)
type Store interface {
@ -26,7 +27,7 @@ type Store interface {
CreateLoginAttempt(ctx context.Context, cmd *models.CreateLoginAttemptCommand) error
GetUserLoginAttemptCount(ctx context.Context, query *models.GetUserLoginAttemptCountQuery) error
DeleteOldLoginAttempts(ctx context.Context, cmd *models.DeleteOldLoginAttemptsCommand) error
CreateUser(ctx context.Context, cmd models.CreateUserCommand) (*models.User, error)
CreateUser(ctx context.Context, cmd user.CreateUserCommand) (*user.User, error)
GetUserById(ctx context.Context, query *models.GetUserByIdQuery) error
GetUserByLogin(ctx context.Context, query *models.GetUserByLoginQuery) error
GetUserByEmail(ctx context.Context, query *models.GetUserByEmailQuery) error

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/serviceaccounts"
"github.com/grafana/grafana/pkg/services/user"
)
func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
@ -34,20 +35,20 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
var userIds []int64
const testOrgID int64 = 1
var team1, team2 models.Team
var user *models.User
var userCmd models.CreateUserCommand
var usr *user.User
var userCmd user.CreateUserCommand
var err error
setup := func() {
for i := 0; i < 5; i++ {
userCmd = models.CreateUserCommand{
userCmd = user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
}
user, err = sqlStore.CreateUser(context.Background(), userCmd)
usr, err = sqlStore.CreateUser(context.Background(), userCmd)
require.NoError(t, err)
userIds = append(userIds, user.Id)
userIds = append(userIds, usr.ID)
}
team1, err = sqlStore.CreateTeam("group1 name", "test1@test.com", testOrgID)
require.NoError(t, err)
@ -375,7 +376,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
t.Run("Should be able to exclude service accounts from teamembers", func(t *testing.T) {
sqlStore = InitTestDB(t)
setup()
userCmd = models.CreateUserCommand{
userCmd = user.CreateUserCommand{
Email: fmt.Sprint("sa", 1, "@test.com"),
Name: fmt.Sprint("sa", 1),
Login: fmt.Sprint("login-sa", 1),
@ -386,7 +387,7 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
groupId := team2.Id
// add service account to team
err = sqlStore.AddTeamMember(serviceAccount.Id, testOrgID, groupId, false, 0)
err = sqlStore.AddTeamMember(serviceAccount.ID, testOrgID, groupId, false, 0)
require.NoError(t, err)
// add user to team
@ -498,14 +499,14 @@ func TestIntegrationSQLStore_GetTeamMembers_ACFilter(t *testing.T) {
require.NoError(t, errCreateTeam)
for i := 0; i < 4; i++ {
userCmd := models.CreateUserCommand{
userCmd := user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@example.org"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
}
user, errCreateUser := store.CreateUser(context.Background(), userCmd)
require.NoError(t, errCreateUser)
userIds[i] = user.Id
userIds[i] = user.ID
}
errAddMember := store.AddTeamMember(userIds[0], testOrgID, team1.Id, false, 0)

View File

@ -11,11 +11,12 @@ import (
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/models"
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/util"
)
type ErrCaseInsensitiveLoginConflict struct {
users []models.User
users []user.User
}
func (e *ErrCaseInsensitiveLoginConflict) Unwrap() error {
@ -27,7 +28,7 @@ func (e *ErrCaseInsensitiveLoginConflict) Error() string {
userStrings := make([]string, 0, n)
for _, v := range e.users {
userStrings = append(userStrings, fmt.Sprintf("%s (email:%s, id:%d)", v.Login, v.Email, v.Id))
userStrings = append(userStrings, fmt.Sprintf("%s (email:%s, id:%d)", v.Login, v.Email, v.ID))
}
return fmt.Sprintf(
@ -35,12 +36,12 @@ func (e *ErrCaseInsensitiveLoginConflict) Error() string {
n, strings.Join(userStrings, ", "))
}
func (ss *SQLStore) getOrgIDForNewUser(sess *DBSession, args models.CreateUserCommand) (int64, error) {
if ss.Cfg.AutoAssignOrg && args.OrgId != 0 {
if err := verifyExistingOrg(sess, args.OrgId); err != nil {
func (ss *SQLStore) getOrgIDForNewUser(sess *DBSession, args user.CreateUserCommand) (int64, error) {
if ss.Cfg.AutoAssignOrg && args.OrgID != 0 {
if err := verifyExistingOrg(sess, args.OrgID); err != nil {
return -1, err
}
return args.OrgId, nil
return args.OrgID, nil
}
orgName := args.OrgName
@ -52,7 +53,7 @@ func (ss *SQLStore) getOrgIDForNewUser(sess *DBSession, args models.CreateUserCo
}
func (ss *SQLStore) userCaseInsensitiveLoginConflict(ctx context.Context, sess *DBSession, login, email string) error {
users := make([]models.User, 0)
users := make([]user.User, 0)
if err := sess.Where("LOWER(email)=LOWER(?) OR LOWER(login)=LOWER(?)",
email, login).Find(&users); err != nil {
@ -67,14 +68,14 @@ func (ss *SQLStore) userCaseInsensitiveLoginConflict(ctx context.Context, sess *
}
// createUser creates a user in the database
func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args models.CreateUserCommand) (models.User, error) {
var user models.User
func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args user.CreateUserCommand) (user.User, error) {
var usr user.User
var orgID int64 = -1
if !args.SkipOrgSetup {
var err error
orgID, err = ss.getOrgIDForNewUser(sess, args)
if err != nil {
return user, err
return usr, err
}
}
@ -89,23 +90,23 @@ func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args models
args.Email = strings.ToLower(args.Email)
}
exists, err := sess.Where(where, args.Email, args.Login).Get(&models.User{})
exists, err := sess.Where(where, args.Email, args.Login).Get(&user.User{})
if err != nil {
return user, err
return usr, err
}
if exists {
return user, models.ErrUserAlreadyExists
return usr, models.ErrUserAlreadyExists
}
// create user
user = models.User{
usr = user.User{
Email: args.Email,
Name: args.Name,
Login: args.Login,
Company: args.Company,
IsAdmin: args.IsAdmin,
IsDisabled: args.IsDisabled,
OrgId: orgID,
OrgID: orgID,
EmailVerified: args.EmailVerified,
Created: time.Now(),
Updated: time.Now(),
@ -115,48 +116,48 @@ func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args models
salt, err := util.GetRandomString(10)
if err != nil {
return user, err
return usr, err
}
user.Salt = salt
usr.Salt = salt
rands, err := util.GetRandomString(10)
if err != nil {
return user, err
return usr, err
}
user.Rands = rands
usr.Rands = rands
if len(args.Password) > 0 {
encodedPassword, err := util.EncodePassword(args.Password, user.Salt)
encodedPassword, err := util.EncodePassword(args.Password, usr.Salt)
if err != nil {
return user, err
return usr, err
}
user.Password = encodedPassword
usr.Password = encodedPassword
}
sess.UseBool("is_admin")
if _, err := sess.Insert(&user); err != nil {
return user, err
if _, err := sess.Insert(&usr); err != nil {
return usr, err
}
sess.publishAfterCommit(&events.UserCreated{
Timestamp: user.Created,
Id: user.Id,
Name: user.Name,
Login: user.Login,
Email: user.Email,
Timestamp: usr.Created,
Id: usr.ID,
Name: usr.Name,
Login: usr.Login,
Email: usr.Email,
})
// create org user link
if !args.SkipOrgSetup {
orgUser := models.OrgUser{
OrgId: orgID,
UserId: user.Id,
UserId: usr.ID,
Role: models.ROLE_ADMIN,
Created: time.Now(),
Updated: time.Now(),
}
if ss.Cfg.AutoAssignOrg && !user.IsAdmin {
if ss.Cfg.AutoAssignOrg && !usr.IsAdmin {
if len(args.DefaultOrgRole) > 0 {
orgUser.Role = models.RoleType(args.DefaultOrgRole)
} else {
@ -165,15 +166,16 @@ func (ss *SQLStore) createUser(ctx context.Context, sess *DBSession, args models
}
if _, err = sess.Insert(&orgUser); err != nil {
return user, err
return usr, err
}
}
return user, nil
return usr, nil
}
func (ss *SQLStore) CreateUser(ctx context.Context, cmd models.CreateUserCommand) (*models.User, error) {
var user models.User
// deprecated method, use only for tests
func (ss *SQLStore) CreateUser(ctx context.Context, cmd user.CreateUserCommand) (*user.User, error) {
var user user.User
createErr := ss.WithTransactionalDbSession(ctx, func(sess *DBSession) (err error) {
user, err = ss.createUser(ctx, sess, cmd)
return
@ -189,7 +191,7 @@ func notServiceAccountFilter(ss *SQLStore) string {
func (ss *SQLStore) GetUserById(ctx context.Context, query *models.GetUserByIdQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
user := new(models.User)
user := new(user.User)
has, err := sess.ID(query.Id).
Where(notServiceAccountFilter(ss)).
@ -221,13 +223,13 @@ func (ss *SQLStore) GetUserByLogin(ctx context.Context, query *models.GetUserByL
// Try and find the user by login first.
// It's not sufficient to assume that a LoginOrEmail with an "@" is an email.
user := &models.User{}
usr := &user.User{}
where := "login=?"
if ss.Cfg.CaseInsensitiveLogin {
where = "LOWER(login)=LOWER(?)"
}
has, err := sess.Where(notServiceAccountFilter(ss)).Where(where, query.LoginOrEmail).Get(user)
has, err := sess.Where(notServiceAccountFilter(ss)).Where(where, query.LoginOrEmail).Get(usr)
if err != nil {
return err
}
@ -235,12 +237,13 @@ func (ss *SQLStore) GetUserByLogin(ctx context.Context, query *models.GetUserByL
if !has && strings.Contains(query.LoginOrEmail, "@") {
// If the user wasn't found, and it contains an "@" fallback to finding the
// user by email.
where = "email=?"
if ss.Cfg.CaseInsensitiveLogin {
where = "LOWER(email)=LOWER(?)"
}
user = &models.User{}
has, err = sess.Where(notServiceAccountFilter(ss)).Where(where, query.LoginOrEmail).Get(user)
usr = &user.User{}
has, err = sess.Where(notServiceAccountFilter(ss)).Where(where, query.LoginOrEmail).Get(usr)
}
if err != nil {
@ -250,12 +253,12 @@ func (ss *SQLStore) GetUserByLogin(ctx context.Context, query *models.GetUserByL
}
if ss.Cfg.CaseInsensitiveLogin {
if err := ss.userCaseInsensitiveLoginConflict(ctx, sess, user.Login, user.Email); err != nil {
if err := ss.userCaseInsensitiveLoginConflict(ctx, sess, usr.Login, usr.Email); err != nil {
return err
}
}
query.Result = user
query.Result = usr
return nil
})
@ -267,7 +270,7 @@ func (ss *SQLStore) GetUserByEmail(ctx context.Context, query *models.GetUserByE
return models.ErrUserNotFound
}
user := &models.User{}
user := &user.User{}
where := "email=?"
if ss.Cfg.CaseInsensitiveLogin {
where = "LOWER(email)=LOWER(?)"
@ -300,7 +303,7 @@ func (ss *SQLStore) UpdateUser(ctx context.Context, cmd *models.UpdateUserComman
}
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
user := user.User{
Name: cmd.Name,
Email: cmd.Email,
Login: cmd.Login,
@ -320,7 +323,7 @@ func (ss *SQLStore) UpdateUser(ctx context.Context, cmd *models.UpdateUserComman
sess.publishAfterCommit(&events.UserUpdated{
Timestamp: user.Created,
Id: user.Id,
Id: user.ID,
Name: user.Name,
Login: user.Login,
Email: user.Email,
@ -332,7 +335,7 @@ func (ss *SQLStore) UpdateUser(ctx context.Context, cmd *models.UpdateUserComman
func (ss *SQLStore) ChangeUserPassword(ctx context.Context, cmd *models.ChangeUserPasswordCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
user := user.User{
Password: cmd.NewPassword,
Updated: time.Now(),
}
@ -344,8 +347,8 @@ func (ss *SQLStore) ChangeUserPassword(ctx context.Context, cmd *models.ChangeUs
func (ss *SQLStore) UpdateUserLastSeenAt(ctx context.Context, cmd *models.UpdateUserLastSeenAtCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Id: cmd.UserId,
user := user.User{
ID: cmd.UserId,
LastSeenAt: time.Now(),
}
@ -376,9 +379,9 @@ func (ss *SQLStore) SetUsingOrg(ctx context.Context, cmd *models.SetUsingOrgComm
}
func setUsingOrgInTransaction(sess *DBSession, userID int64, orgID int64) error {
user := models.User{
Id: userID,
OrgId: orgID,
user := user.User{
ID: userID,
OrgID: orgID,
}
_, err := sess.ID(userID).Update(&user)
@ -386,9 +389,9 @@ func setUsingOrgInTransaction(sess *DBSession, userID int64, orgID int64) error
}
func removeUserOrg(sess *DBSession, userID int64) error {
user := models.User{
Id: userID,
OrgId: 0,
user := user.User{
ID: userID,
OrgID: 0,
}
_, err := sess.ID(userID).MustCols("org_id").Update(&user)
@ -397,7 +400,7 @@ func removeUserOrg(sess *DBSession, userID int64) error {
func (ss *SQLStore) GetUserProfile(ctx context.Context, query *models.GetUserProfileQuery) error {
return ss.WithDbSession(ctx, func(sess *DBSession) error {
var user models.User
var user user.User
has, err := sess.ID(query.UserId).Where(notServiceAccountFilter(ss)).Get(&user)
if err != nil {
@ -407,14 +410,14 @@ func (ss *SQLStore) GetUserProfile(ctx context.Context, query *models.GetUserPro
}
query.Result = models.UserProfileDTO{
Id: user.Id,
Id: user.ID,
Name: user.Name,
Email: user.Email,
Login: user.Login,
Theme: user.Theme,
IsGrafanaAdmin: user.IsAdmin,
IsDisabled: user.IsDisabled,
OrgId: user.OrgId,
OrgId: user.OrgID,
UpdatedAt: user.Updated,
CreatedAt: user.Created,
}
@ -654,7 +657,7 @@ func (ss *SQLStore) SearchUsers(ctx context.Context, query *models.SearchUsersQu
}
// get total
user := models.User{}
user := user.User{}
countSess := dbSess.Table("user").Alias("u")
// Join with user_auth table if users filtered by auth_module
@ -691,7 +694,7 @@ func (ss *SQLStore) SearchUsers(ctx context.Context, query *models.SearchUsersQu
func (ss *SQLStore) DisableUser(ctx context.Context, cmd *models.DisableUserCommand) error {
return ss.WithDbSession(ctx, func(dbSess *DBSession) error {
user := models.User{}
user := user.User{}
sess := dbSess.Table("user")
if has, err := sess.ID(cmd.UserId).Where(notServiceAccountFilter(ss)).Get(&user); err != nil {
@ -737,7 +740,7 @@ func (ss *SQLStore) DeleteUser(ctx context.Context, cmd *models.DeleteUserComman
func deleteUserInTransaction(ss *SQLStore, sess *DBSession, cmd *models.DeleteUserCommand) error {
// Check if user exists
user := models.User{Id: cmd.UserId}
user := user.User{ID: cmd.UserId}
has, err := sess.Where(notServiceAccountFilter(ss)).Get(&user)
if err != nil {
return err
@ -813,7 +816,7 @@ func UserDeletions() []string {
// UpdateUserPermissions sets the user Server Admin flag
func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
return ss.WithTransactionalDbSession(context.Background(), func(sess *DBSession) error {
var user models.User
var user user.User
if _, err := sess.ID(userID).Where(notServiceAccountFilter(ss)).Get(&user); err != nil {
return err
}
@ -821,7 +824,7 @@ func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
user.IsAdmin = isAdmin
sess.UseBool("is_admin")
_, err := sess.ID(user.Id).Update(&user)
_, err := sess.ID(user.ID).Update(&user)
if err != nil {
return err
}
@ -837,9 +840,9 @@ func (ss *SQLStore) UpdateUserPermissions(userID int64, isAdmin bool) error {
func (ss *SQLStore) SetUserHelpFlag(ctx context.Context, cmd *models.SetUserHelpFlagCommand) error {
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
user := models.User{
Id: cmd.UserId,
HelpFlags1: cmd.HelpFlags1,
user := user.User{
ID: cmd.UserId,
HelpFlags1: user.HelpFlags1(cmd.HelpFlags1),
Updated: time.Now(),
}
@ -850,7 +853,7 @@ func (ss *SQLStore) SetUserHelpFlag(ctx context.Context, cmd *models.SetUserHelp
// validateOneAdminLeft validate that there is an admin user left
func validateOneAdminLeft(sess *DBSession) error {
count, err := sess.Where("is_admin=?", true).Count(&models.User{})
count, err := sess.Where("is_admin=?", true).Count(&user.User{})
if err != nil {
return err
}

View File

@ -7,6 +7,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
@ -18,8 +19,8 @@ func TestIntegrationUserUpdate(t *testing.T) {
ss := InitTestDB(t)
users := createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("USER", i, "@test.com"),
Name: fmt.Sprint("USER", i),
Login: fmt.Sprint("loginUSER", i),
@ -32,7 +33,7 @@ func TestIntegrationUserUpdate(t *testing.T) {
t.Run("Testing DB - update generates duplicate user", func(t *testing.T) {
err := ss.UpdateUser(context.Background(), &models.UpdateUserCommand{
Login: "loginuser2",
UserId: users[0].Id,
UserId: users[0].ID,
})
require.Error(t, err)
@ -42,11 +43,11 @@ func TestIntegrationUserUpdate(t *testing.T) {
err := ss.UpdateUser(context.Background(), &models.UpdateUserCommand{
Login: "loginUSER0",
Email: "USER0@test.com",
UserId: users[0].Id,
UserId: users[0].ID,
})
require.NoError(t, err)
query := models.GetUserByIdQuery{Id: users[0].Id}
query := models.GetUserByIdQuery{Id: users[0].ID}
err = ss.GetUserById(context.Background(), &query)
require.NoError(t, err)
@ -59,11 +60,11 @@ func TestIntegrationUserUpdate(t *testing.T) {
Login: "",
Email: "",
Name: "Change Name",
UserId: users[3].Id,
UserId: users[3].ID,
})
require.NoError(t, err)
query := models.GetUserByIdQuery{Id: users[3].Id}
query := models.GetUserByIdQuery{Id: users[3].ID}
err = ss.GetUserById(context.Background(), &query)
require.NoError(t, err)
@ -83,13 +84,13 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Skip("skipping integration test")
}
ss := InitTestDB(t)
user := &models.SignedInUser{
usr := &models.SignedInUser{
OrgId: 1,
Permissions: map[int64]map[string][]string{1: {"users:read": {"global.users:*"}}},
}
t.Run("Testing DB - creates and loads user", func(t *testing.T) {
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "usertest@test.com",
Name: "user name",
Login: "user_test_login",
@ -97,7 +98,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
user, err := ss.CreateUser(context.Background(), cmd)
require.NoError(t, err)
query := models.GetUserByIdQuery{Id: user.Id}
query := models.GetUserByIdQuery{Id: user.ID}
err = ss.GetUserById(context.Background(), &query)
require.Nil(t, err)
@ -107,7 +108,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Len(t, query.Result.Salt, 10)
require.False(t, query.Result.IsDisabled)
query = models.GetUserByIdQuery{Id: user.Id}
query = models.GetUserByIdQuery{Id: user.ID}
err = ss.GetUserById(context.Background(), &query)
require.Nil(t, err)
@ -166,7 +167,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - creates and loads disabled user", func(t *testing.T) {
ss = InitTestDB(t)
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "usertest@test.com",
Name: "user name",
Login: "user_test_login",
@ -176,7 +177,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
user, err := ss.CreateUser(context.Background(), cmd)
require.Nil(t, err)
query := models.GetUserByIdQuery{Id: user.Id}
query := models.GetUserByIdQuery{Id: user.ID}
err = ss.GetUserById(context.Background(), &query)
require.Nil(t, err)
@ -200,17 +201,17 @@ func TestIntegrationUserDataAccess(t *testing.T) {
err := ss.CreateOrg(context.Background(), orgCmd)
require.Nil(t, err)
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "usertest@test.com",
Name: "user name",
Login: "user_test_login",
OrgId: orgCmd.Result.Id,
OrgID: orgCmd.Result.Id,
}
user, err := ss.CreateUser(context.Background(), cmd)
usr, err := ss.CreateUser(context.Background(), cmd)
require.Nil(t, err)
query := models.GetUserByIdQuery{Id: user.Id}
query := models.GetUserByIdQuery{Id: usr.ID}
err = ss.GetUserById(context.Background(), &query)
require.Nil(t, err)
@ -219,14 +220,14 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Len(t, query.Result.Rands, 10)
require.Len(t, query.Result.Salt, 10)
require.False(t, query.Result.IsDisabled)
require.Equal(t, query.Result.OrgId, orgCmd.Result.Id)
require.Equal(t, query.Result.OrgID, orgCmd.Result.Id)
const nonExistingOrgID = 10000
cmd = models.CreateUserCommand{
cmd = user.CreateUserCommand{
Email: "usertest@test.com",
Name: "user name",
Login: "user_test_login",
OrgId: nonExistingOrgID,
OrgID: nonExistingOrgID,
}
_, err = ss.CreateUser(context.Background(), cmd)
@ -236,8 +237,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - multiple users", func(t *testing.T) {
ss = InitTestDB(t)
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -246,7 +247,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
})
// Return the first page of users and a total count
query := models.SearchUsersQuery{Query: "", Page: 1, Limit: 3, SignedInUser: user}
query := models.SearchUsersQuery{Query: "", Page: 1, Limit: 3, SignedInUser: usr}
err := ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -254,7 +255,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.EqualValues(t, query.Result.TotalCount, 5)
// Return the second page of users and a total count
query = models.SearchUsersQuery{Query: "", Page: 2, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "", Page: 2, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -262,28 +263,28 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.EqualValues(t, query.Result.TotalCount, 5)
// Return list of users matching query on user name
query = models.SearchUsersQuery{Query: "use", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "use", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
require.Len(t, query.Result.Users, 3)
require.EqualValues(t, query.Result.TotalCount, 5)
query = models.SearchUsersQuery{Query: "ser1", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "ser1", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
require.Len(t, query.Result.Users, 1)
require.EqualValues(t, query.Result.TotalCount, 1)
query = models.SearchUsersQuery{Query: "USER1", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "USER1", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
require.Len(t, query.Result.Users, 1)
require.EqualValues(t, query.Result.TotalCount, 1)
query = models.SearchUsersQuery{Query: "idontexist", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "idontexist", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -291,7 +292,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.EqualValues(t, query.Result.TotalCount, 0)
// Return list of users matching query on email
query = models.SearchUsersQuery{Query: "ser1@test.com", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "ser1@test.com", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -299,7 +300,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.EqualValues(t, query.Result.TotalCount, 1)
// Return list of users matching query on login name
query = models.SearchUsersQuery{Query: "loginuser1", Page: 1, Limit: 3, SignedInUser: user}
query = models.SearchUsersQuery{Query: "loginuser1", Page: 1, Limit: 3, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -309,8 +310,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - return list users based on their is_disabled flag", func(t *testing.T) {
ss = InitTestDB(t)
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -319,7 +320,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
})
isDisabled := false
query := models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: user}
query := models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: usr}
err := ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -341,8 +342,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
// Re-init DB
ss = InitTestDB(t)
users := createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -352,27 +353,27 @@ func TestIntegrationUserDataAccess(t *testing.T) {
err = ss.AddOrgUser(context.Background(), &models.AddOrgUserCommand{
LoginOrEmail: users[1].Login, Role: models.ROLE_VIEWER,
OrgId: users[0].OrgId, UserId: users[1].Id,
OrgId: users[0].OrgID, UserId: users[1].ID,
})
require.Nil(t, err)
err = updateDashboardAcl(t, ss, 1, &models.DashboardAcl{
DashboardID: 1, OrgID: users[0].OrgId, UserID: users[1].Id,
DashboardID: 1, OrgID: users[0].OrgID, UserID: users[1].ID,
Permission: models.PERMISSION_EDIT,
})
require.Nil(t, err)
// When the user is deleted
err = ss.DeleteUser(context.Background(), &models.DeleteUserCommand{UserId: users[1].Id})
err = ss.DeleteUser(context.Background(), &models.DeleteUserCommand{UserId: users[1].ID})
require.Nil(t, err)
query1 := &models.GetOrgUsersQuery{OrgId: users[0].OrgId, User: user}
query1 := &models.GetOrgUsersQuery{OrgId: users[0].OrgID, User: usr}
err = ss.GetOrgUsersForTest(context.Background(), query1)
require.Nil(t, err)
require.Len(t, query1.Result, 1)
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgId}
permQuery := &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgID}
err = getDashboardAclInfoList(ss, permQuery)
require.Nil(t, err)
@ -381,8 +382,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
// A user is an org member and has been assigned permissions
// Re-init DB
ss = InitTestDB(t)
users = createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
users = createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -391,37 +392,37 @@ func TestIntegrationUserDataAccess(t *testing.T) {
})
err = ss.AddOrgUser(context.Background(), &models.AddOrgUserCommand{
LoginOrEmail: users[1].Login, Role: models.ROLE_VIEWER,
OrgId: users[0].OrgId, UserId: users[1].Id,
OrgId: users[0].OrgID, UserId: users[1].ID,
})
require.Nil(t, err)
err = updateDashboardAcl(t, ss, 1, &models.DashboardAcl{
DashboardID: 1, OrgID: users[0].OrgId, UserID: users[1].Id,
DashboardID: 1, OrgID: users[0].OrgID, UserID: users[1].ID,
Permission: models.PERMISSION_EDIT,
})
require.Nil(t, err)
ss.CacheService.Flush()
query3 := &models.GetSignedInUserQuery{OrgId: users[1].OrgId, UserId: users[1].Id}
query3 := &models.GetSignedInUserQuery{OrgId: users[1].OrgID, UserId: users[1].ID}
err = ss.GetSignedInUserWithCacheCtx(context.Background(), query3)
require.Nil(t, err)
require.NotNil(t, query3.Result)
require.Equal(t, query3.OrgId, users[1].OrgId)
err = ss.SetUsingOrg(context.Background(), &models.SetUsingOrgCommand{UserId: users[1].Id, OrgId: users[0].OrgId})
require.Equal(t, query3.OrgId, users[1].OrgID)
err = ss.SetUsingOrg(context.Background(), &models.SetUsingOrgCommand{UserId: users[1].ID, OrgId: users[0].OrgID})
require.Nil(t, err)
query4 := &models.GetSignedInUserQuery{OrgId: 0, UserId: users[1].Id}
query4 := &models.GetSignedInUserQuery{OrgId: 0, UserId: users[1].ID}
err = ss.GetSignedInUserWithCacheCtx(context.Background(), query4)
require.Nil(t, err)
require.NotNil(t, query4.Result)
require.Equal(t, query4.Result.OrgId, users[0].OrgId)
require.Equal(t, query4.Result.OrgId, users[0].OrgID)
cacheKey := newSignedInUserCacheKey(query4.Result.OrgId, query4.UserId)
_, found := ss.CacheService.Get(cacheKey)
require.True(t, found)
disableCmd := models.BatchDisableUsersCommand{
UserIds: []int64{users[0].Id, users[1].Id, users[2].Id, users[3].Id, users[4].Id},
UserIds: []int64{users[0].ID, users[1].ID, users[2].ID, users[3].ID, users[4].ID},
IsDisabled: true,
}
@ -429,24 +430,24 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Nil(t, err)
isDisabled = true
query5 := &models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: user}
query5 := &models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), query5)
require.Nil(t, err)
require.EqualValues(t, query5.Result.TotalCount, 5)
// the user is deleted
err = ss.DeleteUser(context.Background(), &models.DeleteUserCommand{UserId: users[1].Id})
err = ss.DeleteUser(context.Background(), &models.DeleteUserCommand{UserId: users[1].ID})
require.Nil(t, err)
// delete connected org users and permissions
query2 := &models.GetOrgUsersQuery{OrgId: users[0].OrgId}
query2 := &models.GetOrgUsersQuery{OrgId: users[0].OrgID}
err = ss.GetOrgUsersForTest(context.Background(), query2)
require.Nil(t, err)
require.Len(t, query2.Result, 1)
permQuery = &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgId}
permQuery = &models.GetDashboardAclInfoListQuery{DashboardID: 1, OrgID: users[0].OrgID}
err = getDashboardAclInfoList(ss, permQuery)
require.Nil(t, err)
@ -455,8 +456,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - return list of users that the SignedInUser has permission to read", func(t *testing.T) {
ss := InitTestDB(t)
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -478,7 +479,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Skip("Skipping on MySQL due to case insensitive indexes")
}
cmd := models.CreateUserCommand{
cmd := user.CreateUserCommand{
Email: "confusertest@test.com",
Name: "user name",
Login: "user_email_conflict",
@ -486,7 +487,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
userEmailConflict, err := ss.CreateUser(context.Background(), cmd)
require.NoError(t, err)
cmd = models.CreateUserCommand{
cmd = user.CreateUserCommand{
Email: "confusertest@TEST.COM",
Name: "user name",
Login: "user_email_conflict_two",
@ -494,7 +495,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
_, err = ss.CreateUser(context.Background(), cmd)
require.NoError(t, err)
cmd = models.CreateUserCommand{
cmd = user.CreateUserCommand{
Email: "user_test_login_conflict@test.com",
Name: "user name",
Login: "user_test_login_conflict",
@ -502,7 +503,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
userLoginConflict, err := ss.CreateUser(context.Background(), cmd)
require.NoError(t, err)
cmd = models.CreateUserCommand{
cmd = user.CreateUserCommand{
Email: "user_test_login_conflict_two@test.com",
Name: "user name",
Login: "user_test_login_CONFLICT",
@ -525,13 +526,13 @@ func TestIntegrationUserDataAccess(t *testing.T) {
})
t.Run("GetUserByID - email conflict", func(t *testing.T) {
query := models.GetUserByIdQuery{Id: userEmailConflict.Id}
query := models.GetUserByIdQuery{Id: userEmailConflict.ID}
err = ss.GetUserById(context.Background(), &query)
require.Error(t, err)
})
t.Run("GetUserByID - login conflict", func(t *testing.T) {
query := models.GetUserByIdQuery{Id: userLoginConflict.Id}
query := models.GetUserByIdQuery{Id: userLoginConflict.ID}
err = ss.GetUserById(context.Background(), &query)
require.Error(t, err)
})
@ -560,8 +561,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
ss = InitTestDB(t)
t.Run("Testing DB - enable all users", func(t *testing.T) {
users := createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -570,7 +571,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
})
disableCmd := models.BatchDisableUsersCommand{
UserIds: []int64{users[0].Id, users[1].Id, users[2].Id, users[3].Id, users[4].Id},
UserIds: []int64{users[0].ID, users[1].ID, users[2].ID, users[3].ID, users[4].ID},
IsDisabled: false,
}
@ -578,7 +579,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Nil(t, err)
isDisabled := false
query := &models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: user}
query := &models.SearchUsersQuery{IsDisabled: &isDisabled, SignedInUser: usr}
err = ss.SearchUsers(context.Background(), query)
require.Nil(t, err)
@ -588,8 +589,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
ss = InitTestDB(t)
t.Run("Testing DB - disable only specific users", func(t *testing.T) {
users := createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -599,7 +600,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
userIdsToDisable := []int64{}
for i := 0; i < 3; i++ {
userIdsToDisable = append(userIdsToDisable, users[i].Id)
userIdsToDisable = append(userIdsToDisable, users[i].ID)
}
disableCmd := models.BatchDisableUsersCommand{
UserIds: userIdsToDisable,
@ -609,7 +610,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
err := ss.BatchDisableUsers(context.Background(), &disableCmd)
require.Nil(t, err)
query := models.SearchUsersQuery{SignedInUser: user}
query := models.SearchUsersQuery{SignedInUser: usr}
err = ss.SearchUsers(context.Background(), &query)
require.Nil(t, err)
@ -636,8 +637,8 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - search users", func(t *testing.T) {
// Since previous tests were destructive
createFiveTestUsers(t, ss, func(i int) *models.CreateUserCommand {
return &models.CreateUserCommand{
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
return &user.CreateUserCommand{
Email: fmt.Sprint("user", i, "@test.com"),
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
@ -649,21 +650,21 @@ func TestIntegrationUserDataAccess(t *testing.T) {
t.Run("Testing DB - grafana admin users", func(t *testing.T) {
ss = InitTestDB(t)
createUserCmd := models.CreateUserCommand{
createUserCmd := user.CreateUserCommand{
Email: fmt.Sprint("admin", "@test.com"),
Name: "admin",
Login: "admin",
IsAdmin: true,
}
user, err := ss.CreateUser(context.Background(), createUserCmd)
usr, err := ss.CreateUser(context.Background(), createUserCmd)
require.Nil(t, err)
// Cannot make themselves a non-admin
updatePermsError := ss.UpdateUserPermissions(user.Id, false)
updatePermsError := ss.UpdateUserPermissions(usr.ID, false)
require.Equal(t, updatePermsError, models.ErrLastGrafanaAdmin)
query := models.GetUserByIdQuery{Id: user.Id}
query := models.GetUserByIdQuery{Id: usr.ID}
getUserError := ss.GetUserById(context.Background(), &query)
require.Nil(t, getUserError)
@ -672,7 +673,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
// One user
const email = "user@test.com"
const username = "user"
createUserCmd = models.CreateUserCommand{
createUserCmd = user.CreateUserCommand{
Email: email,
Name: "user",
Login: username,
@ -681,7 +682,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Nil(t, err)
// When trying to create a new user with the same email, an error is returned
createUserCmd = models.CreateUserCommand{
createUserCmd = user.CreateUserCommand{
Email: email,
Name: "user2",
Login: "user2",
@ -691,7 +692,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
require.Equal(t, err, models.ErrUserAlreadyExists)
// When trying to create a new user with the same login, an error is returned
createUserCmd = models.CreateUserCommand{
createUserCmd = user.CreateUserCommand{
Email: "user2@test.com",
Name: "user2",
Login: username,
@ -715,10 +716,10 @@ func (ss *SQLStore) GetOrgUsersForTest(ctx context.Context, query *models.GetOrg
})
}
func createFiveTestUsers(t *testing.T, sqlStore *SQLStore, fn func(i int) *models.CreateUserCommand) []models.User {
func createFiveTestUsers(t *testing.T, sqlStore *SQLStore, fn func(i int) *user.CreateUserCommand) []user.User {
t.Helper()
users := []models.User{}
users := []user.User{}
for i := 0; i < 5; i++ {
cmd := fn(i)

View File

@ -0,0 +1,55 @@
package user
import "time"
type HelpFlags1 uint64
type User struct {
ID int64 `xorm:"pk autoincr 'id'"`
Version int
Email string
Name string
Login string
Password string
Salt string
Rands string
Company string
EmailVerified bool
Theme string
HelpFlags1 HelpFlags1
IsDisabled bool
IsAdmin bool
IsServiceAccount bool
OrgID int64 `xorm:"org_id"`
Created time.Time
Updated time.Time
LastSeenAt time.Time
}
type CreateUserCommand struct {
Email string
Login string
Name string
Company string
OrgID int64
OrgName string
Password string
EmailVerified bool
IsAdmin bool
IsDisabled bool
SkipOrgSetup bool
DefaultOrgRole string
IsServiceAccount bool
}
func (u *User) NameOrFallback() string {
if u.Name != "" {
return u.Name
}
if u.Login != "" {
return u.Login
}
return u.Email
}

View File

@ -0,0 +1,9 @@
package user
import (
"context"
)
type Service interface {
Create(context.Context, *CreateUserCommand) (*User, error)
}

View File

@ -0,0 +1,62 @@
package userimpl
import (
"context"
"github.com/grafana/grafana/pkg/events"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/user"
)
type store interface {
Insert(context.Context, *user.User) (int64, error)
Get(context.Context, *user.User) (*user.User, error)
}
type sqlStore struct {
db db.DB
}
func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) {
var userID int64
var err error
err = ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
sess.UseBool("is_admin")
if userID, err = sess.Insert(cmd); err != nil {
return err
}
sess.PublishAfterCommit(&events.UserCreated{
Timestamp: cmd.Created,
Id: cmd.ID,
Name: cmd.Name,
Login: cmd.Login,
Email: cmd.Email,
})
return nil
})
if err != nil {
return 0, err
}
return userID, nil
}
func (ss *sqlStore) Get(ctx context.Context, cmd *user.User) (*user.User, error) {
var usr *user.User
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
exists, err := sess.Where("email=? OR login=?", cmd.Email, cmd.Login).Get(&user.User{})
if !exists {
return models.ErrUserNotFound
}
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, err
}
return usr, nil
}

View File

@ -0,0 +1,57 @@
package userimpl
import (
"context"
"testing"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
func TestIntegrationUserDataAccess(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}
ss := sqlstore.InitTestDB(t)
userStore := sqlStore{db: ss}
t.Run("user not found", func(t *testing.T) {
_, err := userStore.Get(context.Background(),
&user.User{
Email: "test@email.com",
Name: "test1",
Login: "test1",
},
)
require.Error(t, err, models.ErrUserNotFound)
})
t.Run("insert user", func(t *testing.T) {
_, err := userStore.Insert(context.Background(),
&user.User{
Email: "test@email.com",
Name: "test1",
Login: "test1",
Created: time.Now(),
Updated: time.Now(),
},
)
require.NoError(t, err)
})
t.Run("get user", func(t *testing.T) {
_, err := userStore.Get(context.Background(),
&user.User{
Email: "test@email.com",
Name: "test1",
Login: "test1",
},
)
require.NoError(t, err)
})
}

View File

@ -0,0 +1,121 @@
package userimpl
import (
"context"
"errors"
"time"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/org"
"github.com/grafana/grafana/pkg/services/sqlstore/db"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/util"
)
type Service struct {
store store
orgService org.Service
}
func ProvideService(db db.DB, orgService org.Service) user.Service {
return &Service{
store: &sqlStore{
db: db,
},
orgService: orgService,
}
}
func (s *Service) Create(ctx context.Context, cmd *user.CreateUserCommand) (*user.User, error) {
cmdOrg := org.GetOrgIDForNewUserCommand{
Email: cmd.Email,
Login: cmd.Login,
OrgID: cmd.OrgID,
OrgName: cmd.OrgName,
SkipOrgSetup: cmd.SkipOrgSetup,
}
orgID, err := s.orgService.GetIDForNewUser(ctx, cmdOrg)
cmd.OrgID = orgID
if err != nil {
return nil, err
}
if cmd.Email == "" {
cmd.Email = cmd.Login
}
usr := &user.User{
Login: cmd.Login,
Email: cmd.Email,
}
usr, err = s.store.Get(ctx, usr)
if err != nil && !errors.Is(err, models.ErrUserNotFound) {
return usr, err
}
// create user
usr = &user.User{
Email: cmd.Email,
Name: cmd.Name,
Login: cmd.Login,
Company: cmd.Company,
IsAdmin: cmd.IsAdmin,
IsDisabled: cmd.IsDisabled,
OrgID: cmd.OrgID,
EmailVerified: cmd.EmailVerified,
Created: time.Now(),
Updated: time.Now(),
LastSeenAt: time.Now().AddDate(-10, 0, 0),
IsServiceAccount: cmd.IsServiceAccount,
}
salt, err := util.GetRandomString(10)
if err != nil {
return nil, err
}
usr.Salt = salt
rands, err := util.GetRandomString(10)
if err != nil {
return nil, err
}
usr.Rands = rands
if len(cmd.Password) > 0 {
encodedPassword, err := util.EncodePassword(cmd.Password, usr.Salt)
if err != nil {
return nil, err
}
usr.Password = encodedPassword
}
_, err = s.store.Insert(ctx, usr)
if err != nil {
return nil, err
}
// create org user link
if !cmd.SkipOrgSetup {
orgUser := org.OrgUser{
OrgID: orgID,
UserID: usr.ID,
Role: org.ROLE_ADMIN,
Created: time.Now(),
Updated: time.Now(),
}
if setting.AutoAssignOrg && !usr.IsAdmin {
if len(cmd.DefaultOrgRole) > 0 {
orgUser.Role = org.RoleType(cmd.DefaultOrgRole)
} else {
orgUser.Role = org.RoleType(setting.AutoAssignOrgRole)
}
}
_, err = s.orgService.InsertUser(ctx, &orgUser)
if err != nil {
// HERE ADD DELETE USER
return usr, err
}
}
return usr, nil
}

View File

@ -0,0 +1,41 @@
package userimpl
import (
"context"
"testing"
"github.com/grafana/grafana/pkg/services/org/orgtest"
"github.com/grafana/grafana/pkg/services/user"
"github.com/stretchr/testify/require"
)
func TestUserService(t *testing.T) {
userStore := newUserStoreFake()
orgService := orgtest.NewOrgServiceFake()
userService := Service{
store: userStore,
orgService: orgService,
}
t.Run("create user", func(t *testing.T) {
_, err := userService.Create(context.Background(), &user.CreateUserCommand{})
require.NoError(t, err)
})
}
type FakeUserStore struct {
ExpectedUser *user.User
ExpectedError error
}
func newUserStoreFake() *FakeUserStore {
return &FakeUserStore{}
}
func (f *FakeUserStore) Get(ctx context.Context, query *user.User) (*user.User, error) {
return f.ExpectedUser, f.ExpectedError
}
func (f *FakeUserStore) Insert(ctx context.Context, query *user.User) (int64, error) {
return 0, f.ExpectedError
}

View File

@ -0,0 +1,20 @@
package usertest
import (
"context"
"github.com/grafana/grafana/pkg/services/user"
)
type FakeUserService struct {
ExpectedUser *user.User
ExpectedError error
}
func NewUserServiceFake() *FakeUserService {
return &FakeUserService{}
}
func (f *FakeUserService) Create(ctx context.Context, cmd *user.CreateUserCommand) (*user.User, error) {
return f.ExpectedUser, f.ExpectedError
}

View File

@ -16,6 +16,7 @@ import (
apimodels "github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/tests/testinfra"
)
@ -33,7 +34,7 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
grafanaListedAddr, s := testinfra.StartGrafana(t, dir, path)
// Create a user to make authenticated requests
userID := createUser(t, s, models.CreateUserCommand{
userID := createUser(t, s, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_ADMIN),
Login: "grafana",
Password: "password",
@ -45,11 +46,11 @@ func TestAdminConfiguration_SendingToExternalAlertmanagers(t *testing.T) {
require.Equal(t, disableOrgID, orgID)
// create user under different organisation
createUser(t, s, models.CreateUserCommand{
createUser(t, s, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_ADMIN),
Password: "admin-42",
Login: "admin-42",
OrgId: orgID,
OrgID: orgID,
})
// Create a couple of "fake" Alertmanagers

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ngalert/api/tooling/definitions"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/tests/testinfra"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
@ -31,7 +32,7 @@ func TestAlertmanagerConfigurationIsTransactional(t *testing.T) {
alertConfigURL := fmt.Sprintf("http://editor:editor@%s/api/alertmanager/grafana/config/api/v1/alerts", grafanaListedAddr)
// create user under main organisation
userID := createUser(t, store, models.CreateUserCommand{
userID := createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor",
Login: "editor",
@ -41,11 +42,11 @@ func TestAlertmanagerConfigurationIsTransactional(t *testing.T) {
orgID := createOrg(t, store, "another org", userID)
// create user under different organisation
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor-42",
Login: "editor-42",
OrgId: orgID,
OrgID: orgID,
})
// On a blank start with no configuration, it saves and delivers the default configuration.
@ -139,7 +140,7 @@ func TestAlertmanagerConfigurationPersistSecrets(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
alertConfigURL := fmt.Sprintf("http://editor:editor@%s/api/alertmanager/grafana/config/api/v1/alerts", grafanaListedAddr)
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor",
Login: "editor",

View File

@ -21,6 +21,7 @@ import (
ngmodels "github.com/grafana/grafana/pkg/services/ngalert/models"
ngstore "github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tests/testinfra"
)
@ -41,17 +42,17 @@ func TestAMConfigAccess(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
// Create a users to make authenticated requests
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_VIEWER),
Password: "viewer",
Login: "viewer",
})
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor",
Login: "editor",
})
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_ADMIN),
Password: "admin",
Login: "admin",
@ -415,7 +416,7 @@ func TestAlertAndGroupsQuery(t *testing.T) {
}
// Create a user to make authenticated requests
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",
@ -559,17 +560,17 @@ func TestRulerAccess(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
// Create a users to make authenticated requests
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_VIEWER),
Password: "viewer",
Login: "viewer",
})
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor",
Login: "editor",
})
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_ADMIN),
Password: "admin",
Login: "admin",
@ -673,12 +674,12 @@ func TestDeleteFolderWithRules(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_VIEWER),
Password: "viewer",
Login: "viewer",
})
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "editor",
Login: "editor",
@ -833,7 +834,7 @@ func TestAlertRuleCRUD(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",
@ -1874,7 +1875,7 @@ func TestQuota(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
// Create a user to make authenticated requests
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",
@ -2090,7 +2091,7 @@ func TestEval(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",
@ -2545,7 +2546,7 @@ func rulesNamespaceWithoutVariableValues(t *testing.T, b []byte) (string, map[st
return string(json), m
}
func createUser(t *testing.T, store *sqlstore.SQLStore, cmd models.CreateUserCommand) int64 {
func createUser(t *testing.T, store *sqlstore.SQLStore, cmd user.CreateUserCommand) int64 {
t.Helper()
store.Cfg.AutoAssignOrg = true
@ -2553,7 +2554,7 @@ func createUser(t *testing.T, store *sqlstore.SQLStore, cmd models.CreateUserCom
u, err := store.CreateUser(context.Background(), cmd)
require.NoError(t, err)
return u.Id
return u.ID
}
func createOrg(t *testing.T, store *sqlstore.SQLStore, name string, userID int64) int64 {

View File

@ -11,6 +11,7 @@ import (
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/tests/testinfra"
)
@ -25,7 +26,7 @@ func TestAvailableChannels(t *testing.T) {
grafanaListedAddr, store := testinfra.StartGrafana(t, dir, path)
// Create a user to make authenticated requests
createUser(t, store, models.CreateUserCommand{
createUser(t, store, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",

View File

@ -27,6 +27,7 @@ import (
"github.com/grafana/grafana/pkg/services/ngalert/notifier/channels"
"github.com/grafana/grafana/pkg/services/ngalert/store"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/services/user"
"github.com/grafana/grafana/pkg/tests/testinfra"
)
@ -41,7 +42,7 @@ func TestTestReceivers(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -75,7 +76,7 @@ func TestTestReceivers(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -157,7 +158,7 @@ func TestTestReceivers(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -234,7 +235,7 @@ func TestTestReceivers(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -321,7 +322,7 @@ func TestTestReceivers(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -434,7 +435,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -527,7 +528,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -615,7 +616,7 @@ func TestTestReceiversAlertCustomization(t *testing.T) {
grafanaListedAddr, env := testinfra.StartGrafanaEnv(t, dir, path)
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Login: "grafana",
Password: "password",
@ -738,7 +739,7 @@ func TestNotificationChannels(t *testing.T) {
}
// Create a user to make authenticated requests
createUser(t, env.SQLStore, models.CreateUserCommand{
createUser(t, env.SQLStore, user.CreateUserCommand{
DefaultOrgRole: string(models.ROLE_EDITOR),
Password: "password",
Login: "grafana",

Some files were not shown because too many files have changed in this diff Show More