mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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:
parent
2429fe1c70
commit
6c43eb0b4d
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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()
|
||||
|
@ -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")
|
||||
}
|
||||
|
@ -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{
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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) {
|
||||
|
@ -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
|
||||
|
@ -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 {
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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) {
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
@ -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{})
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -7,7 +7,7 @@ import (
|
||||
|
||||
// Typed errors
|
||||
var (
|
||||
ErrTempUserNotFound = errors.New("User not found")
|
||||
ErrTempUserNotFound = errors.New("user not found")
|
||||
)
|
||||
|
||||
type TempUserStatus string
|
||||
|
@ -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 {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
|
@ -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")
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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{}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
}
|
||||
|
@ -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",
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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,
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -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")
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
60
pkg/services/org/model.go
Normal 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
10
pkg/services/org/org.go
Normal file
@ -0,0 +1,10 @@
|
||||
package org
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
GetIDForNewUser(context.Context, GetOrgIDForNewUserCommand) (int64, error)
|
||||
InsertUser(context.Context, *OrgUser) (int64, error)
|
||||
}
|
78
pkg/services/org/orgimpl/org.go
Normal file
78
pkg/services/org/orgimpl/org.go
Normal 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)
|
||||
}
|
72
pkg/services/org/orgimpl/org_test.go
Normal file
72
pkg/services/org/orgimpl/org_test.go
Normal 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
|
||||
}
|
83
pkg/services/org/orgimpl/store.go
Normal file
83
pkg/services/org/orgimpl/store.go
Normal 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
|
||||
}
|
73
pkg/services/org/orgimpl/store_test.go
Normal file
73
pkg/services/org/orgimpl/store_test.go
Normal 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)
|
||||
})
|
||||
}
|
28
pkg/services/org/orgtest/fake.go
Normal file
28
pkg/services/org/orgtest/fake.go
Normal 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
|
||||
}
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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 {
|
||||
|
@ -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 {
|
||||
|
@ -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())
|
||||
|
@ -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 {
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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()}
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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)
|
||||
|
||||
|
55
pkg/services/user/model.go
Normal file
55
pkg/services/user/model.go
Normal 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
|
||||
}
|
9
pkg/services/user/user.go
Normal file
9
pkg/services/user/user.go
Normal file
@ -0,0 +1,9 @@
|
||||
package user
|
||||
|
||||
import (
|
||||
"context"
|
||||
)
|
||||
|
||||
type Service interface {
|
||||
Create(context.Context, *CreateUserCommand) (*User, error)
|
||||
}
|
62
pkg/services/user/userimpl/store.go
Normal file
62
pkg/services/user/userimpl/store.go
Normal 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
|
||||
}
|
57
pkg/services/user/userimpl/store_test.go
Normal file
57
pkg/services/user/userimpl/store_test.go
Normal 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)
|
||||
})
|
||||
}
|
121
pkg/services/user/userimpl/user.go
Normal file
121
pkg/services/user/userimpl/user.go
Normal 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
|
||||
}
|
41
pkg/services/user/userimpl/user_test.go
Normal file
41
pkg/services/user/userimpl/user_test.go
Normal 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
|
||||
}
|
20
pkg/services/user/usertest/fake.go
Normal file
20
pkg/services/user/usertest/fake.go
Normal 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
|
||||
}
|
@ -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
|
||||
|
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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",
|
||||
|
@ -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
Loading…
Reference in New Issue
Block a user