AuthService: Move database logic to its own class and package (#44835)

* Move database logic to its own class and package

* Fix lint
This commit is contained in:
Selene 2022-02-03 18:23:45 +01:00 committed by GitHub
parent 9b3cb4a306
commit 3ce0730558
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 149 additions and 111 deletions

View File

@ -44,7 +44,6 @@ import (
"github.com/grafana/grafana/pkg/services/live"
"github.com/grafana/grafana/pkg/services/live/pushhttp"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
"github.com/grafana/grafana/pkg/services/ngalert"
"github.com/grafana/grafana/pkg/services/notifications"
"github.com/grafana/grafana/pkg/services/provisioning"
@ -128,7 +127,7 @@ type HTTPServer struct {
teamGuardian teamguardian.TeamGuardian
queryDataService *query.Service
serviceAccountsService serviceaccounts.Service
authInfoService authinfoservice.Service
authInfoService login.AuthInfoService
TeamPermissionsService *resourcepermissions.Service
NotificationService *notifications.NotificationService
}
@ -157,7 +156,7 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
pluginsUpdateChecker *updatechecker.PluginsService, searchUsersService searchusers.Service,
dataSourcesService *datasources.Service, secretsService secrets.Service, queryDataService *query.Service,
ldapGroups ldap.Groups, teamGuardian teamguardian.TeamGuardian, serviceaccountsService serviceaccounts.Service,
authInfoService authinfoservice.Service, resourcePermissionServices *resourceservices.ResourceServices,
authInfoService login.AuthInfoService, resourcePermissionServices *resourceservices.ResourceServices,
notificationService *notifications.NotificationService) (*HTTPServer, error) {
web.Env = cfg.Env
m := web.New()

View File

@ -10,6 +10,7 @@ import (
"github.com/grafana/grafana/pkg/api/dtos"
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
authinfostore "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
"github.com/grafana/grafana/pkg/services/searchusers/filters"
"github.com/grafana/grafana/pkg/services/secrets/database"
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
@ -46,7 +47,8 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
loggedInUserScenario(t, "When calling GET on", "api/users/1", "api/users/:id", func(sc *scenarioContext) {
fakeNow := time.Date(2019, 2, 11, 17, 30, 40, 0, time.UTC)
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
srv := authinfoservice.ProvideAuthInfoService(bus.New(), sqlStore, &authinfoservice.OSSUserProtectionImpl{}, secretsService)
authInfoStore := authinfostore.ProvideAuthInfoStore(sqlStore, bus.New(), secretsService)
srv := authinfoservice.ProvideAuthInfoService(&authinfoservice.OSSUserProtectionImpl{}, authInfoStore)
hs.authInfoService = srv
createUserCmd := models.CreateUserCommand{

View File

@ -45,6 +45,7 @@ import (
"github.com/grafana/grafana/pkg/services/live/pushhttp"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
authinfodatabase "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
"github.com/grafana/grafana/pkg/services/login/loginservice"
"github.com/grafana/grafana/pkg/services/ngalert"
ngmetrics "github.com/grafana/grafana/pkg/services/ngalert/metrics"
@ -144,6 +145,8 @@ var wireBasicSet = wire.NewSet(
wire.Bind(new(login.Service), new(*loginservice.Implementation)),
authinfoservice.ProvideAuthInfoService,
wire.Bind(new(login.AuthInfoService), new(*authinfoservice.Implementation)),
authinfodatabase.ProvideAuthInfoStore,
wire.Bind(new(login.Store), new(*authinfodatabase.AuthInfoStore)),
datasourceproxy.ProvideService,
search.ProvideService,
live.ProvideService,
@ -190,7 +193,6 @@ var wireBasicSet = wire.NewSet(
wire.Bind(new(teamguardian.Store), new(*teamguardianDatabase.TeamGuardianStoreImpl)),
teamguardianManager.ProvideService,
wire.Bind(new(teamguardian.TeamGuardian), new(*teamguardianManager.Service)),
wire.Bind(new(authinfoservice.Service), new(*authinfoservice.Implementation)),
featuremgmt.ProvideManagerService,
featuremgmt.ProvideToggles,
resourceservices.ProvideResourceServices,

View File

@ -8,4 +8,5 @@ import (
type AuthInfoService interface {
LookupAndUpdate(ctx context.Context, query *models.GetUserByAuthInfoQuery) (*models.User, error)
GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error
}

View File

@ -1,27 +1,54 @@
package authinfoservice
package database
import (
"context"
"encoding/base64"
"time"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"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/models"
)
var getTime = time.Now
var GetTime = time.Now
func (s *Implementation) GetExternalUserInfoByLogin(ctx context.Context, query *models.GetExternalUserInfoByLoginQuery) error {
type AuthInfoStore struct {
sqlStore sqlstore.Store
bus bus.Bus
secretsService secrets.Service
logger log.Logger
}
func ProvideAuthInfoStore(sqlStore sqlstore.Store, bus bus.Bus, secretsService secrets.Service) *AuthInfoStore {
store := &AuthInfoStore{
sqlStore: sqlStore,
bus: bus,
secretsService: secretsService,
logger: log.New("login.authinfo.store"),
}
store.registerBusHandlers()
return store
}
func (s *AuthInfoStore) registerBusHandlers() {
s.bus.AddHandler(s.GetExternalUserInfoByLogin)
s.bus.AddHandler(s.GetAuthInfo)
s.bus.AddHandler(s.SetAuthInfo)
s.bus.AddHandler(s.UpdateAuthInfo)
s.bus.AddHandler(s.DeleteAuthInfo)
}
func (s *AuthInfoStore) GetExternalUserInfoByLogin(ctx context.Context, query *models.GetExternalUserInfoByLoginQuery) error {
userQuery := models.GetUserByLoginQuery{LoginOrEmail: query.LoginOrEmail}
err := s.Bus.Dispatch(ctx, &userQuery)
err := s.bus.Dispatch(ctx, &userQuery)
if err != nil {
return err
}
authInfoQuery := &models.GetAuthInfoQuery{UserId: userQuery.Result.Id}
if err := s.Bus.Dispatch(ctx, authInfoQuery); err != nil {
if err := s.bus.Dispatch(ctx, authInfoQuery); err != nil {
return err
}
@ -37,7 +64,7 @@ func (s *Implementation) GetExternalUserInfoByLogin(ctx context.Context, query *
return nil
}
func (s *Implementation) GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error {
func (s *AuthInfoStore) GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error {
if query.UserId == 0 && query.AuthId == "" {
return models.ErrUserNotFound
}
@ -51,7 +78,7 @@ func (s *Implementation) GetAuthInfo(ctx context.Context, query *models.GetAuthI
var has bool
var err error
err = s.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
err = s.sqlStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
has, err = sess.Desc("created").Get(userAuth)
return err
})
@ -88,12 +115,12 @@ func (s *Implementation) GetAuthInfo(ctx context.Context, query *models.GetAuthI
return nil
}
func (s *Implementation) SetAuthInfo(ctx context.Context, cmd *models.SetAuthInfoCommand) error {
func (s *AuthInfoStore) SetAuthInfo(ctx context.Context, cmd *models.SetAuthInfoCommand) error {
authUser := &models.UserAuth{
UserId: cmd.UserId,
AuthModule: cmd.AuthModule,
AuthId: cmd.AuthId,
Created: getTime(),
Created: GetTime(),
}
if cmd.OAuthToken != nil {
@ -125,18 +152,18 @@ func (s *Implementation) SetAuthInfo(ctx context.Context, cmd *models.SetAuthInf
authUser.OAuthExpiry = cmd.OAuthToken.Expiry
}
return s.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
return s.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Insert(authUser)
return err
})
}
func (s *Implementation) UpdateAuthInfo(ctx context.Context, cmd *models.UpdateAuthInfoCommand) error {
func (s *AuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *models.UpdateAuthInfoCommand) error {
authUser := &models.UserAuth{
UserId: cmd.UserId,
AuthModule: cmd.AuthModule,
AuthId: cmd.AuthId,
Created: getTime(),
Created: GetTime(),
}
if cmd.OAuthToken != nil {
@ -173,22 +200,51 @@ func (s *Implementation) UpdateAuthInfo(ctx context.Context, cmd *models.UpdateA
AuthModule: cmd.AuthModule,
}
return s.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
return s.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
upd, err := sess.Update(authUser, cond)
s.logger.Debug("Updated user_auth", "user_id", cmd.UserId, "auth_module", cmd.AuthModule, "rows", upd)
return err
})
}
func (s *Implementation) DeleteAuthInfo(ctx context.Context, cmd *models.DeleteAuthInfoCommand) error {
return s.SQLStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
func (s *AuthInfoStore) DeleteAuthInfo(ctx context.Context, cmd *models.DeleteAuthInfoCommand) error {
return s.sqlStore.WithTransactionalDbSession(ctx, func(sess *sqlstore.DBSession) error {
_, err := sess.Delete(cmd.UserAuth)
return err
})
}
func (s *AuthInfoStore) GetUserById(id int64) (bool, *models.User, error) {
var (
has bool
err error
)
user := &models.User{}
err = s.sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
has, err = sess.ID(id).Get(user)
return err
})
if err != nil {
return false, nil, err
}
return has, user, nil
}
func (s *AuthInfoStore) GetUser(user *models.User) (bool, error) {
var err error
var has bool
err = s.sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
has, err = sess.Get(user)
return err
})
return has, err
}
// decodeAndDecrypt will decode the string with the standard base64 decoder and then decrypt it
func (s *Implementation) decodeAndDecrypt(str string) (string, error) {
func (s *AuthInfoStore) decodeAndDecrypt(str string) (string, error) {
// Bail out if empty string since it'll cause a segfault in Decrypt
if str == "" {
return "", nil
@ -197,7 +253,7 @@ func (s *Implementation) decodeAndDecrypt(str string) (string, error) {
if err != nil {
return "", err
}
decrypted, err := s.SecretsService.Decrypt(context.Background(), decoded)
decrypted, err := s.secretsService.Decrypt(context.Background(), decoded)
if err != nil {
return "", err
}
@ -206,8 +262,8 @@ func (s *Implementation) decodeAndDecrypt(str string) (string, error) {
// encryptAndEncode will encrypt a string with grafana's secretKey, and
// then encode it with the standard bas64 encoder
func (s *Implementation) encryptAndEncode(str string) (string, error) {
encrypted, err := s.SecretsService.Encrypt(context.Background(), []byte(str), secrets.WithoutScope())
func (s *AuthInfoStore) encryptAndEncode(str string) (string, error) {
encrypted, err := s.secretsService.Encrypt(context.Background(), []byte(str), secrets.WithoutScope())
if err != nil {
return "", err
}

View File

@ -4,76 +4,29 @@ import (
"context"
"errors"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/login"
"github.com/grafana/grafana/pkg/services/secrets"
"github.com/grafana/grafana/pkg/services/sqlstore"
)
const genericOAuthModule = "oauth_generic_oauth"
type Implementation struct {
Bus bus.Bus
SQLStore *sqlstore.SQLStore
UserProtectionService login.UserProtectionService
SecretsService secrets.Service
authInfoStore login.Store
logger log.Logger
}
type Service interface {
GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error
}
func ProvideAuthInfoService(bus bus.Bus, store *sqlstore.SQLStore, userProtectionService login.UserProtectionService,
secretsService secrets.Service) *Implementation {
func ProvideAuthInfoService(userProtectionService login.UserProtectionService, authInfoStore login.Store) *Implementation {
s := &Implementation{
Bus: bus,
SQLStore: store,
UserProtectionService: userProtectionService,
SecretsService: secretsService,
authInfoStore: authInfoStore,
logger: log.New("login.authinfo"),
}
s.Bus.AddHandler(s.GetExternalUserInfoByLogin)
s.Bus.AddHandler(s.GetAuthInfo)
s.Bus.AddHandler(s.SetAuthInfo)
s.Bus.AddHandler(s.UpdateAuthInfo)
s.Bus.AddHandler(s.DeleteAuthInfo)
return s
}
func (s *Implementation) getUserById(id int64) (bool, *models.User, error) {
var (
has bool
err error
)
user := &models.User{}
err = s.SQLStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
has, err = sess.ID(id).Get(user)
return err
})
if err != nil {
return false, nil, err
}
return has, user, nil
}
func (s *Implementation) getUser(user *models.User) (bool, error) {
var err error
var has bool
err = s.SQLStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
has, err = sess.Get(user)
return err
})
return has, err
}
func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUserByAuthInfoQuery) (bool, *models.User, *models.UserAuth, error) {
authQuery := &models.GetAuthInfoQuery{}
@ -82,7 +35,7 @@ func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUser
authQuery.AuthModule = query.AuthModule
authQuery.AuthId = query.AuthId
err := s.GetAuthInfo(ctx, authQuery)
err := s.authInfoStore.GetAuthInfo(ctx, authQuery)
if !errors.Is(err, models.ErrUserNotFound) {
if err != nil {
return false, nil, nil, err
@ -90,7 +43,7 @@ func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUser
// if user id was specified and doesn't match the user_auth entry, remove it
if query.UserId != 0 && query.UserId != authQuery.Result.UserId {
err := s.DeleteAuthInfo(ctx, &models.DeleteAuthInfoCommand{
err := s.authInfoStore.DeleteAuthInfo(ctx, &models.DeleteAuthInfoCommand{
UserAuth: authQuery.Result,
})
if err != nil {
@ -99,14 +52,14 @@ func (s *Implementation) LookupAndFix(ctx context.Context, query *models.GetUser
return false, nil, nil, models.ErrUserNotFound
} else {
has, user, err := s.getUserById(authQuery.Result.UserId)
has, user, err := s.authInfoStore.GetUserById(authQuery.Result.UserId)
if err != nil {
return false, nil, nil, err
}
if !has {
// if the user has been deleted then remove the entry
err = s.DeleteAuthInfo(ctx, &models.DeleteAuthInfoCommand{
err = s.authInfoStore.DeleteAuthInfo(ctx, &models.DeleteAuthInfoCommand{
UserAuth: authQuery.Result,
})
if err != nil {
@ -131,7 +84,7 @@ func (s *Implementation) LookupByOneOf(userId int64, email string, login string)
// If not found, try to find the user by id
if userId != 0 {
foundUser, user, err = s.getUserById(userId)
foundUser, user, err = s.authInfoStore.GetUserById(userId)
if err != nil {
return false, nil, err
}
@ -140,7 +93,7 @@ func (s *Implementation) LookupByOneOf(userId int64, email string, login string)
// If not found, try to find the user by email address
if !foundUser && email != "" {
user = &models.User{Email: email}
foundUser, err = s.getUser(user)
foundUser, err = s.authInfoStore.GetUser(user)
if err != nil {
return false, nil, err
}
@ -149,7 +102,7 @@ func (s *Implementation) LookupByOneOf(userId int64, email string, login string)
// If not found, try to find the user by login
if !foundUser && login != "" {
user = &models.User{Login: login}
foundUser, err = s.getUser(user)
foundUser, err = s.authInfoStore.GetUser(user)
if err != nil {
return false, nil, err
}
@ -168,7 +121,7 @@ func (s *Implementation) GenericOAuthLookup(ctx context.Context, authModule stri
authQuery.AuthModule = authModule
authQuery.AuthId = authId
authQuery.UserId = userID
err := s.GetAuthInfo(ctx, authQuery)
err := s.authInfoStore.GetAuthInfo(ctx, authQuery)
if err != nil {
return nil, err
}
@ -215,10 +168,18 @@ func (s *Implementation) LookupAndUpdate(ctx context.Context, query *models.GetU
AuthModule: query.AuthModule,
AuthId: query.AuthId,
}
if err := s.SetAuthInfo(ctx, cmd); err != nil {
if err := s.authInfoStore.SetAuthInfo(ctx, cmd); err != nil {
return nil, err
}
}
return user, nil
}
func (s *Implementation) GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error {
return s.authInfoStore.GetAuthInfo(ctx, query)
}
func (s *Implementation) UpdateAuthInfo(ctx context.Context, cmd *models.UpdateAuthInfoCommand) error {
return s.authInfoStore.UpdateAuthInfo(ctx, cmd)
}

View File

@ -1,6 +1,3 @@
//go:build integration
// +build integration
package authinfoservice
import (
@ -11,7 +8,8 @@ import (
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/secrets/database"
"github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
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/stretchr/testify/require"
@ -21,8 +19,9 @@ import (
//nolint:goconst
func TestUserAuth(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t)
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
srv := ProvideAuthInfoService(bus.New(), sqlStore, &OSSUserProtectionImpl{}, secretsService)
secretsService := secretsManager.SetupTestService(t, secretstore.ProvideSecretsStore(sqlStore))
authInfoStore := database.ProvideAuthInfoStore(sqlStore, bus.New(), secretsService)
srv := ProvideAuthInfoService(&OSSUserProtectionImpl{}, authInfoStore)
t.Run("Given 5 users", func(t *testing.T) {
for i := 0; i < 5; i++ {
@ -31,7 +30,7 @@ func TestUserAuth(t *testing.T) {
Name: fmt.Sprint("user", i),
Login: fmt.Sprint("loginuser", i),
}
_, err := srv.SQLStore.CreateUser(context.Background(), cmd)
_, err := sqlStore.CreateUser(context.Background(), cmd)
require.Nil(t, err)
}
@ -111,12 +110,11 @@ func TestUserAuth(t *testing.T) {
require.Equal(t, user.Login, "loginuser1")
// remove user
srv.SQLStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
sess.Exec("DELETE FROM "+srv.SQLStore.Dialect.Quote("user")+" WHERE id=?", user.Id)
require.NoError(t, err)
return nil
err = sqlStore.WithDbSession(context.Background(), func(sess *sqlstore.DBSession) error {
_, err := sess.Exec("DELETE FROM "+sqlStore.Dialect.Quote("user")+" WHERE id=?", user.Id)
return err
})
require.NoError(t, err)
// get via user_auth for deleted user
query = &models.GetUserByAuthInfoQuery{AuthModule: "test", AuthId: "test"}
@ -152,7 +150,7 @@ func TestUserAuth(t *testing.T) {
AuthModule: query.AuthModule,
OAuthToken: token,
}
err = srv.UpdateAuthInfo(context.Background(), cmd)
err = srv.authInfoStore.UpdateAuthInfo(context.Background(), cmd)
require.Nil(t, err)
@ -160,7 +158,7 @@ func TestUserAuth(t *testing.T) {
UserId: user.Id,
}
err = srv.GetAuthInfo(context.Background(), getAuthQuery)
err = srv.authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
require.Nil(t, err)
require.Equal(t, token.AccessToken, getAuthQuery.Result.OAuthAccessToken)
@ -188,20 +186,20 @@ func TestUserAuth(t *testing.T) {
// Calling srv.LookupAndUpdateQuery on an existing user will populate an entry in the user_auth table
// Make the first log-in during the past
getTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
database.GetTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
query := &models.GetUserByAuthInfoQuery{Login: login, AuthModule: "test1", AuthId: "test1"}
user, err := srv.LookupAndUpdate(context.Background(), query)
getTime = time.Now
database.GetTime = time.Now
require.Nil(t, err)
require.Equal(t, user.Login, login)
// Add a second auth module for this user
// Have this module's last log-in be more recent
getTime = func() time.Time { return time.Now().AddDate(0, 0, -1) }
database.GetTime = func() time.Time { return time.Now().AddDate(0, 0, -1) }
query = &models.GetUserByAuthInfoQuery{Login: login, AuthModule: "test2", AuthId: "test2"}
user, err = srv.LookupAndUpdate(context.Background(), query)
getTime = time.Now
database.GetTime = time.Now
require.Nil(t, err)
require.Equal(t, user.Login, login)
@ -211,14 +209,14 @@ func TestUserAuth(t *testing.T) {
UserId: user.Id,
}
err = srv.GetAuthInfo(context.Background(), getAuthQuery)
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
require.Nil(t, err)
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"}
err = srv.UpdateAuthInfo(context.Background(), updateAuthCmd)
err = authInfoStore.UpdateAuthInfo(context.Background(), updateAuthCmd)
require.Nil(t, err)
@ -227,7 +225,7 @@ func TestUserAuth(t *testing.T) {
UserId: user.Id,
}
err = srv.GetAuthInfo(context.Background(), getAuthQuery)
err = authInfoStore.GetAuthInfo(context.Background(), getAuthQuery)
require.Nil(t, err)
require.Equal(t, getAuthQuery.Result.AuthModule, "test1")
@ -238,19 +236,19 @@ func TestUserAuth(t *testing.T) {
login := "loginuser0"
// Expect to pass since there's a matching login user
getTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
database.GetTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
query := &models.GetUserByAuthInfoQuery{Login: login, AuthModule: genericOAuthModule, AuthId: ""}
user, err := srv.LookupAndUpdate(context.Background(), query)
getTime = time.Now
database.GetTime = time.Now
require.Nil(t, err)
require.Equal(t, user.Login, login)
// Should throw a "user not found" error since there's no matching login user
getTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
database.GetTime = func() time.Time { return time.Now().AddDate(0, 0, -2) }
query = &models.GetUserByAuthInfoQuery{Login: "aloginuser", AuthModule: genericOAuthModule, AuthId: ""}
user, err = srv.LookupAndUpdate(context.Background(), query)
getTime = time.Now
database.GetTime = time.Now
require.NotNil(t, err)
require.Nil(t, user)

View File

@ -84,6 +84,10 @@ func (a *authInfoServiceMock) LookupAndUpdate(ctx context.Context, query *models
return a.user, a.err
}
func (a *authInfoServiceMock) GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error {
return nil
}
func Test_teamSync(t *testing.T) {
b := bus.New()
authInfoMock := &authInfoServiceMock{}

View File

@ -1,7 +1,22 @@
package login
import "github.com/grafana/grafana/pkg/models"
import (
"context"
"github.com/grafana/grafana/pkg/models"
)
type UserProtectionService interface {
AllowUserMapping(user *models.User, authModule string) error
}
type Store interface {
GetExternalUserInfoByLogin(ctx context.Context, query *models.GetExternalUserInfoByLoginQuery) error
GetAuthInfo(ctx context.Context, query *models.GetAuthInfoQuery) error
SetAuthInfo(ctx context.Context, cmd *models.SetAuthInfoCommand) error
UpdateAuthInfo(ctx context.Context, cmd *models.UpdateAuthInfoCommand) error
DeleteAuthInfo(ctx context.Context, cmd *models.DeleteAuthInfoCommand) error
GetUserById(id int64) (bool, *models.User, error)
GetUser(user *models.User) (bool, error)
}