mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Login: refactor auth info package (#78459)
* Remove unused stats and metrics * No longer collect metrics * Remove unused dependency * Move database from sub package
This commit is contained in:
parent
d85f03ec26
commit
1eb19befaa
@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/services/user/usertest"
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
||||||
@ -312,7 +312,7 @@ func Test_AdminUpdateUserPermissions(t *testing.T) {
|
|||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
userAuth := &login.UserAuth{AuthModule: tc.authModule}
|
userAuth := &login.UserAuth{AuthModule: tc.authModule}
|
||||||
authInfoService := &logintest.AuthInfoServiceFake{ExpectedUserAuth: userAuth}
|
authInfoService := &authinfotest.FakeService{ExpectedUserAuth: userAuth}
|
||||||
socialService := &socialtest.FakeSocialService{}
|
socialService := &socialtest.FakeSocialService{}
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
|
|
||||||
@ -357,7 +357,7 @@ func putAdminScenario(t *testing.T, desc string, url string, routePattern string
|
|||||||
hs := &HTTPServer{
|
hs := &HTTPServer{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: setting.NewCfg(),
|
||||||
SQLStore: sqlStore,
|
SQLStore: sqlStore,
|
||||||
authInfoService: &logintest.AuthInfoServiceFake{},
|
authInfoService: &authinfotest.FakeService{},
|
||||||
userService: userSvc,
|
userService: userSvc,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -462,7 +462,7 @@ func adminDisableUserScenario(t *testing.T, desc string, action string, url stri
|
|||||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||||
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
|
fakeAuthTokenService := authtest.NewFakeUserAuthTokenService()
|
||||||
|
|
||||||
authInfoService := &logintest.AuthInfoServiceFake{}
|
authInfoService := &authinfotest.FakeService{}
|
||||||
|
|
||||||
hs := HTTPServer{
|
hs := HTTPServer{
|
||||||
SQLStore: dbtest.NewFakeDB(),
|
SQLStore: dbtest.NewFakeDB(),
|
||||||
@ -500,7 +500,7 @@ func adminDeleteUserScenario(t *testing.T, desc string, url string, routePattern
|
|||||||
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s %s", desc, url), func(t *testing.T) {
|
||||||
sc := setupScenarioContext(t, url)
|
sc := setupScenarioContext(t, url)
|
||||||
sc.sqlStore = hs.SQLStore
|
sc.sqlStore = hs.SQLStore
|
||||||
sc.authInfoService = &logintest.AuthInfoServiceFake{}
|
sc.authInfoService = &authinfotest.FakeService{}
|
||||||
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
||||||
sc.context = c
|
sc.context = c
|
||||||
sc.context.UserID = testUserID
|
sc.context.UserID = testUserID
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
"github.com/grafana/grafana/pkg/services/licensing"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||||
"github.com/grafana/grafana/pkg/services/search"
|
"github.com/grafana/grafana/pkg/services/search"
|
||||||
@ -164,7 +164,7 @@ type scenarioContext struct {
|
|||||||
url string
|
url string
|
||||||
userAuthTokenService *authtest.FakeUserAuthTokenService
|
userAuthTokenService *authtest.FakeUserAuthTokenService
|
||||||
sqlStore db.DB
|
sqlStore db.DB
|
||||||
authInfoService *logintest.AuthInfoServiceFake
|
authInfoService *authinfotest.FakeService
|
||||||
dashboardVersionService dashver.Service
|
dashboardVersionService dashver.Service
|
||||||
userService user.Service
|
userService user.Service
|
||||||
ctxHdlr *contexthandler.ContextHandler
|
ctxHdlr *contexthandler.ContextHandler
|
||||||
@ -236,7 +236,7 @@ func setupSimpleHTTPServer(features *featuremgmt.FeatureManager) *HTTPServer {
|
|||||||
License: &licensing.OSSLicensingService{},
|
License: &licensing.OSSLicensingService{},
|
||||||
AccessControl: acimpl.ProvideAccessControl(cfg),
|
AccessControl: acimpl.ProvideAccessControl(cfg),
|
||||||
annotationsRepo: annotationstest.NewFakeAnnotationsRepo(),
|
annotationsRepo: annotationstest.NewFakeAnnotationsRepo(),
|
||||||
authInfoService: &logintest.AuthInfoServiceFake{
|
authInfoService: &authinfotest.FakeService{
|
||||||
ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)},
|
ExpectedLabels: map[int64]string{int64(1): login.GetAuthProviderLabel(login.LDAPAuthModule)},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
"github.com/grafana/grafana/pkg/services/accesscontrol/actest"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
@ -275,7 +275,7 @@ func TestOrgUsersAPIEndpoint_updateOrgRole(t *testing.T) {
|
|||||||
t.Errorf("invalid auth module for test: %s", tt.AuthModule)
|
t.Errorf("invalid auth module for test: %s", tt.AuthModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{
|
hs.authInfoService = &authinfotest.FakeService{
|
||||||
ExpectedUserAuth: &login.UserAuth{AuthModule: tt.AuthModule},
|
ExpectedUserAuth: &login.UserAuth{AuthModule: tt.AuthModule},
|
||||||
}
|
}
|
||||||
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions}
|
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions}
|
||||||
@ -319,7 +319,7 @@ func TestOrgUsersAPIEndpoint(t *testing.T) {
|
|||||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||||
hs.Cfg = setting.NewCfg()
|
hs.Cfg = setting.NewCfg()
|
||||||
hs.orgService = &orgtest.FakeOrgService{ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{}}
|
hs.orgService = &orgtest.FakeOrgService{ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{}}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
hs.authInfoService = &authinfotest.FakeService{}
|
||||||
})
|
})
|
||||||
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/org/users/lookup"), userWithPermissions(1, tt.permissions)))
|
res, err := server.Send(webtest.RequestWithSignedInUser(server.NewGetRequest("/api/org/users/lookup"), userWithPermissions(1, tt.permissions)))
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
@ -377,7 +377,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
|
|||||||
hs.orgService = &orgtest.FakeOrgService{
|
hs.orgService = &orgtest.FakeOrgService{
|
||||||
ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{OrgUsers: []*org.OrgUserDTO{{UserID: 1}}},
|
ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{OrgUsers: []*org.OrgUserDTO{{UserID: 1}}},
|
||||||
}
|
}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
hs.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions(1, tt.permissions)}
|
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions(1, tt.permissions)}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -435,7 +435,7 @@ func TestGetOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
|
|||||||
hs.orgService = &orgtest.FakeOrgService{
|
hs.orgService = &orgtest.FakeOrgService{
|
||||||
ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{},
|
ExpectedSearchOrgUsersResult: &org.SearchOrgUsersQueryResult{},
|
||||||
}
|
}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
hs.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions(1, tc.permissions)}
|
hs.userService = &usertest.FakeUserService{ExpectedSignedInUser: userWithPermissions(1, tc.permissions)}
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -477,7 +477,7 @@ func TestPostOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
|
|||||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||||
hs.Cfg = setting.NewCfg()
|
hs.Cfg = setting.NewCfg()
|
||||||
hs.orgService = &orgtest.FakeOrgService{}
|
hs.orgService = &orgtest.FakeOrgService{}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
hs.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.userService = &usertest.FakeUserService{
|
hs.userService = &usertest.FakeUserService{
|
||||||
ExpectedUser: &user.User{},
|
ExpectedUser: &user.User{},
|
||||||
ExpectedSignedInUser: userWithPermissions(1, tt.permissions),
|
ExpectedSignedInUser: userWithPermissions(1, tt.permissions),
|
||||||
@ -601,7 +601,7 @@ func TestOrgUsersAPIEndpointWithSetPerms_AccessControl(t *testing.T) {
|
|||||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||||
hs.Cfg = setting.NewCfg()
|
hs.Cfg = setting.NewCfg()
|
||||||
hs.orgService = &orgtest.FakeOrgService{}
|
hs.orgService = &orgtest.FakeOrgService{}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{
|
hs.authInfoService = &authinfotest.FakeService{
|
||||||
ExpectedUserAuth: &login.UserAuth{
|
ExpectedUserAuth: &login.UserAuth{
|
||||||
AuthModule: "",
|
AuthModule: "",
|
||||||
},
|
},
|
||||||
@ -663,7 +663,7 @@ func TestPatchOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
|
|||||||
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
server := SetupAPITestServer(t, func(hs *HTTPServer) {
|
||||||
hs.Cfg = setting.NewCfg()
|
hs.Cfg = setting.NewCfg()
|
||||||
hs.orgService = &orgtest.FakeOrgService{}
|
hs.orgService = &orgtest.FakeOrgService{}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{
|
hs.authInfoService = &authinfotest.FakeService{
|
||||||
ExpectedUserAuth: &login.UserAuth{
|
ExpectedUserAuth: &login.UserAuth{
|
||||||
AuthModule: "",
|
AuthModule: "",
|
||||||
},
|
},
|
||||||
@ -716,7 +716,7 @@ func TestDeleteOrgUsersAPIEndpoint_AccessControl(t *testing.T) {
|
|||||||
Response error
|
Response error
|
||||||
}{OrgID: 1, Response: nil}},
|
}{OrgID: 1, Response: nil}},
|
||||||
}
|
}
|
||||||
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
hs.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.userService = &usertest.FakeUserService{
|
hs.userService = &usertest.FakeUserService{
|
||||||
ExpectedUser: &user.User{},
|
ExpectedUser: &user.User{},
|
||||||
ExpectedSignedInUser: userWithPermissions(1, tt.permissions),
|
ExpectedSignedInUser: userWithPermissions(1, tt.permissions),
|
||||||
|
@ -24,9 +24,8 @@ import (
|
|||||||
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
acmock "github.com/grafana/grafana/pkg/services/accesscontrol/mock"
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
authinfostore "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
"github.com/grafana/grafana/pkg/services/org/orgimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||||
"github.com/grafana/grafana/pkg/services/searchusers"
|
"github.com/grafana/grafana/pkg/services/searchusers"
|
||||||
@ -63,8 +62,8 @@ func TestUserAPIEndpoint_userLoggedIn(t *testing.T) {
|
|||||||
loggedInUserScenario(t, "When calling GET on", "api/users/1", "api/users/:id", func(sc *scenarioContext) {
|
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)
|
fakeNow := time.Date(2019, 2, 11, 17, 30, 40, 0, time.UTC)
|
||||||
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
|
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(sqlStore))
|
||||||
authInfoStore := authinfostore.ProvideAuthInfoStore(sqlStore, secretsService, userMock)
|
authInfoStore := authinfoimpl.ProvideStore(sqlStore, secretsService)
|
||||||
srv := authinfoservice.ProvideAuthInfoService(
|
srv := authinfoimpl.ProvideService(
|
||||||
authInfoStore,
|
authInfoStore,
|
||||||
)
|
)
|
||||||
hs.authInfoService = srv
|
hs.authInfoService = srv
|
||||||
@ -292,7 +291,7 @@ func Test_GetUserByID(t *testing.T) {
|
|||||||
for _, tc := range testcases {
|
for _, tc := range testcases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
userAuth := &login.UserAuth{AuthModule: tc.authModule}
|
userAuth := &login.UserAuth{AuthModule: tc.authModule}
|
||||||
authInfoService := &logintest.AuthInfoServiceFake{ExpectedUserAuth: userAuth}
|
authInfoService := &authinfotest.FakeService{ExpectedUserAuth: userAuth}
|
||||||
socialService := &socialtest.FakeSocialService{}
|
socialService := &socialtest.FakeSocialService{}
|
||||||
userService := &usertest.FakeUserService{ExpectedUserProfileDTO: &user.UserProfileDTO{}}
|
userService := &usertest.FakeUserService{ExpectedUserProfileDTO: &user.UserProfileDTO{}}
|
||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
@ -376,7 +375,7 @@ func updateUserScenario(t *testing.T, ctx updateUserContext, hs *HTTPServer) {
|
|||||||
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
||||||
sc := setupScenarioContext(t, ctx.url)
|
sc := setupScenarioContext(t, ctx.url)
|
||||||
|
|
||||||
sc.authInfoService = &logintest.AuthInfoServiceFake{}
|
sc.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.authInfoService = sc.authInfoService
|
hs.authInfoService = sc.authInfoService
|
||||||
|
|
||||||
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
||||||
@ -429,7 +428,7 @@ func updateSignedInUserScenario(t *testing.T, ctx updateUserContext, hs *HTTPSer
|
|||||||
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
t.Run(fmt.Sprintf("%s %s", ctx.desc, ctx.url), func(t *testing.T) {
|
||||||
sc := setupScenarioContext(t, ctx.url)
|
sc := setupScenarioContext(t, ctx.url)
|
||||||
|
|
||||||
sc.authInfoService = &logintest.AuthInfoServiceFake{}
|
sc.authInfoService = &authinfotest.FakeService{}
|
||||||
hs.authInfoService = sc.authInfoService
|
hs.authInfoService = sc.authInfoService
|
||||||
|
|
||||||
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
sc.defaultHandler = routing.Wrap(func(c *contextmodel.ReqContext) response.Response {
|
||||||
|
@ -21,7 +21,6 @@ import (
|
|||||||
ldapapi "github.com/grafana/grafana/pkg/services/ldap/api"
|
ldapapi "github.com/grafana/grafana/pkg/services/ldap/api"
|
||||||
"github.com/grafana/grafana/pkg/services/live"
|
"github.com/grafana/grafana/pkg/services/live"
|
||||||
"github.com/grafana/grafana/pkg/services/live/pushhttp"
|
"github.com/grafana/grafana/pkg/services/live/pushhttp"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
|
||||||
"github.com/grafana/grafana/pkg/services/loginattempt/loginattemptimpl"
|
"github.com/grafana/grafana/pkg/services/loginattempt/loginattemptimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/ngalert"
|
"github.com/grafana/grafana/pkg/services/ngalert"
|
||||||
"github.com/grafana/grafana/pkg/services/notifications"
|
"github.com/grafana/grafana/pkg/services/notifications"
|
||||||
@ -54,8 +53,8 @@ func ProvideBackgroundServiceRegistry(
|
|||||||
statsCollector *statscollector.Service, grafanaUpdateChecker *updatechecker.GrafanaService,
|
statsCollector *statscollector.Service, grafanaUpdateChecker *updatechecker.GrafanaService,
|
||||||
pluginsUpdateChecker *updatechecker.PluginsService, metrics *metrics.InternalMetricsService,
|
pluginsUpdateChecker *updatechecker.PluginsService, metrics *metrics.InternalMetricsService,
|
||||||
secretsService *secretsManager.SecretsService, remoteCache *remotecache.RemoteCache, StorageService store.StorageService, searchService searchV2.SearchService, entityEventsService store.EntityEventsService,
|
secretsService *secretsManager.SecretsService, remoteCache *remotecache.RemoteCache, StorageService store.StorageService, searchService searchV2.SearchService, entityEventsService store.EntityEventsService,
|
||||||
saService *samanager.ServiceAccountsService, authInfoService *authinfoservice.Implementation,
|
saService *samanager.ServiceAccountsService, grpcServerProvider grpcserver.Provider,
|
||||||
grpcServerProvider grpcserver.Provider, secretMigrationProvider secretsMigrations.SecretMigrationProvider, loginAttemptService *loginattemptimpl.Service,
|
secretMigrationProvider secretsMigrations.SecretMigrationProvider, loginAttemptService *loginattemptimpl.Service,
|
||||||
bundleService *supportbundlesimpl.Service, publicDashboardsMetric *publicdashboardsmetric.Service,
|
bundleService *supportbundlesimpl.Service, publicDashboardsMetric *publicdashboardsmetric.Service,
|
||||||
keyRetriever *dynamic.KeyRetriever, dynamicAngularDetectorsProvider *angulardetectorsprovider.Dynamic,
|
keyRetriever *dynamic.KeyRetriever, dynamicAngularDetectorsProvider *angulardetectorsprovider.Dynamic,
|
||||||
grafanaAPIServer grafanaapiserver.Service,
|
grafanaAPIServer grafanaapiserver.Service,
|
||||||
@ -91,7 +90,6 @@ func ProvideBackgroundServiceRegistry(
|
|||||||
entityEventsService,
|
entityEventsService,
|
||||||
grpcServerProvider,
|
grpcServerProvider,
|
||||||
saService,
|
saService,
|
||||||
authInfoService,
|
|
||||||
pluginStore,
|
pluginStore,
|
||||||
secretMigrationProvider,
|
secretMigrationProvider,
|
||||||
loginAttemptService,
|
loginAttemptService,
|
||||||
|
@ -83,8 +83,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/live"
|
"github.com/grafana/grafana/pkg/services/live"
|
||||||
"github.com/grafana/grafana/pkg/services/live/pushhttp"
|
"github.com/grafana/grafana/pkg/services/live/pushhttp"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
authinfodatabase "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
|
|
||||||
"github.com/grafana/grafana/pkg/services/loginattempt"
|
"github.com/grafana/grafana/pkg/services/loginattempt"
|
||||||
"github.com/grafana/grafana/pkg/services/loginattempt/loginattemptimpl"
|
"github.com/grafana/grafana/pkg/services/loginattempt/loginattemptimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/navtree/navtreeimpl"
|
"github.com/grafana/grafana/pkg/services/navtree/navtreeimpl"
|
||||||
@ -226,9 +225,9 @@ var wireBasicSet = wire.NewSet(
|
|||||||
quotaimpl.ProvideService,
|
quotaimpl.ProvideService,
|
||||||
remotecache.ProvideService,
|
remotecache.ProvideService,
|
||||||
wire.Bind(new(remotecache.CacheStorage), new(*remotecache.RemoteCache)),
|
wire.Bind(new(remotecache.CacheStorage), new(*remotecache.RemoteCache)),
|
||||||
authinfoservice.ProvideAuthInfoService,
|
authinfoimpl.ProvideService,
|
||||||
wire.Bind(new(login.AuthInfoService), new(*authinfoservice.Implementation)),
|
wire.Bind(new(login.AuthInfoService), new(*authinfoimpl.Service)),
|
||||||
authinfodatabase.ProvideAuthInfoStore,
|
authinfoimpl.ProvideStore,
|
||||||
datasourceproxy.ProvideService,
|
datasourceproxy.ProvideService,
|
||||||
search.ProvideService,
|
search.ProvideService,
|
||||||
searchV2.ProvideService,
|
searchV2.ProvideService,
|
||||||
|
@ -31,7 +31,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ldap"
|
"github.com/grafana/grafana/pkg/services/ldap"
|
||||||
"github.com/grafana/grafana/pkg/services/licensing"
|
"github.com/grafana/grafana/pkg/services/licensing"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/pluginsintegration"
|
"github.com/grafana/grafana/pkg/services/pluginsintegration"
|
||||||
"github.com/grafana/grafana/pkg/services/provisioning"
|
"github.com/grafana/grafana/pkg/services/provisioning"
|
||||||
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
"github.com/grafana/grafana/pkg/services/publicdashboards"
|
||||||
@ -68,8 +68,8 @@ var wireExtsBasicSet = wire.NewSet(
|
|||||||
wire.Bind(new(registry.BackgroundServiceRegistry), new(*backgroundsvcs.BackgroundServiceRegistry)),
|
wire.Bind(new(registry.BackgroundServiceRegistry), new(*backgroundsvcs.BackgroundServiceRegistry)),
|
||||||
migrations.ProvideOSSMigrations,
|
migrations.ProvideOSSMigrations,
|
||||||
wire.Bind(new(registry.DatabaseMigrator), new(*migrations.OSSMigrations)),
|
wire.Bind(new(registry.DatabaseMigrator), new(*migrations.OSSMigrations)),
|
||||||
authinfoservice.ProvideOSSUserProtectionService,
|
authinfoimpl.ProvideOSSUserProtectionService,
|
||||||
wire.Bind(new(login.UserProtectionService), new(*authinfoservice.OSSUserProtectionImpl)),
|
wire.Bind(new(login.UserProtectionService), new(*authinfoimpl.OSSUserProtectionImpl)),
|
||||||
encryptionprovider.ProvideEncryptionProvider,
|
encryptionprovider.ProvideEncryptionProvider,
|
||||||
wire.Bind(new(encryption.Provider), new(encryptionprovider.Provider)),
|
wire.Bind(new(encryption.Provider), new(encryptionprovider.Provider)),
|
||||||
filters.ProvideOSSSearchUserFilter,
|
filters.ProvideOSSSearchUserFilter,
|
||||||
|
@ -9,8 +9,8 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/authn"
|
"github.com/grafana/grafana/pkg/services/authn"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/quota"
|
"github.com/grafana/grafana/pkg/services/quota"
|
||||||
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
"github.com/grafana/grafana/pkg/services/quota/quotatest"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@ -30,9 +30,9 @@ func ptrInt64(i int64) *int64 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestUserSync_SyncUserHook(t *testing.T) {
|
func TestUserSync_SyncUserHook(t *testing.T) {
|
||||||
userProtection := &authinfoservice.OSSUserProtectionImpl{}
|
userProtection := &authinfoimpl.OSSUserProtectionImpl{}
|
||||||
|
|
||||||
authFakeNil := &logintest.AuthInfoServiceFake{
|
authFakeNil := &authinfotest.FakeService{
|
||||||
ExpectedError: user.ErrUserNotFound,
|
ExpectedError: user.ErrUserNotFound,
|
||||||
SetAuthInfoFn: func(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
SetAuthInfoFn: func(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
||||||
return nil
|
return nil
|
||||||
@ -41,7 +41,7 @@ func TestUserSync_SyncUserHook(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
authFakeUserID := &logintest.AuthInfoServiceFake{
|
authFakeUserID := &authinfotest.FakeService{
|
||||||
ExpectedError: nil,
|
ExpectedError: nil,
|
||||||
ExpectedUserAuth: &login.UserAuth{
|
ExpectedUserAuth: &login.UserAuth{
|
||||||
AuthModule: "oauth",
|
AuthModule: "oauth",
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||||
"github.com/grafana/grafana/pkg/services/ldap/service"
|
"github.com/grafana/grafana/pkg/services/ldap/service"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/services/user/usertest"
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
||||||
@ -192,7 +192,7 @@ func setupLDAPTestCase(tt *ldapTestCase) *LDAP {
|
|||||||
return nil
|
return nil
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
authInfoService := &logintest.AuthInfoServiceFake{
|
authInfoService := &authinfotest.FakeService{
|
||||||
ExpectedUserAuth: &tt.expectedAuthInfo,
|
ExpectedUserAuth: &tt.expectedAuthInfo,
|
||||||
ExpectedError: tt.expectedAuthInfoErr,
|
ExpectedError: tt.expectedAuthInfoErr,
|
||||||
}
|
}
|
||||||
|
@ -20,7 +20,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||||
"github.com/grafana/grafana/pkg/services/ldap/service"
|
"github.com/grafana/grafana/pkg/services/ldap/service"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
"github.com/grafana/grafana/pkg/services/login/authinfotest"
|
||||||
"github.com/grafana/grafana/pkg/services/org"
|
"github.com/grafana/grafana/pkg/services/org"
|
||||||
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
||||||
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
|
"github.com/grafana/grafana/pkg/services/supportbundles/supportbundlestest"
|
||||||
@ -67,7 +67,7 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
|||||||
router,
|
router,
|
||||||
acimpl.ProvideAccessControl(cfg),
|
acimpl.ProvideAccessControl(cfg),
|
||||||
usertest.NewUserServiceFake(),
|
usertest.NewUserServiceFake(),
|
||||||
&logintest.AuthInfoServiceFake{},
|
&authinfotest.FakeService{},
|
||||||
ldap.ProvideGroupsService(),
|
ldap.ProvideGroupsService(),
|
||||||
&authntest.FakeService{},
|
&authntest.FakeService{},
|
||||||
&orgtest.FakeOrgService{},
|
&orgtest.FakeOrgService{},
|
||||||
@ -507,7 +507,7 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
|||||||
|
|
||||||
_, server := setupAPITest(t, func(a *Service) {
|
_, server := setupAPITest(t, func(a *Service) {
|
||||||
a.userService = userServiceMock
|
a.userService = userServiceMock
|
||||||
a.authInfoService = &logintest.AuthInfoServiceFake{ExpectedExternalUser: &login.ExternalUserInfo{IsDisabled: true, UserId: 34}}
|
a.authInfoService = &authinfotest.FakeService{ExpectedExternalUser: &login.ExternalUserInfo{IsDisabled: true, UserId: 34}}
|
||||||
a.ldapService = &service.LDAPFakeService{
|
a.ldapService = &service.LDAPFakeService{
|
||||||
ExpectedClient: &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser},
|
ExpectedClient: &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser},
|
||||||
ExpectedConfig: &ldap.Config{},
|
ExpectedConfig: &ldap.Config{},
|
||||||
|
@ -20,8 +20,6 @@ type Store interface {
|
|||||||
SetAuthInfo(ctx context.Context, cmd *SetAuthInfoCommand) error
|
SetAuthInfo(ctx context.Context, cmd *SetAuthInfoCommand) error
|
||||||
UpdateAuthInfo(ctx context.Context, cmd *UpdateAuthInfoCommand) error
|
UpdateAuthInfo(ctx context.Context, cmd *UpdateAuthInfoCommand) error
|
||||||
DeleteUserAuthInfo(ctx context.Context, userID int64) error
|
DeleteUserAuthInfo(ctx context.Context, userID int64) error
|
||||||
CollectLoginStats(ctx context.Context) (map[string]any, error)
|
|
||||||
RunMetricsCollection(ctx context.Context) error
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
45
pkg/services/login/authinfoimpl/service.go
Normal file
45
pkg/services/login/authinfoimpl/service.go
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
package authinfoimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Service struct {
|
||||||
|
authInfoStore login.Store
|
||||||
|
logger log.Logger
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProvideService(authInfoStore login.Store) *Service {
|
||||||
|
s := &Service{
|
||||||
|
authInfoStore: authInfoStore,
|
||||||
|
logger: log.New("login.authinfo"),
|
||||||
|
}
|
||||||
|
|
||||||
|
return s
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
||||||
|
return s.authInfoStore.GetAuthInfo(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
||||||
|
if len(query.UserIDs) == 0 {
|
||||||
|
return map[int64]string{}, nil
|
||||||
|
}
|
||||||
|
return s.authInfoStore.GetUserLabels(ctx, query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
||||||
|
return s.authInfoStore.UpdateAuthInfo(ctx, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
||||||
|
return s.authInfoStore.SetAuthInfo(ctx, cmd)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Service) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
||||||
|
return s.authInfoStore.DeleteUserAuthInfo(ctx, userID)
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package database
|
package authinfoimpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -14,29 +14,25 @@ import (
|
|||||||
|
|
||||||
var GetTime = time.Now
|
var GetTime = time.Now
|
||||||
|
|
||||||
type AuthInfoStore struct {
|
type Store struct {
|
||||||
sqlStore db.DB
|
sqlStore db.DB
|
||||||
secretsService secrets.Service
|
secretsService secrets.Service
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
userService user.Service
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func ProvideAuthInfoStore(sqlStore db.DB, secretsService secrets.Service, userService user.Service) login.Store {
|
func ProvideStore(sqlStore db.DB, secretsService secrets.Service) login.Store {
|
||||||
store := &AuthInfoStore{
|
store := &Store{
|
||||||
sqlStore: sqlStore,
|
sqlStore: sqlStore,
|
||||||
secretsService: secretsService,
|
secretsService: secretsService,
|
||||||
logger: log.New("login.authinfo.store"),
|
logger: log.New("login.authinfo.store"),
|
||||||
userService: userService,
|
|
||||||
}
|
}
|
||||||
// FIXME: disabled the metric collection for duplicate user entries
|
|
||||||
// due to query performance issues that is clogging the users Grafana instance
|
|
||||||
// InitDuplicateUserMetrics()
|
|
||||||
return store
|
return store
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetAuthInfo returns the auth info for a user
|
// GetAuthInfo returns the auth info for a user
|
||||||
// It will return the latest auth info for a user
|
// It will return the latest auth info for a user
|
||||||
func (s *AuthInfoStore) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
func (s *Store) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
||||||
if query.UserId == 0 && query.AuthId == "" {
|
if query.UserId == 0 && query.AuthId == "" {
|
||||||
return nil, user.ErrUserNotFound
|
return nil, user.ErrUserNotFound
|
||||||
}
|
}
|
||||||
@ -86,7 +82,7 @@ func (s *AuthInfoStore) GetAuthInfo(ctx context.Context, query *login.GetAuthInf
|
|||||||
return userAuth, nil
|
return userAuth, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AuthInfoStore) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
func (s *Store) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
||||||
userAuths := []login.UserAuth{}
|
userAuths := []login.UserAuth{}
|
||||||
params := make([]interface{}, 0, len(query.UserIDs))
|
params := make([]interface{}, 0, len(query.UserIDs))
|
||||||
for _, id := range query.UserIDs {
|
for _, id := range query.UserIDs {
|
||||||
@ -110,7 +106,7 @@ func (s *AuthInfoStore) GetUserLabels(ctx context.Context, query login.GetUserLa
|
|||||||
return labelMap, nil
|
return labelMap, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AuthInfoStore) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
func (s *Store) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
||||||
authUser := &login.UserAuth{
|
authUser := &login.UserAuth{
|
||||||
UserId: cmd.UserId,
|
UserId: cmd.UserId,
|
||||||
AuthModule: cmd.AuthModule,
|
AuthModule: cmd.AuthModule,
|
||||||
@ -153,7 +149,7 @@ func (s *AuthInfoStore) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoC
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
func (s *Store) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
||||||
authUser := &login.UserAuth{
|
authUser := &login.UserAuth{
|
||||||
UserId: cmd.UserId,
|
UserId: cmd.UserId,
|
||||||
AuthModule: cmd.AuthModule,
|
AuthModule: cmd.AuthModule,
|
||||||
@ -222,7 +218,7 @@ func (s *AuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAut
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AuthInfoStore) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
func (s *Store) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
||||||
return s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
return s.sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||||
var rawSQL = "DELETE FROM user_auth WHERE user_id = ?"
|
var rawSQL = "DELETE FROM user_auth WHERE user_id = ?"
|
||||||
_, err := sess.Exec(rawSQL, userID)
|
_, err := sess.Exec(rawSQL, userID)
|
||||||
@ -231,7 +227,7 @@ func (s *AuthInfoStore) DeleteUserAuthInfo(ctx context.Context, userID int64) er
|
|||||||
}
|
}
|
||||||
|
|
||||||
// decodeAndDecrypt will decode the string with the standard base64 decoder and then decrypt it
|
// decodeAndDecrypt will decode the string with the standard base64 decoder and then decrypt it
|
||||||
func (s *AuthInfoStore) decodeAndDecrypt(str string) (string, error) {
|
func (s *Store) decodeAndDecrypt(str string) (string, error) {
|
||||||
// Bail out if empty string since it'll cause a segfault in Decrypt
|
// Bail out if empty string since it'll cause a segfault in Decrypt
|
||||||
if str == "" {
|
if str == "" {
|
||||||
return "", nil
|
return "", nil
|
||||||
@ -249,7 +245,7 @@ func (s *AuthInfoStore) decodeAndDecrypt(str string) (string, error) {
|
|||||||
|
|
||||||
// encryptAndEncode will encrypt a string with grafana's secretKey, and
|
// encryptAndEncode will encrypt a string with grafana's secretKey, and
|
||||||
// then encode it with the standard bas64 encoder
|
// then encode it with the standard bas64 encoder
|
||||||
func (s *AuthInfoStore) encryptAndEncode(str string) (string, error) {
|
func (s *Store) encryptAndEncode(str string) (string, error) {
|
||||||
encrypted, err := s.secretsService.Encrypt(context.Background(), []byte(str), secrets.WithoutScope())
|
encrypted, err := s.secretsService.Encrypt(context.Background(), []byte(str), secrets.WithoutScope())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return "", err
|
return "", err
|
@ -1,4 +1,4 @@
|
|||||||
package database
|
package authinfoimpl
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -21,7 +21,7 @@ func TestIntegrationAuthInfoStore(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
sql := db.InitTestDB(t)
|
sql := db.InitTestDB(t)
|
||||||
store := ProvideAuthInfoStore(sql, secretstest.NewFakeSecretsService(), nil)
|
store := ProvideStore(sql, secretstest.NewFakeSecretsService())
|
||||||
|
|
||||||
t.Run("should be able to auth lables for users", func(t *testing.T) {
|
t.Run("should be able to auth lables for users", func(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
@ -1,4 +1,4 @@
|
|||||||
package authinfoservice
|
package authinfoimpl
|
||||||
|
|
||||||
import "github.com/grafana/grafana/pkg/services/user"
|
import "github.com/grafana/grafana/pkg/services/user"
|
||||||
|
|
@ -1,127 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Should be in use in ProvideAuthInfoStore
|
|
||||||
// due to query performance for big user tables
|
|
||||||
// we have disabled these metrics from Grafana for now
|
|
||||||
func InitDuplicateUserMetrics() {
|
|
||||||
login.Once.Do(func() {
|
|
||||||
login.MStatDuplicateUserEntries = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Name: "stat_users_total_duplicate_user_entries",
|
|
||||||
Help: "total number of duplicate user entries by email or login",
|
|
||||||
Namespace: login.ExporterName,
|
|
||||||
})
|
|
||||||
|
|
||||||
login.MStatHasDuplicateEntries = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Name: "stat_users_has_duplicate_user_entries",
|
|
||||||
Help: "instance has duplicate user entries by email or login",
|
|
||||||
Namespace: login.ExporterName,
|
|
||||||
})
|
|
||||||
|
|
||||||
login.MStatMixedCasedUsers = prometheus.NewGauge(prometheus.GaugeOpts{
|
|
||||||
Name: "stat_users_total_mixed_cased_users",
|
|
||||||
Help: "total number of users with upper and lower case logins or emails",
|
|
||||||
Namespace: login.ExporterName,
|
|
||||||
})
|
|
||||||
|
|
||||||
prometheus.MustRegister(
|
|
||||||
login.MStatDuplicateUserEntries,
|
|
||||||
login.MStatHasDuplicateEntries,
|
|
||||||
login.MStatMixedCasedUsers,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AuthInfoStore) RunMetricsCollection(ctx context.Context) error {
|
|
||||||
// if _, err := s.getLoginStats(ctx); err != nil {
|
|
||||||
// s.logger.Warn("Failed to get authinfo metrics", "error", err.Error())
|
|
||||||
// }
|
|
||||||
updateStatsTicker := time.NewTicker(login.MetricsCollectionInterval)
|
|
||||||
defer updateStatsTicker.Stop()
|
|
||||||
|
|
||||||
for {
|
|
||||||
select {
|
|
||||||
case <-updateStatsTicker.C:
|
|
||||||
// if _, err := s.getLoginStats(ctx); err != nil {
|
|
||||||
// s.logger.Warn("Failed to get authinfo metrics", "error", nil)
|
|
||||||
// }
|
|
||||||
case <-ctx.Done():
|
|
||||||
return ctx.Err()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AuthInfoStore) CollectLoginStats(ctx context.Context) (map[string]any, error) {
|
|
||||||
m := map[string]any{}
|
|
||||||
|
|
||||||
loginStats, err := s.getLoginStats(ctx)
|
|
||||||
if err != nil {
|
|
||||||
s.logger.Error("Failed to get login stats", "error", err)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
m["stats.users.duplicate_user_entries"] = loginStats.DuplicateUserEntries
|
|
||||||
if loginStats.DuplicateUserEntries > 0 {
|
|
||||||
m["stats.users.has_duplicate_user_entries"] = 1
|
|
||||||
} else {
|
|
||||||
m["stats.users.has_duplicate_user_entries"] = 0
|
|
||||||
}
|
|
||||||
m["stats.users.mixed_cased_users"] = loginStats.MixedCasedUsers
|
|
||||||
|
|
||||||
return m, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AuthInfoStore) getLoginStats(ctx context.Context) (login.LoginStats, error) {
|
|
||||||
var stats login.LoginStats
|
|
||||||
outerErr := s.sqlStore.WithDbSession(ctx, func(dbSession *db.Session) error {
|
|
||||||
rawSQL := `SELECT
|
|
||||||
(SELECT COUNT(*) FROM (` + s.duplicateUserEntriesSQL(ctx) + `) AS d WHERE (d.dup_login IS NOT NULL OR d.dup_email IS NOT NULL)) as duplicate_user_entries,
|
|
||||||
(SELECT COUNT(*) FROM (` + s.mixedCasedUsers(ctx) + `) AS mcu) AS mixed_cased_users
|
|
||||||
`
|
|
||||||
_, err := dbSession.SQL(rawSQL).Get(&stats)
|
|
||||||
return err
|
|
||||||
})
|
|
||||||
if outerErr != nil {
|
|
||||||
return stats, outerErr
|
|
||||||
}
|
|
||||||
|
|
||||||
// set prometheus metrics stats
|
|
||||||
login.MStatDuplicateUserEntries.Set(float64(stats.DuplicateUserEntries))
|
|
||||||
if stats.DuplicateUserEntries == 0 {
|
|
||||||
login.MStatHasDuplicateEntries.Set(float64(0))
|
|
||||||
} else {
|
|
||||||
login.MStatHasDuplicateEntries.Set(float64(1))
|
|
||||||
}
|
|
||||||
|
|
||||||
login.MStatMixedCasedUsers.Set(float64(stats.MixedCasedUsers))
|
|
||||||
return stats, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AuthInfoStore) duplicateUserEntriesSQL(ctx context.Context) string {
|
|
||||||
userDialect := s.sqlStore.GetDialect().Quote("user")
|
|
||||||
// this query counts how many users have the same login or email.
|
|
||||||
// which might be confusing, but gives a good indication
|
|
||||||
// we want this query to not require too much cpu
|
|
||||||
sqlQuery := `SELECT
|
|
||||||
(SELECT login from ` + userDialect + ` WHERE (LOWER(login) = LOWER(u.login)) AND (login != u.login)) AS dup_login,
|
|
||||||
(SELECT email from ` + userDialect + ` WHERE (LOWER(email) = LOWER(u.email)) AND (email != u.email)) AS dup_email
|
|
||||||
FROM ` + userDialect + ` AS u`
|
|
||||||
return sqlQuery
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *AuthInfoStore) mixedCasedUsers(ctx context.Context) string {
|
|
||||||
userDialect := db.DB.GetDialect(s.sqlStore).Quote("user")
|
|
||||||
// this query counts how many users have upper case and lower case login or emails.
|
|
||||||
// why
|
|
||||||
// users login via IDP or service providers get upper cased domains at times :shrug:
|
|
||||||
sqlQuery := `SELECT login, email FROM ` + userDialect + ` WHERE (LOWER(login) != login OR lower(email) != email)`
|
|
||||||
return sqlQuery
|
|
||||||
}
|
|
@ -1,76 +0,0 @@
|
|||||||
package database
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stretchr/testify/require"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
|
||||||
secretstest "github.com/grafana/grafana/pkg/services/secrets/fakes"
|
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
|
||||||
"github.com/grafana/grafana/pkg/services/user/userimpl"
|
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestIntegrationAuthInfoStoreStats(t *testing.T) {
|
|
||||||
sql := db.InitTestDB(t)
|
|
||||||
cfg := setting.NewCfg()
|
|
||||||
InitDuplicateUserMetrics()
|
|
||||||
|
|
||||||
now := time.Now()
|
|
||||||
|
|
||||||
usrStore := userimpl.ProvideStore(sql, cfg)
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
usr := &user.User{
|
|
||||||
Email: fmt.Sprint("user", i, "@test.com"),
|
|
||||||
Login: fmt.Sprint("user", i),
|
|
||||||
Name: fmt.Sprint("user", i),
|
|
||||||
Created: now,
|
|
||||||
Updated: now,
|
|
||||||
LastSeenAt: now,
|
|
||||||
}
|
|
||||||
_, err := usrStore.Insert(context.Background(), usr)
|
|
||||||
require.Nil(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
duplicatedUsers int
|
|
||||||
mixedCasedUsers int
|
|
||||||
hasDuplicatedUsers int
|
|
||||||
)
|
|
||||||
|
|
||||||
if sql.GetDialect().DriverName() != "mysql" {
|
|
||||||
duplicatedUsers, mixedCasedUsers, hasDuplicatedUsers = 2, 1, 1
|
|
||||||
_, err := usrStore.Insert(context.Background(), &user.User{
|
|
||||||
Email: "USERDUPLICATETEST1@TEST.COM",
|
|
||||||
Name: "user name 1",
|
|
||||||
Login: "USER_DUPLICATE_TEST_1_LOGIN",
|
|
||||||
Created: now,
|
|
||||||
Updated: now,
|
|
||||||
LastSeenAt: now,
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
// add additional user with duplicate login where DOMAIN is upper case
|
|
||||||
_, err = usrStore.Insert(context.Background(), &user.User{
|
|
||||||
Email: "userduplicatetest1@test.com",
|
|
||||||
Name: "user name 1",
|
|
||||||
Login: "user_duplicate_test_1_login",
|
|
||||||
Created: now,
|
|
||||||
Updated: now,
|
|
||||||
LastSeenAt: now,
|
|
||||||
})
|
|
||||||
require.NoError(t, err)
|
|
||||||
}
|
|
||||||
|
|
||||||
store := ProvideAuthInfoStore(sql, secretstest.NewFakeSecretsService(), nil)
|
|
||||||
stats, err := store.CollectLoginStats(context.Background())
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
require.Equal(t, duplicatedUsers, stats["stats.users.duplicate_user_entries"])
|
|
||||||
require.Equal(t, mixedCasedUsers, stats["stats.users.mixed_cased_users"])
|
|
||||||
require.Equal(t, hasDuplicatedUsers, stats["stats.users.has_duplicate_user_entries"])
|
|
||||||
}
|
|
@ -1,52 +0,0 @@
|
|||||||
package authinfoservice
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Implementation struct {
|
|
||||||
authInfoStore login.Store
|
|
||||||
logger log.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func ProvideAuthInfoService(authInfoStore login.Store) *Implementation {
|
|
||||||
s := &Implementation{
|
|
||||||
authInfoStore: authInfoStore,
|
|
||||||
logger: log.New("login.authinfo"),
|
|
||||||
}
|
|
||||||
// FIXME: disabled metrics until further notice
|
|
||||||
// query performance is slow for more than 20000 users
|
|
||||||
// usageStats.RegisterMetricsFunc(authInfoStore.CollectLoginStats)
|
|
||||||
return s
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
|
||||||
return s.authInfoStore.GetAuthInfo(ctx, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
|
||||||
if len(query.UserIDs) == 0 {
|
|
||||||
return map[int64]string{}, nil
|
|
||||||
}
|
|
||||||
return s.authInfoStore.GetUserLabels(ctx, query)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
|
||||||
return s.authInfoStore.UpdateAuthInfo(ctx, cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
|
||||||
return s.authInfoStore.SetAuthInfo(ctx, cmd)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
|
||||||
return s.authInfoStore.DeleteUserAuthInfo(ctx, userID)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Implementation) Run(ctx context.Context) error {
|
|
||||||
s.logger.Debug("Started AuthInfo Metrics collection service")
|
|
||||||
return s.authInfoStore.RunMetricsCollection(ctx)
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
package logintest
|
package authinfotest
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
@ -6,7 +6,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
)
|
)
|
||||||
|
|
||||||
type AuthInfoServiceFake struct {
|
type FakeService struct {
|
||||||
login.AuthInfoService
|
login.AuthInfoService
|
||||||
LatestUserID int64
|
LatestUserID int64
|
||||||
ExpectedUserAuth *login.UserAuth
|
ExpectedUserAuth *login.UserAuth
|
||||||
@ -18,16 +18,16 @@ type AuthInfoServiceFake struct {
|
|||||||
UpdateAuthInfoFn func(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error
|
UpdateAuthInfoFn func(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfoServiceFake) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
func (a *FakeService) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
||||||
a.LatestUserID = query.UserId
|
a.LatestUserID = query.UserId
|
||||||
return a.ExpectedUserAuth, a.ExpectedError
|
return a.ExpectedUserAuth, a.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfoServiceFake) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
func (a *FakeService) GetUserLabels(ctx context.Context, query login.GetUserLabelsQuery) (map[int64]string, error) {
|
||||||
return a.ExpectedLabels, a.ExpectedError
|
return a.ExpectedLabels, a.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfoServiceFake) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
func (a *FakeService) SetAuthInfo(ctx context.Context, cmd *login.SetAuthInfoCommand) error {
|
||||||
if a.SetAuthInfoFn != nil {
|
if a.SetAuthInfoFn != nil {
|
||||||
return a.SetAuthInfoFn(ctx, cmd)
|
return a.SetAuthInfoFn(ctx, cmd)
|
||||||
}
|
}
|
||||||
@ -35,7 +35,7 @@ func (a *AuthInfoServiceFake) SetAuthInfo(ctx context.Context, cmd *login.SetAut
|
|||||||
return a.ExpectedError
|
return a.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfoServiceFake) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
func (a *FakeService) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
||||||
if a.UpdateAuthInfoFn != nil {
|
if a.UpdateAuthInfoFn != nil {
|
||||||
return a.UpdateAuthInfoFn(ctx, cmd)
|
return a.UpdateAuthInfoFn(ctx, cmd)
|
||||||
}
|
}
|
||||||
@ -43,6 +43,6 @@ func (a *AuthInfoServiceFake) UpdateAuthInfo(ctx context.Context, cmd *login.Upd
|
|||||||
return a.ExpectedError
|
return a.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AuthInfoServiceFake) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
func (a *FakeService) DeleteUserAuthInfo(ctx context.Context, userID int64) error {
|
||||||
return a.ExpectedError
|
return a.ExpectedError
|
||||||
}
|
}
|
@ -2,10 +2,8 @@ package login
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus"
|
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
|
||||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||||
@ -14,30 +12,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
type LoginStats struct {
|
|
||||||
DuplicateUserEntries int `xorm:"duplicate_user_entries"`
|
|
||||||
MixedCasedUsers int `xorm:"mixed_cased_users"`
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
ExporterName = "grafana"
|
|
||||||
MetricsCollectionInterval = time.Hour * 4 // every 4 hours, indication of duplicate users
|
|
||||||
)
|
|
||||||
|
|
||||||
var (
|
|
||||||
// MStatDuplicateUserEntries is a indication metric gauge for number of users with duplicate emails or logins
|
|
||||||
MStatDuplicateUserEntries prometheus.Gauge
|
|
||||||
|
|
||||||
// MStatHasDuplicateEntries is a metric for if there is duplicate users
|
|
||||||
MStatHasDuplicateEntries prometheus.Gauge
|
|
||||||
|
|
||||||
// MStatMixedCasedUsers is a metric for if there is duplicate users
|
|
||||||
MStatMixedCasedUsers prometheus.Gauge
|
|
||||||
|
|
||||||
Once sync.Once
|
|
||||||
Initialised bool = false
|
|
||||||
)
|
|
||||||
|
|
||||||
type UserAuth struct {
|
type UserAuth struct {
|
||||||
Id int64
|
Id int64
|
||||||
UserId int64
|
UserId int64
|
||||||
|
@ -15,7 +15,7 @@ import (
|
|||||||
|
|
||||||
"github.com/grafana/grafana/pkg/login/socialtest"
|
"github.com/grafana/grafana/pkg/login/socialtest"
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
"github.com/grafana/grafana/pkg/services/login/authinfoservice"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
@ -229,7 +229,7 @@ func setupOAuthTokenService(t *testing.T) (*Service, *FakeAuthInfoStore, *social
|
|||||||
}
|
}
|
||||||
|
|
||||||
authInfoStore := &FakeAuthInfoStore{}
|
authInfoStore := &FakeAuthInfoStore{}
|
||||||
authInfoService := authinfoservice.ProvideAuthInfoService(authInfoStore)
|
authInfoService := authinfoimpl.ProvideService(authInfoStore)
|
||||||
return &Service{
|
return &Service{
|
||||||
Cfg: setting.NewCfg(),
|
Cfg: setting.NewCfg(),
|
||||||
SocialService: socialService,
|
SocialService: socialService,
|
||||||
@ -241,12 +241,8 @@ func setupOAuthTokenService(t *testing.T) (*Service, *FakeAuthInfoStore, *social
|
|||||||
|
|
||||||
type FakeAuthInfoStore struct {
|
type FakeAuthInfoStore struct {
|
||||||
login.Store
|
login.Store
|
||||||
ExpectedError error
|
ExpectedError error
|
||||||
ExpectedUser *user.User
|
ExpectedOAuth *login.UserAuth
|
||||||
ExpectedOAuth *login.UserAuth
|
|
||||||
ExpectedDuplicateUserEntries int
|
|
||||||
ExpectedHasDuplicateUserEntries int
|
|
||||||
ExpectedLoginStats login.LoginStats
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
func (f *FakeAuthInfoStore) GetAuthInfo(ctx context.Context, query *login.GetAuthInfoQuery) (*login.UserAuth, error) {
|
||||||
@ -257,10 +253,6 @@ func (f *FakeAuthInfoStore) SetAuthInfo(ctx context.Context, cmd *login.SetAuthI
|
|||||||
return f.ExpectedError
|
return f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) UpdateAuthInfoDate(ctx context.Context, authInfo *login.UserAuth) error {
|
|
||||||
return f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
func (f *FakeAuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *login.UpdateAuthInfoCommand) error {
|
||||||
f.ExpectedOAuth.OAuthAccessToken = cmd.OAuthToken.AccessToken
|
f.ExpectedOAuth.OAuthAccessToken = cmd.OAuthToken.AccessToken
|
||||||
f.ExpectedOAuth.OAuthExpiry = cmd.OAuthToken.Expiry
|
f.ExpectedOAuth.OAuthExpiry = cmd.OAuthToken.Expiry
|
||||||
@ -272,35 +264,3 @@ func (f *FakeAuthInfoStore) UpdateAuthInfo(ctx context.Context, cmd *login.Updat
|
|||||||
func (f *FakeAuthInfoStore) DeleteAuthInfo(ctx context.Context, cmd *login.DeleteAuthInfoCommand) error {
|
func (f *FakeAuthInfoStore) DeleteAuthInfo(ctx context.Context, cmd *login.DeleteAuthInfoCommand) error {
|
||||||
return f.ExpectedError
|
return f.ExpectedError
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) GetUserById(ctx context.Context, id int64) (*user.User, error) {
|
|
||||||
return f.ExpectedUser, f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) GetUserByLogin(ctx context.Context, login string) (*user.User, error) {
|
|
||||||
return f.ExpectedUser, f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) GetUserByEmail(ctx context.Context, email string) (*user.User, error) {
|
|
||||||
return f.ExpectedUser, f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) CollectLoginStats(ctx context.Context) (map[string]interface{}, error) {
|
|
||||||
var res = make(map[string]interface{})
|
|
||||||
res["stats.users.duplicate_user_entries"] = f.ExpectedDuplicateUserEntries
|
|
||||||
res["stats.users.has_duplicate_user_entries"] = f.ExpectedHasDuplicateUserEntries
|
|
||||||
res["stats.users.duplicate_user_entries_by_login"] = 0
|
|
||||||
res["stats.users.has_duplicate_user_entries_by_login"] = 0
|
|
||||||
res["stats.users.duplicate_user_entries_by_email"] = 0
|
|
||||||
res["stats.users.has_duplicate_user_entries_by_email"] = 0
|
|
||||||
res["stats.users.mixed_cased_users"] = f.ExpectedLoginStats.MixedCasedUsers
|
|
||||||
return res, f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) RunMetricsCollection(ctx context.Context) error {
|
|
||||||
return f.ExpectedError
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *FakeAuthInfoStore) GetLoginStats(ctx context.Context) (login.LoginStats, error) {
|
|
||||||
return f.ExpectedLoginStats, f.ExpectedError
|
|
||||||
}
|
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/login"
|
"github.com/grafana/grafana/pkg/services/login"
|
||||||
databaseAuthInfo "github.com/grafana/grafana/pkg/services/login/authinfoservice/database"
|
"github.com/grafana/grafana/pkg/services/login/authinfoimpl"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets/database"
|
"github.com/grafana/grafana/pkg/services/secrets/database"
|
||||||
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
|
secretsManager "github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||||
"github.com/grafana/grafana/pkg/services/user"
|
"github.com/grafana/grafana/pkg/services/user"
|
||||||
@ -129,7 +129,7 @@ func TestIntegrationIndexViewAnalytics(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(store))
|
secretsService := secretsManager.SetupTestService(t, database.ProvideSecretsStore(store))
|
||||||
authInfoStore := databaseAuthInfo.ProvideAuthInfoStore(store, secretsService, nil)
|
authInfoStore := authinfoimpl.ProvideStore(store, secretsService)
|
||||||
|
|
||||||
// insert user_auth relationship
|
// insert user_auth relationship
|
||||||
err := authInfoStore.SetAuthInfo(context.Background(), &login.SetAuthInfoCommand{
|
err := authInfoStore.SetAuthInfo(context.Background(), &login.SetAuthInfoCommand{
|
||||||
|
Loading…
Reference in New Issue
Block a user