chore: remove sqlstore & mockstore dependencies from (most) packages (#57087)
* chore: add alias for InitTestDB and Session Adds an alias for the sqlstore InitTestDB and Session, and updates tests using these to reduce dependencies on the sqlstore.Store. * next pass of removing sqlstore imports * last little bit * remove mockstore where possible
This commit is contained in:
@@ -8,10 +8,9 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
@@ -59,7 +58,7 @@ func ProvideStore(db db.DB, cfg *setting.Cfg) sqlStore {
|
||||
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 {
|
||||
err = ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
sess.UseBool("is_admin")
|
||||
|
||||
if userID, err = sess.Insert(cmd); err != nil {
|
||||
@@ -81,7 +80,7 @@ func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) {
|
||||
}
|
||||
|
||||
func (ss *sqlStore) Get(ctx context.Context, usr *user.User) (*user.User, error) {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
exists, err := sess.Where("email=? OR login=?", usr.Email, usr.Login).Get(usr)
|
||||
if !exists {
|
||||
return user.ErrUserNotFound
|
||||
@@ -98,7 +97,7 @@ func (ss *sqlStore) Get(ctx context.Context, usr *user.User) (*user.User, error)
|
||||
}
|
||||
|
||||
func (ss *sqlStore) Delete(ctx context.Context, userID int64) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
var rawSQL = "DELETE FROM " + ss.dialect.Quote("user") + " WHERE id = ?"
|
||||
_, err := sess.Exec(rawSQL, userID)
|
||||
return err
|
||||
@@ -111,7 +110,7 @@ func (ss *sqlStore) Delete(ctx context.Context, userID int64) error {
|
||||
|
||||
func (ss *sqlStore) GetNotServiceAccount(ctx context.Context, userID int64) (*user.User, error) {
|
||||
usr := user.User{ID: userID}
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
has, err := sess.Where(ss.notServiceAccountFilter()).Get(&usr)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -127,7 +126,7 @@ func (ss *sqlStore) GetNotServiceAccount(ctx context.Context, userID int64) (*us
|
||||
func (ss *sqlStore) GetByID(ctx context.Context, userID int64) (*user.User, error) {
|
||||
var usr user.User
|
||||
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
has, err := sess.ID(&userID).
|
||||
Where(ss.notServiceAccountFilter()).
|
||||
Get(&usr)
|
||||
@@ -150,7 +149,7 @@ func (ss *sqlStore) notServiceAccountFilter() string {
|
||||
|
||||
func (ss *sqlStore) CaseInsensitiveLoginConflict(ctx context.Context, login, email string) error {
|
||||
users := make([]user.User, 0)
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if err := sess.Where("LOWER(email)=LOWER(?) OR LOWER(login)=LOWER(?)",
|
||||
email, login).Find(&users); err != nil {
|
||||
return err
|
||||
@@ -166,7 +165,7 @@ func (ss *sqlStore) CaseInsensitiveLoginConflict(ctx context.Context, login, ema
|
||||
|
||||
func (ss *sqlStore) GetByLogin(ctx context.Context, query *user.GetUserByLoginQuery) (*user.User, error) {
|
||||
usr := &user.User{}
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if query.LoginOrEmail == "" {
|
||||
return user.ErrUserNotFound
|
||||
}
|
||||
@@ -216,7 +215,7 @@ func (ss *sqlStore) GetByLogin(ctx context.Context, query *user.GetUserByLoginQu
|
||||
|
||||
func (ss *sqlStore) GetByEmail(ctx context.Context, query *user.GetUserByEmailQuery) (*user.User, error) {
|
||||
usr := &user.User{}
|
||||
err := ss.db.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
if query.Email == "" {
|
||||
return user.ErrUserNotFound
|
||||
}
|
||||
@@ -247,7 +246,7 @@ func (ss *sqlStore) GetByEmail(ctx context.Context, query *user.GetUserByEmailQu
|
||||
return usr, nil
|
||||
}
|
||||
|
||||
func (ss *sqlStore) userCaseInsensitiveLoginConflict(ctx context.Context, sess *sqlstore.DBSession, login, email string) error {
|
||||
func (ss *sqlStore) userCaseInsensitiveLoginConflict(ctx context.Context, sess *db.Session, login, email string) error {
|
||||
users := make([]user.User, 0)
|
||||
|
||||
if err := sess.Where("LOWER(email)=LOWER(?) OR LOWER(login)=LOWER(?)",
|
||||
@@ -268,7 +267,7 @@ func (ss *sqlStore) Update(ctx context.Context, cmd *user.UpdateUserCommand) err
|
||||
cmd.Email = strings.ToLower(cmd.Email)
|
||||
}
|
||||
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
user := user.User{
|
||||
Name: cmd.Name,
|
||||
Email: cmd.Email,
|
||||
@@ -300,7 +299,7 @@ func (ss *sqlStore) Update(ctx context.Context, cmd *user.UpdateUserCommand) err
|
||||
}
|
||||
|
||||
func (ss *sqlStore) ChangePassword(ctx context.Context, cmd *user.ChangeUserPasswordCommand) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
user := user.User{
|
||||
Password: cmd.NewPassword,
|
||||
Updated: time.Now(),
|
||||
@@ -312,7 +311,7 @@ func (ss *sqlStore) ChangePassword(ctx context.Context, cmd *user.ChangeUserPass
|
||||
}
|
||||
|
||||
func (ss *sqlStore) UpdateLastSeenAt(ctx context.Context, cmd *user.UpdateUserLastSeenAtCommand) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
user := user.User{
|
||||
ID: cmd.UserID,
|
||||
LastSeenAt: time.Now(),
|
||||
@@ -325,7 +324,7 @@ func (ss *sqlStore) UpdateLastSeenAt(ctx context.Context, cmd *user.UpdateUserLa
|
||||
|
||||
func (ss *sqlStore) GetSignedInUser(ctx context.Context, query *user.GetSignedInUserQuery) (*user.SignedInUser, error) {
|
||||
var signedInUser user.SignedInUser
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error {
|
||||
orgId := "u.org_id"
|
||||
if query.OrgID > 0 {
|
||||
orgId = strconv.FormatInt(query.OrgID, 10)
|
||||
@@ -390,7 +389,7 @@ func (ss *sqlStore) GetSignedInUser(ctx context.Context, query *user.GetSignedIn
|
||||
}
|
||||
|
||||
func (ss *sqlStore) UpdateUser(ctx context.Context, user *user.User) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
_, err := sess.ID(user.ID).Update(user)
|
||||
return err
|
||||
})
|
||||
@@ -399,7 +398,7 @@ func (ss *sqlStore) UpdateUser(ctx context.Context, user *user.User) error {
|
||||
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 {
|
||||
err := ss.db.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
has, err := sess.ID(query.UserID).Where(ss.notServiceAccountFilter()).Get(&usr)
|
||||
|
||||
if err != nil {
|
||||
@@ -427,11 +426,11 @@ func (ss *sqlStore) GetProfile(ctx context.Context, query *user.GetUserProfileQu
|
||||
}
|
||||
|
||||
func (ss *sqlStore) SetHelpFlag(ctx context.Context, cmd *user.SetUserHelpFlagCommand) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
user := user.User{
|
||||
ID: cmd.UserID,
|
||||
HelpFlags1: cmd.HelpFlags1,
|
||||
Updated: sqlstore.TimeNow(),
|
||||
Updated: time.Now(),
|
||||
}
|
||||
|
||||
_, err := sess.ID(cmd.UserID).Cols("help_flags1").Update(&user)
|
||||
@@ -441,7 +440,7 @@ func (ss *sqlStore) SetHelpFlag(ctx context.Context, cmd *user.SetUserHelpFlagCo
|
||||
|
||||
// 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 {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
var user user.User
|
||||
if _, err := sess.ID(userID).Where(ss.notServiceAccountFilter()).Get(&user); err != nil {
|
||||
return err
|
||||
@@ -462,7 +461,7 @@ func (ss *sqlStore) UpdatePermissions(ctx context.Context, userID int64, isAdmin
|
||||
}
|
||||
|
||||
// validateOneAdminLeft validate that there is an admin user left
|
||||
func validateOneAdminLeft(ctx context.Context, sess *sqlstore.DBSession) error {
|
||||
func validateOneAdminLeft(ctx context.Context, sess *db.Session) error {
|
||||
count, err := sess.Where("is_admin=?", true).Count(&user.User{})
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -476,7 +475,7 @@ func validateOneAdminLeft(ctx context.Context, sess *sqlstore.DBSession) error {
|
||||
}
|
||||
|
||||
func (ss *sqlStore) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisableUsersCommand) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
|
||||
return ss.db.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
userIds := cmd.UserIDs
|
||||
|
||||
if len(userIds) == 0 {
|
||||
@@ -497,7 +496,7 @@ func (ss *sqlStore) BatchDisableUsers(ctx context.Context, cmd *user.BatchDisabl
|
||||
}
|
||||
|
||||
func (ss *sqlStore) Disable(ctx context.Context, cmd *user.DisableUserCommand) error {
|
||||
return ss.db.WithDbSession(ctx, func(dbSess *sqlstore.DBSession) error {
|
||||
return ss.db.WithDbSession(ctx, func(dbSess *db.Session) error {
|
||||
usr := user.User{}
|
||||
sess := dbSess.Table("user")
|
||||
|
||||
@@ -519,7 +518,7 @@ func (ss *sqlStore) Search(ctx context.Context, query *user.SearchUsersQuery) (*
|
||||
result := user.SearchUserQueryResult{
|
||||
Users: make([]*user.UserSearchHitDTO, 0),
|
||||
}
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error {
|
||||
queryWithWildcards := "%" + query.Query + "%"
|
||||
|
||||
whereConditions := make([]string, 0)
|
||||
|
||||
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@@ -23,7 +24,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ss := sqlstore.InitTestDB(t)
|
||||
ss := db.InitTestDB(t)
|
||||
userStore := ProvideStore(ss, setting.NewCfg())
|
||||
usr := &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
@@ -66,7 +67,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Testing DB - creates and loads user", func(t *testing.T) {
|
||||
ss := sqlstore.InitTestDB(t)
|
||||
ss := db.InitTestDB(t)
|
||||
cmd := user.CreateUserCommand{
|
||||
Email: "usertest@test.com",
|
||||
Name: "user name",
|
||||
@@ -253,7 +254,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Testing DB - grafana admin users", func(t *testing.T) {
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
|
||||
createUserCmd := user.CreateUserCommand{
|
||||
Email: fmt.Sprint("admin", "@test.com"),
|
||||
@@ -318,7 +319,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Testing DB - return list users based on their is_disabled flag", func(t *testing.T) {
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
return &user.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
@@ -350,7 +351,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
require.True(t, third)
|
||||
|
||||
// Re-init DB
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
return &user.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
@@ -390,7 +391,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
|
||||
// A user is an org member and has been assigned permissions
|
||||
// Re-init DB
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
users = createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
return &user.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
@@ -463,7 +464,7 @@ 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 := sqlstore.InitTestDB(t)
|
||||
ss := db.InitTestDB(t)
|
||||
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
return &user.CreateUserCommand{
|
||||
Email: fmt.Sprint("user", i, "@test.com"),
|
||||
@@ -482,7 +483,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
assert.Len(t, queryResult.Users, 2)
|
||||
})
|
||||
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
|
||||
t.Run("Testing DB - enable all users", func(t *testing.T) {
|
||||
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
@@ -511,7 +512,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Can search users", func(t *testing.T) {
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
userStore.cfg.AutoAssignOrg = false
|
||||
|
||||
ac1cmd := user.CreateUserCommand{Login: "ac1", Email: "ac1@test.com", Name: "ac1 name"}
|
||||
@@ -538,7 +539,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
require.Equal(t, queryResult.Users[1].Email, "ac2@test.com")
|
||||
})
|
||||
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
|
||||
t.Run("Testing DB - disable only specific users", func(t *testing.T) {
|
||||
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
@@ -585,7 +586,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
}
|
||||
})
|
||||
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
|
||||
t.Run("Testing DB - search users", func(t *testing.T) {
|
||||
// Since previous tests were destructive
|
||||
@@ -611,7 +612,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
})
|
||||
|
||||
t.Run("Testing DB - multiple users", func(t *testing.T) {
|
||||
ss = sqlstore.InitTestDB(t)
|
||||
ss = db.InitTestDB(t)
|
||||
|
||||
createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
return &user.CreateUserCommand{
|
||||
@@ -690,7 +691,7 @@ func TestIntegrationUserUpdate(t *testing.T) {
|
||||
t.Skip("skipping integration test")
|
||||
}
|
||||
|
||||
ss := sqlstore.InitTestDB(t)
|
||||
ss := db.InitTestDB(t)
|
||||
userStore := ProvideStore(ss, setting.NewCfg())
|
||||
|
||||
users := createFiveTestUsers(t, ss, func(i int) *user.CreateUserCommand {
|
||||
@@ -769,10 +770,10 @@ func createFiveTestUsers(t *testing.T, sqlStore *sqlstore.SQLStore, fn func(i in
|
||||
}
|
||||
|
||||
// TODO: Use FakeDashboardStore when org has its own service
|
||||
func updateDashboardACL(t *testing.T, sqlStore *sqlstore.SQLStore, dashboardID int64, items ...*models.DashboardACL) error {
|
||||
func updateDashboardACL(t *testing.T, sqlStore db.DB, dashboardID int64, items ...*models.DashboardACL) error {
|
||||
t.Helper()
|
||||
|
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
|
||||
err := sqlStore.WithDbSession(context.Background(), func(sess *db.Session) error {
|
||||
_, err := sess.Exec("DELETE FROM dashboard_acl WHERE dashboard_id=?", dashboardID)
|
||||
if err != nil {
|
||||
return fmt.Errorf("deleting from dashboard_acl failed: %w", err)
|
||||
@@ -805,7 +806,7 @@ func updateDashboardACL(t *testing.T, sqlStore *sqlstore.SQLStore, dashboardID i
|
||||
|
||||
func (ss *sqlStore) getOrgUsersForTest(ctx context.Context, query *org.GetOrgUsersQuery) ([]*org.OrgUserDTO, error) {
|
||||
result := make([]*org.OrgUserDTO, 0)
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *sqlstore.DBSession) error {
|
||||
err := ss.db.WithDbSession(ctx, func(dbSess *db.Session) error {
|
||||
sess := dbSess.Table("org_user")
|
||||
sess.Join("LEFT ", ss.dialect.Quote("user"), fmt.Sprintf("org_user.user_id=%s.id", ss.dialect.Quote("user")))
|
||||
sess.Where("org_user.org_id=?", query.OrgID)
|
||||
@@ -821,7 +822,7 @@ func (ss *sqlStore) getOrgUsersForTest(ctx context.Context, query *org.GetOrgUse
|
||||
// import cycles. When this org-related code is refactored into a service the
|
||||
// tests can the real GetDashboardACLInfoList functions
|
||||
func (ss *sqlStore) getDashboardACLInfoList(query *models.GetDashboardACLInfoListQuery) error {
|
||||
outerErr := ss.db.WithDbSession(context.Background(), func(dbSession *sqlstore.DBSession) error {
|
||||
outerErr := ss.db.WithDbSession(context.Background(), func(dbSession *db.Session) error {
|
||||
query.Result = make([]*models.DashboardACLInfoDTO, 0)
|
||||
falseStr := ss.dialect.BooleanStr(false)
|
||||
|
||||
|
||||
@@ -6,11 +6,11 @@ import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/infra/localcache"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||
"github.com/grafana/grafana/pkg/services/team"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
Reference in New Issue
Block a user