Chore: Copy sqlstore methods to user store (#56280)

* Chore: Copy sqlstore methods to user store

* Fix xorm tag

* Add tests

* Remove unused methods from sqlstore
This commit is contained in:
idafurjes
2022-10-04 14:14:32 +02:00
committed by GitHub
parent 3d58f39b25
commit a25516fbe3
12 changed files with 175 additions and 150 deletions
+82
View File
@@ -30,6 +30,9 @@ type store interface {
UpdateLastSeenAt(context.Context, *user.UpdateUserLastSeenAtCommand) error
GetSignedInUser(context.Context, *user.GetSignedInUserQuery) (*user.SignedInUser, error)
UpdateUser(context.Context, *user.User) error
GetProfile(context.Context, *user.GetUserProfileQuery) (*user.UserProfileDTO, error)
SetHelpFlag(context.Context, *user.SetUserHelpFlagCommand) error
UpdatePermissions(context.Context, int64, bool) error
}
type sqlStore struct {
@@ -387,3 +390,82 @@ func (ss *sqlStore) UpdateUser(ctx context.Context, user *user.User) error {
return err
})
}
func (ss *sqlStore) GetProfile(ctx context.Context, query *user.GetUserProfileQuery) (*user.UserProfileDTO, error) {
var usr user.User
var userProfile user.UserProfileDTO
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
has, err := sess.ID(query.UserID).Where(ss.notServiceAccountFilter()).Get(&usr)
if err != nil {
return err
} else if !has {
return user.ErrUserNotFound
}
userProfile = user.UserProfileDTO{
ID: usr.ID,
Name: usr.Name,
Email: usr.Email,
Login: usr.Login,
Theme: usr.Theme,
IsGrafanaAdmin: usr.IsAdmin,
IsDisabled: usr.IsDisabled,
OrgID: usr.OrgID,
UpdatedAt: usr.Updated,
CreatedAt: usr.Created,
}
return err
})
return &userProfile, err
}
func (ss *sqlStore) SetHelpFlag(ctx context.Context, cmd *user.SetUserHelpFlagCommand) error {
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
user := user.User{
ID: cmd.UserID,
HelpFlags1: cmd.HelpFlags1,
Updated: sqlstore.TimeNow(),
}
_, err := sess.ID(cmd.UserID).Cols("help_flags1").Update(&user)
return err
})
}
// UpdatePermissions sets the user Server Admin flag
func (ss *sqlStore) UpdatePermissions(ctx context.Context, userID int64, isAdmin bool) error {
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
var user user.User
if _, err := sess.ID(userID).Where(ss.notServiceAccountFilter()).Get(&user); err != nil {
return err
}
user.IsAdmin = isAdmin
sess.UseBool("is_admin")
_, err := sess.ID(user.ID).Update(&user)
if err != nil {
return err
}
// validate that after update there is at least one server admin
if err := validateOneAdminLeft(ctx, sess); err != nil {
return err
}
return nil
})
}
// validateOneAdminLeft validate that there is an admin user left
func validateOneAdminLeft(ctx context.Context, sess *sqlstore.DBSession) error {
count, err := sess.Where("is_admin=?", true).Count(&user.User{})
if err != nil {
return err
}
if count == 0 {
return user.ErrLastGrafanaAdmin
}
return nil
}
+65
View File
@@ -246,6 +246,71 @@ func TestIntegrationUserDataAccess(t *testing.T) {
assert.Equal(t, result.Name, "testtestest")
assert.Equal(t, result.Login, "loginloginlogin")
})
t.Run("Testing DB - grafana admin users", func(t *testing.T) {
ss = sqlstore.InitTestDB(t)
createUserCmd := user.CreateUserCommand{
Email: fmt.Sprint("admin", "@test.com"),
Name: "admin",
Login: "admin",
IsAdmin: true,
}
usr, err := ss.CreateUser(context.Background(), createUserCmd)
require.Nil(t, err)
// Cannot make themselves a non-admin
updatePermsError := userStore.UpdatePermissions(context.Background(), usr.ID, false)
require.Equal(t, user.ErrLastGrafanaAdmin, updatePermsError)
query := models.GetUserByIdQuery{Id: usr.ID}
getUserError := ss.GetUserById(context.Background(), &query)
require.Nil(t, getUserError)
require.True(t, query.Result.IsAdmin)
// One user
const email = "user@test.com"
const username = "user"
createUserCmd = user.CreateUserCommand{
Email: email,
Name: "user",
Login: username,
}
_, err = ss.CreateUser(context.Background(), createUserCmd)
require.Nil(t, err)
// When trying to create a new user with the same email, an error is returned
createUserCmd = user.CreateUserCommand{
Email: email,
Name: "user2",
Login: "user2",
SkipOrgSetup: true,
}
_, err = ss.CreateUser(context.Background(), createUserCmd)
require.Equal(t, err, user.ErrUserAlreadyExists)
// When trying to create a new user with the same login, an error is returned
createUserCmd = user.CreateUserCommand{
Email: "user2@test.com",
Name: "user2",
Login: username,
SkipOrgSetup: true,
}
_, err = ss.CreateUser(context.Background(), createUserCmd)
require.Equal(t, err, user.ErrUserAlreadyExists)
})
t.Run("GetProfile", func(t *testing.T) {
_, err := userStore.GetProfile(context.Background(), &user.GetUserProfileQuery{UserID: 1})
require.NoError(t, err)
})
t.Run("SetHelpFlag", func(t *testing.T) {
err := userStore.SetHelpFlag(context.Background(), &user.SetUserHelpFlagCommand{UserID: 1, HelpFlags1: user.HelpFlags1(1)})
require.NoError(t, err)
})
}
func TestIntegrationUserUpdate(t *testing.T) {
+6 -35
View File
@@ -319,44 +319,15 @@ func (s *Service) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableU
return s.sqlStore.BatchDisableUsers(ctx, c)
}
// TODO: remove wrapper around sqlstore
func (s *Service) UpdatePermissions(userID int64, isAdmin bool) error {
return s.sqlStore.UpdateUserPermissions(userID, isAdmin)
func (s *Service) UpdatePermissions(ctx context.Context, userID int64, isAdmin bool) error {
return s.store.UpdatePermissions(ctx, userID, isAdmin)
}
// TODO: remove wrapper around sqlstore
func (s *Service) SetUserHelpFlag(ctx context.Context, cmd *user.SetUserHelpFlagCommand) error {
c := &models.SetUserHelpFlagCommand{
UserId: cmd.UserID,
HelpFlags1: cmd.HelpFlags1,
}
return s.sqlStore.SetUserHelpFlag(ctx, c)
return s.store.SetHelpFlag(ctx, cmd)
}
// TODO: remove wrapper around sqlstore
func (s *Service) GetProfile(ctx context.Context, query *user.GetUserProfileQuery) (user.UserProfileDTO, error) {
q := &models.GetUserProfileQuery{
UserId: query.UserID,
}
err := s.sqlStore.GetUserProfile(ctx, q)
if err != nil {
return user.UserProfileDTO{}, err
}
result := user.UserProfileDTO{
ID: q.Result.Id,
Email: q.Result.Email,
Name: q.Result.Name,
Login: q.Result.Login,
Theme: q.Result.Theme,
OrgID: q.Result.OrgId,
IsGrafanaAdmin: q.Result.IsGrafanaAdmin,
IsDisabled: q.Result.IsDisabled,
IsExternal: q.Result.IsExternal,
AuthLabels: q.Result.AuthLabels,
UpdatedAt: q.Result.UpdatedAt,
CreatedAt: q.Result.CreatedAt,
AvatarUrl: q.Result.AvatarUrl,
AccessControl: q.Result.AccessControl,
}
return result, nil
func (s *Service) GetProfile(ctx context.Context, query *user.GetUserProfileQuery) (*user.UserProfileDTO, error) {
result, err := s.store.GetProfile(ctx, query)
return result, err
}
+13
View File
@@ -131,6 +131,7 @@ func TestUserService(t *testing.T) {
type FakeUserStore struct {
ExpectedUser *user.User
ExpectedSignedInUser *user.SignedInUser
ExpectedUserProfile *user.UserProfileDTO
ExpectedError error
ExpectedDeleteUserError error
}
@@ -190,3 +191,15 @@ func (f *FakeUserStore) GetSignedInUser(ctx context.Context, query *user.GetSign
func (f *FakeUserStore) UpdateUser(ctx context.Context, user *user.User) error {
return f.ExpectedError
}
func (f *FakeUserStore) GetProfile(ctx context.Context, query *user.GetUserProfileQuery) (*user.UserProfileDTO, error) {
return f.ExpectedUserProfile, f.ExpectedError
}
func (f *FakeUserStore) SetHelpFlag(ctx context.Context, cmd *user.SetUserHelpFlagCommand) error {
return f.ExpectedError
}
func (f *FakeUserStore) UpdatePermissions(ctx context.Context, userID int64, isAdmin bool) error {
return f.ExpectedError
}