mirror of
https://github.com/grafana/grafana.git
synced 2026-08-11 13:44:59 -05:00
UserService: use the UserService instead of calling sqlstore directly (#55745)
* UserService: update callers to use the UserService instead of calling sqlstore directly There is one major change hiding in this PR. UserService.Delete originally called a number of services to delete user-related records. I moved everything except the actual call to the user table, and moved those into the API. This was done to avoid dependencies cycles; many of our services depend on the user service, so the user service itself should have as few dependencies as possible.
This commit is contained in:
@@ -5,10 +5,12 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/events"
|
||||
"github.com/grafana/grafana/pkg/infra/log"
|
||||
"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"
|
||||
)
|
||||
|
||||
type store interface {
|
||||
@@ -23,6 +25,17 @@ type store interface {
|
||||
type sqlStore struct {
|
||||
db db.DB
|
||||
dialect migrator.Dialect
|
||||
logger log.Logger
|
||||
cfg *setting.Cfg
|
||||
}
|
||||
|
||||
func ProvideStore(db db.DB, cfg *setting.Cfg) sqlStore {
|
||||
return sqlStore{
|
||||
db: db,
|
||||
dialect: db.GetDialect(),
|
||||
cfg: cfg,
|
||||
logger: log.New("user.store"),
|
||||
}
|
||||
}
|
||||
|
||||
func (ss *sqlStore) Insert(ctx context.Context, cmd *user.User) (int64, error) {
|
||||
|
||||
@@ -5,10 +5,11 @@ import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
@@ -17,7 +18,7 @@ func TestIntegrationUserDataAccess(t *testing.T) {
|
||||
}
|
||||
|
||||
ss := sqlstore.InitTestDB(t)
|
||||
userStore := sqlStore{db: ss}
|
||||
userStore := ProvideStore(ss, setting.NewCfg())
|
||||
|
||||
t.Run("user not found", func(t *testing.T) {
|
||||
_, err := userStore.Get(context.Background(),
|
||||
|
||||
@@ -6,67 +6,34 @@ import (
|
||||
"time"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
pref "github.com/grafana/grafana/pkg/services/preference"
|
||||
"github.com/grafana/grafana/pkg/services/quota"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/db"
|
||||
"github.com/grafana/grafana/pkg/services/star"
|
||||
"github.com/grafana/grafana/pkg/services/teamguardian"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/services/userauth"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
"github.com/grafana/grafana/pkg/util"
|
||||
|
||||
"golang.org/x/sync/errgroup"
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
store store
|
||||
orgService org.Service
|
||||
starService star.Service
|
||||
dashboardService dashboards.DashboardService
|
||||
preferenceService pref.Service
|
||||
teamMemberService teamguardian.TeamGuardian
|
||||
userAuthService userauth.Service
|
||||
quotaService quota.Service
|
||||
accessControlStore accesscontrol.Service
|
||||
store store
|
||||
orgService org.Service
|
||||
// TODO remove sqlstore
|
||||
sqlStore *sqlstore.SQLStore
|
||||
|
||||
cfg *setting.Cfg
|
||||
cfg *setting.Cfg
|
||||
}
|
||||
|
||||
func ProvideService(
|
||||
db db.DB,
|
||||
orgService org.Service,
|
||||
starService star.Service,
|
||||
dashboardService dashboards.DashboardService,
|
||||
preferenceService pref.Service,
|
||||
teamMemberService teamguardian.TeamGuardian,
|
||||
userAuthService userauth.Service,
|
||||
quotaService quota.Service,
|
||||
accessControlStore accesscontrol.Service,
|
||||
cfg *setting.Cfg,
|
||||
ss *sqlstore.SQLStore,
|
||||
) user.Service {
|
||||
store := ProvideStore(db, cfg)
|
||||
return &Service{
|
||||
store: &sqlStore{
|
||||
db: db,
|
||||
dialect: db.GetDialect(),
|
||||
},
|
||||
orgService: orgService,
|
||||
starService: starService,
|
||||
dashboardService: dashboardService,
|
||||
preferenceService: preferenceService,
|
||||
teamMemberService: teamMemberService,
|
||||
userAuthService: userAuthService,
|
||||
quotaService: quotaService,
|
||||
accessControlStore: accessControlStore,
|
||||
cfg: cfg,
|
||||
sqlStore: ss,
|
||||
store: &store,
|
||||
orgService: orgService,
|
||||
cfg: cfg,
|
||||
sqlStore: ss,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -169,70 +136,7 @@ func (s *Service) Delete(ctx context.Context, cmd *user.DeleteUserCommand) error
|
||||
return err
|
||||
}
|
||||
// delete from all the stores
|
||||
if err := s.store.Delete(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
g, ctx := errgroup.WithContext(ctx)
|
||||
g.Go(func() error {
|
||||
if err := s.starService.DeleteByUser(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.orgService.DeleteUserFromAll(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.dashboardService.DeleteACLByUser(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.preferenceService.DeleteByUser(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.teamMemberService.DeleteByUser(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.userAuthService.Delete(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.userAuthService.DeleteToken(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.quotaService.DeleteByUser(ctx, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
g.Go(func() error {
|
||||
if err := s.accessControlStore.DeleteUserPermissions(ctx, accesscontrol.GlobalOrgID, cmd.UserID); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if err := g.Wait(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
return s.store.Delete(ctx, cmd.UserID)
|
||||
}
|
||||
|
||||
func (s *Service) GetByID(ctx context.Context, query *user.GetUserByIDQuery) (*user.User, error) {
|
||||
@@ -331,10 +235,7 @@ func (s *Service) GetSignedInUser(ctx context.Context, query *user.GetSignedInUs
|
||||
OrgId: query.OrgID,
|
||||
}
|
||||
err := s.sqlStore.GetSignedInUser(ctx, q)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return q.Result, nil
|
||||
return q.Result, err
|
||||
}
|
||||
|
||||
// TODO: remove wrapper around sqlstore
|
||||
|
||||
@@ -2,18 +2,10 @@ package userimpl
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||
"github.com/grafana/grafana/pkg/services/dashboards"
|
||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||
"github.com/grafana/grafana/pkg/services/preference/preftest"
|
||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||
"github.com/grafana/grafana/pkg/services/star/startest"
|
||||
"github.com/grafana/grafana/pkg/services/teamguardian/manager"
|
||||
"github.com/grafana/grafana/pkg/services/user"
|
||||
"github.com/grafana/grafana/pkg/services/userauth/userauthtest"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
@@ -22,23 +14,9 @@ import (
|
||||
func TestUserService(t *testing.T) {
|
||||
userStore := newUserStoreFake()
|
||||
orgService := orgtest.NewOrgServiceFake()
|
||||
starService := startest.NewStarServiceFake()
|
||||
dashboardService := dashboards.NewFakeDashboardService(t)
|
||||
preferenceService := preftest.NewPreferenceServiceFake()
|
||||
teamMemberService := manager.NewTeamGuardianMock()
|
||||
userAuthService := userauthtest.NewFakeUserAuthService()
|
||||
quotaService := quotatest.NewQuotaServiceFake()
|
||||
accessControlStore := mock.New()
|
||||
userService := Service{
|
||||
store: userStore,
|
||||
orgService: orgService,
|
||||
starService: starService,
|
||||
dashboardService: dashboardService,
|
||||
preferenceService: preferenceService,
|
||||
teamMemberService: teamMemberService,
|
||||
userAuthService: userAuthService,
|
||||
quotaService: quotaService,
|
||||
accessControlStore: accessControlStore,
|
||||
store: userStore,
|
||||
orgService: orgService,
|
||||
}
|
||||
|
||||
t.Run("create user", func(t *testing.T) {
|
||||
@@ -81,26 +59,6 @@ func TestUserService(t *testing.T) {
|
||||
require.Error(t, err, user.ErrUserNotFound)
|
||||
})
|
||||
|
||||
t.Run("delete user returns from team", func(t *testing.T) {
|
||||
teamMemberService.ExpectedError = errors.New("some error")
|
||||
t.Cleanup(func() {
|
||||
teamMemberService.ExpectedError = nil
|
||||
})
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("delete user returns from team and pref", func(t *testing.T) {
|
||||
teamMemberService.ExpectedError = errors.New("some error")
|
||||
preferenceService.ExpectedError = errors.New("some error 2")
|
||||
t.Cleanup(func() {
|
||||
teamMemberService.ExpectedError = nil
|
||||
preferenceService.ExpectedError = nil
|
||||
})
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("delete user successfully", func(t *testing.T) {
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.NoError(t, err)
|
||||
@@ -115,26 +73,6 @@ func TestUserService(t *testing.T) {
|
||||
require.Error(t, err, user.ErrUserNotFound)
|
||||
})
|
||||
|
||||
t.Run("delete user returns from team", func(t *testing.T) {
|
||||
teamMemberService.ExpectedError = errors.New("some error")
|
||||
t.Cleanup(func() {
|
||||
teamMemberService.ExpectedError = nil
|
||||
})
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("delete user returns from team and pref", func(t *testing.T) {
|
||||
teamMemberService.ExpectedError = errors.New("some error")
|
||||
preferenceService.ExpectedError = errors.New("some error 2")
|
||||
t.Cleanup(func() {
|
||||
teamMemberService.ExpectedError = nil
|
||||
preferenceService.ExpectedError = nil
|
||||
})
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.Error(t, err)
|
||||
})
|
||||
|
||||
t.Run("delete user successfully", func(t *testing.T) {
|
||||
err := userService.Delete(context.Background(), &user.DeleteUserCommand{UserID: 1})
|
||||
require.NoError(t, err)
|
||||
|
||||
Reference in New Issue
Block a user