mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 10:24:54 -06:00
Auth: Add SSO settings usage stats (#81143)
* Add usage stats * UsageStats test + svc rename * Fix test
This commit is contained in:
parent
c44594d6b3
commit
c47b55ae10
@ -73,7 +73,7 @@ func TestSocialService_ProvideService(t *testing.T) {
|
|||||||
accessControl := acimpl.ProvideAccessControl(cfg)
|
accessControl := acimpl.ProvideAccessControl(cfg)
|
||||||
sqlStore := db.InitTestDB(t)
|
sqlStore := db.InitTestDB(t)
|
||||||
|
|
||||||
ssoSettingsSvc := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routing.NewRouteRegister(), featuremgmt.WithFeatures(), secrets)
|
ssoSettingsSvc := ssosettingsimpl.ProvideService(cfg, sqlStore, accessControl, routing.NewRouteRegister(), featuremgmt.WithFeatures(), secrets, &usagestats.UsageStatsMock{})
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
@ -59,7 +59,7 @@ func ProvideBackgroundServiceRegistry(
|
|||||||
keyRetriever *dynamic.KeyRetriever, dynamicAngularDetectorsProvider *angulardetectorsprovider.Dynamic,
|
keyRetriever *dynamic.KeyRetriever, dynamicAngularDetectorsProvider *angulardetectorsprovider.Dynamic,
|
||||||
grafanaAPIServer grafanaapiserver.Service,
|
grafanaAPIServer grafanaapiserver.Service,
|
||||||
anon *anonimpl.AnonDeviceService,
|
anon *anonimpl.AnonDeviceService,
|
||||||
ssoSettings *ssosettingsimpl.SSOSettingsService,
|
ssoSettings *ssosettingsimpl.Service,
|
||||||
// Need to make sure these are initialized, is there a better place to put them?
|
// Need to make sure these are initialized, is there a better place to put them?
|
||||||
_ dashboardsnapshots.Service, _ *alerting.AlertNotificationService,
|
_ dashboardsnapshots.Service, _ *alerting.AlertNotificationService,
|
||||||
_ serviceaccounts.Service, _ *guardian.Provider,
|
_ serviceaccounts.Service, _ *guardian.Provider,
|
||||||
|
@ -380,7 +380,7 @@ var wireBasicSet = wire.NewSet(
|
|||||||
signingkeysimpl.ProvideEmbeddedSigningKeysService,
|
signingkeysimpl.ProvideEmbeddedSigningKeysService,
|
||||||
wire.Bind(new(signingkeys.Service), new(*signingkeysimpl.Service)),
|
wire.Bind(new(signingkeys.Service), new(*signingkeysimpl.Service)),
|
||||||
ssoSettingsImpl.ProvideService,
|
ssoSettingsImpl.ProvideService,
|
||||||
wire.Bind(new(ssosettings.Service), new(*ssoSettingsImpl.SSOSettingsService)),
|
wire.Bind(new(ssosettings.Service), new(*ssoSettingsImpl.Service)),
|
||||||
idimpl.ProvideService,
|
idimpl.ProvideService,
|
||||||
wire.Bind(new(auth.IDService), new(*idimpl.Service)),
|
wire.Bind(new(auth.IDService), new(*idimpl.Service)),
|
||||||
cloudmigrations.ProvideService,
|
cloudmigrations.ProvideService,
|
||||||
|
@ -11,6 +11,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/infra/db"
|
"github.com/grafana/grafana/pkg/infra/db"
|
||||||
"github.com/grafana/grafana/pkg/infra/log"
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||||
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
ac "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
||||||
"github.com/grafana/grafana/pkg/services/secrets"
|
"github.com/grafana/grafana/pkg/services/secrets"
|
||||||
@ -22,9 +23,9 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
var _ ssosettings.Service = (*SSOSettingsService)(nil)
|
var _ ssosettings.Service = (*Service)(nil)
|
||||||
|
|
||||||
type SSOSettingsService struct {
|
type Service struct {
|
||||||
logger log.Logger
|
logger log.Logger
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
store ssosettings.Store
|
store ssosettings.Store
|
||||||
@ -37,7 +38,7 @@ type SSOSettingsService struct {
|
|||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
||||||
routeRegister routing.RouteRegister, features featuremgmt.FeatureToggles,
|
routeRegister routing.RouteRegister, features featuremgmt.FeatureToggles,
|
||||||
secrets secrets.Service) *SSOSettingsService {
|
secrets secrets.Service, usageStats usagestats.Service) *Service {
|
||||||
strategies := []ssosettings.FallbackStrategy{
|
strategies := []ssosettings.FallbackStrategy{
|
||||||
strategies.NewOAuthStrategy(cfg),
|
strategies.NewOAuthStrategy(cfg),
|
||||||
// register other strategies here, for example SAML
|
// register other strategies here, for example SAML
|
||||||
@ -45,7 +46,7 @@ func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
|||||||
|
|
||||||
store := database.ProvideStore(sqlStore)
|
store := database.ProvideStore(sqlStore)
|
||||||
|
|
||||||
svc := &SSOSettingsService{
|
svc := &Service{
|
||||||
logger: log.New("ssosettings.service"),
|
logger: log.New("ssosettings.service"),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
store: store,
|
store: store,
|
||||||
@ -55,6 +56,8 @@ func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
|||||||
reloadables: make(map[string]ssosettings.Reloadable),
|
reloadables: make(map[string]ssosettings.Reloadable),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
usageStats.RegisterMetricsFunc(svc.getUsageStats)
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
||||||
ssoSettingsApi := api.ProvideApi(svc, routeRegister, ac)
|
ssoSettingsApi := api.ProvideApi(svc, routeRegister, ac)
|
||||||
ssoSettingsApi.RegisterAPIEndpoints()
|
ssoSettingsApi.RegisterAPIEndpoints()
|
||||||
@ -63,9 +66,9 @@ func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
|||||||
return svc
|
return svc
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ ssosettings.Service = (*SSOSettingsService)(nil)
|
var _ ssosettings.Service = (*Service)(nil)
|
||||||
|
|
||||||
func (s *SSOSettingsService) GetForProvider(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
func (s *Service) GetForProvider(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||||
dbSettings, err := s.store.Get(ctx, provider)
|
dbSettings, err := s.store.Get(ctx, provider)
|
||||||
if err != nil && !errors.Is(err, ssosettings.ErrNotFound) {
|
if err != nil && !errors.Is(err, ssosettings.ErrNotFound) {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -87,7 +90,7 @@ func (s *SSOSettingsService) GetForProvider(ctx context.Context, provider string
|
|||||||
return s.mergeSSOSettings(dbSettings, systemSettings), nil
|
return s.mergeSSOSettings(dbSettings, systemSettings), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) GetForProviderWithRedactedSecrets(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
func (s *Service) GetForProviderWithRedactedSecrets(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||||
if !s.isProviderConfigurable(provider) {
|
if !s.isProviderConfigurable(provider) {
|
||||||
return nil, ssosettings.ErrNotConfigurable
|
return nil, ssosettings.ErrNotConfigurable
|
||||||
}
|
}
|
||||||
@ -106,7 +109,7 @@ func (s *SSOSettingsService) GetForProviderWithRedactedSecrets(ctx context.Conte
|
|||||||
return storeSettings, nil
|
return storeSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) List(ctx context.Context) ([]*models.SSOSettings, error) {
|
func (s *Service) List(ctx context.Context) ([]*models.SSOSettings, error) {
|
||||||
result := make([]*models.SSOSettings, 0, len(ssosettings.AllOAuthProviders))
|
result := make([]*models.SSOSettings, 0, len(ssosettings.AllOAuthProviders))
|
||||||
storedSettings, err := s.store.List(ctx)
|
storedSettings, err := s.store.List(ctx)
|
||||||
|
|
||||||
@ -134,7 +137,7 @@ func (s *SSOSettingsService) List(ctx context.Context) ([]*models.SSOSettings, e
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) ListWithRedactedSecrets(ctx context.Context) ([]*models.SSOSettings, error) {
|
func (s *Service) ListWithRedactedSecrets(ctx context.Context) ([]*models.SSOSettings, error) {
|
||||||
storeSettings, err := s.List(ctx)
|
storeSettings, err := s.List(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -158,7 +161,7 @@ func (s *SSOSettingsService) ListWithRedactedSecrets(ctx context.Context) ([]*mo
|
|||||||
return configurableSettings, nil
|
return configurableSettings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) Upsert(ctx context.Context, settings *models.SSOSettings) error {
|
func (s *Service) Upsert(ctx context.Context, settings *models.SSOSettings) error {
|
||||||
if !s.isProviderConfigurable(settings.Provider) {
|
if !s.isProviderConfigurable(settings.Provider) {
|
||||||
return ssosettings.ErrNotConfigurable
|
return ssosettings.ErrNotConfigurable
|
||||||
}
|
}
|
||||||
@ -201,33 +204,33 @@ func (s *SSOSettingsService) Upsert(ctx context.Context, settings *models.SSOSet
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) Patch(ctx context.Context, provider string, data map[string]any) error {
|
func (s *Service) Patch(ctx context.Context, provider string, data map[string]any) error {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) Delete(ctx context.Context, provider string) error {
|
func (s *Service) Delete(ctx context.Context, provider string) error {
|
||||||
if !s.isProviderConfigurable(provider) {
|
if !s.isProviderConfigurable(provider) {
|
||||||
return ssosettings.ErrNotConfigurable
|
return ssosettings.ErrNotConfigurable
|
||||||
}
|
}
|
||||||
return s.store.Delete(ctx, provider)
|
return s.store.Delete(ctx, provider)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) Reload(ctx context.Context, provider string) {
|
func (s *Service) Reload(ctx context.Context, provider string) {
|
||||||
panic("not implemented") // TODO: Implement
|
panic("not implemented") // TODO: Implement
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) RegisterReloadable(provider string, reloadable ssosettings.Reloadable) {
|
func (s *Service) RegisterReloadable(provider string, reloadable ssosettings.Reloadable) {
|
||||||
if s.reloadables == nil {
|
if s.reloadables == nil {
|
||||||
s.reloadables = make(map[string]ssosettings.Reloadable)
|
s.reloadables = make(map[string]ssosettings.Reloadable)
|
||||||
}
|
}
|
||||||
s.reloadables[provider] = reloadable
|
s.reloadables[provider] = reloadable
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) RegisterFallbackStrategy(providerRegex string, strategy ssosettings.FallbackStrategy) {
|
func (s *Service) RegisterFallbackStrategy(providerRegex string, strategy ssosettings.FallbackStrategy) {
|
||||||
s.fbStrategies = append(s.fbStrategies, strategy)
|
s.fbStrategies = append(s.fbStrategies, strategy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) loadSettingsUsingFallbackStrategy(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
func (s *Service) loadSettingsUsingFallbackStrategy(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||||
loadStrategy, ok := s.getFallbackStrategyFor(provider)
|
loadStrategy, ok := s.getFallbackStrategyFor(provider)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("no fallback strategy found for provider: " + provider)
|
return nil, errors.New("no fallback strategy found for provider: " + provider)
|
||||||
@ -254,7 +257,7 @@ func getSettingByProvider(provider string, settings []*models.SSOSettings) *mode
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) getFallbackStrategyFor(provider string) (ssosettings.FallbackStrategy, bool) {
|
func (s *Service) getFallbackStrategyFor(provider string) (ssosettings.FallbackStrategy, bool) {
|
||||||
for _, strategy := range s.fbStrategies {
|
for _, strategy := range s.fbStrategies {
|
||||||
if strategy.IsMatch(provider) {
|
if strategy.IsMatch(provider) {
|
||||||
return strategy, true
|
return strategy, true
|
||||||
@ -263,7 +266,7 @@ func (s *SSOSettingsService) getFallbackStrategyFor(provider string) (ssosetting
|
|||||||
return nil, false
|
return nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) encryptSecrets(ctx context.Context, settings, storedSettings map[string]any) (map[string]any, error) {
|
func (s *Service) encryptSecrets(ctx context.Context, settings, storedSettings map[string]any) (map[string]any, error) {
|
||||||
result := make(map[string]any)
|
result := make(map[string]any)
|
||||||
for k, v := range settings {
|
for k, v := range settings {
|
||||||
if isSecret(k) && v != "" {
|
if isSecret(k) && v != "" {
|
||||||
@ -289,7 +292,7 @@ func (s *SSOSettingsService) encryptSecrets(ctx context.Context, settings, store
|
|||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) Run(ctx context.Context) error {
|
func (s *Service) Run(ctx context.Context) error {
|
||||||
interval := s.cfg.SSOSettingsReloadInterval
|
interval := s.cfg.SSOSettingsReloadInterval
|
||||||
if interval == 0 {
|
if interval == 0 {
|
||||||
return nil
|
return nil
|
||||||
@ -310,7 +313,7 @@ func (s *SSOSettingsService) Run(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) doReload(ctx context.Context) {
|
func (s *Service) doReload(ctx context.Context) {
|
||||||
s.logger.Debug("reloading SSO Settings for all providers")
|
s.logger.Debug("reloading SSO Settings for all providers")
|
||||||
|
|
||||||
settingsList, err := s.List(ctx)
|
settingsList, err := s.List(ctx)
|
||||||
@ -333,7 +336,7 @@ func (s *SSOSettingsService) doReload(ctx context.Context) {
|
|||||||
// mergeSSOSettings merges the settings from the database with the system settings
|
// mergeSSOSettings merges the settings from the database with the system settings
|
||||||
// Required because it is possible that the user has configured some of the settings (current Advanced OAuth settings)
|
// Required because it is possible that the user has configured some of the settings (current Advanced OAuth settings)
|
||||||
// and the rest of the settings have to be loaded from the system settings
|
// and the rest of the settings have to be loaded from the system settings
|
||||||
func (s *SSOSettingsService) mergeSSOSettings(dbSettings, systemSettings *models.SSOSettings) *models.SSOSettings {
|
func (s *Service) mergeSSOSettings(dbSettings, systemSettings *models.SSOSettings) *models.SSOSettings {
|
||||||
if dbSettings == nil {
|
if dbSettings == nil {
|
||||||
s.logger.Debug("No SSO Settings found in the database, using system settings")
|
s.logger.Debug("No SSO Settings found in the database, using system settings")
|
||||||
return systemSettings
|
return systemSettings
|
||||||
@ -352,7 +355,7 @@ func (s *SSOSettingsService) mergeSSOSettings(dbSettings, systemSettings *models
|
|||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) decryptSecrets(ctx context.Context, settings map[string]any) (map[string]any, error) {
|
func (s *Service) decryptSecrets(ctx context.Context, settings map[string]any) (map[string]any, error) {
|
||||||
for k, v := range settings {
|
for k, v := range settings {
|
||||||
if isSecret(k) && v != "" {
|
if isSecret(k) && v != "" {
|
||||||
strValue, ok := v.(string)
|
strValue, ok := v.(string)
|
||||||
@ -379,7 +382,7 @@ func (s *SSOSettingsService) decryptSecrets(ctx context.Context, settings map[st
|
|||||||
return settings, nil
|
return settings, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SSOSettingsService) isProviderConfigurable(provider string) bool {
|
func (s *Service) isProviderConfigurable(provider string) bool {
|
||||||
_, ok := s.cfg.SSOSettingsConfigurableProviders[provider]
|
_, ok := s.cfg.SSOSettingsConfigurableProviders[provider]
|
||||||
return ok
|
return ok
|
||||||
}
|
}
|
||||||
|
@ -24,7 +24,7 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestSSOSettingsService_GetForProvider(t *testing.T) {
|
func TestService_GetForProvider(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(env testEnv)
|
setup func(env testEnv)
|
||||||
@ -205,7 +205,7 @@ func TestSSOSettingsService_GetForProvider(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_GetForProviderWithRedactedSecrets(t *testing.T) {
|
func TestService_GetForProviderWithRedactedSecrets(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(env testEnv)
|
setup func(env testEnv)
|
||||||
@ -304,7 +304,7 @@ func TestSSOSettingsService_GetForProviderWithRedactedSecrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_List(t *testing.T) {
|
func TestService_List(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(env testEnv)
|
setup func(env testEnv)
|
||||||
@ -447,7 +447,7 @@ func TestSSOSettingsService_List(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_ListWithRedactedSecrets(t *testing.T) {
|
func TestService_ListWithRedactedSecrets(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(env testEnv)
|
setup func(env testEnv)
|
||||||
@ -741,7 +741,7 @@ func TestSSOSettingsService_ListWithRedactedSecrets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_Upsert(t *testing.T) {
|
func TestService_Upsert(t *testing.T) {
|
||||||
t.Run("successfully upsert SSO settings", func(t *testing.T) {
|
t.Run("successfully upsert SSO settings", func(t *testing.T) {
|
||||||
env := setupTestEnv(t)
|
env := setupTestEnv(t)
|
||||||
|
|
||||||
@ -1003,7 +1003,7 @@ func TestSSOSettingsService_Upsert(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_Delete(t *testing.T) {
|
func TestService_Delete(t *testing.T) {
|
||||||
t.Run("successfully delete SSO settings", func(t *testing.T) {
|
t.Run("successfully delete SSO settings", func(t *testing.T) {
|
||||||
env := setupTestEnv(t)
|
env := setupTestEnv(t)
|
||||||
|
|
||||||
@ -1048,7 +1048,7 @@ func TestSSOSettingsService_Delete(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_DoReload(t *testing.T) {
|
func TestService_DoReload(t *testing.T) {
|
||||||
t.Run("successfully reload settings", func(t *testing.T) {
|
t.Run("successfully reload settings", func(t *testing.T) {
|
||||||
env := setupTestEnv(t)
|
env := setupTestEnv(t)
|
||||||
|
|
||||||
@ -1101,7 +1101,7 @@ func TestSSOSettingsService_DoReload(t *testing.T) {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSSOSettingsService_decryptSecrets(t *testing.T) {
|
func TestService_decryptSecrets(t *testing.T) {
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(env testEnv)
|
setup func(env testEnv)
|
||||||
@ -1216,7 +1216,7 @@ func setupTestEnv(t *testing.T) testEnv {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
svc := &SSOSettingsService{
|
svc := &Service{
|
||||||
logger: log.NewNopLogger(),
|
logger: log.NewNopLogger(),
|
||||||
cfg: cfg,
|
cfg: cfg,
|
||||||
store: store,
|
store: store,
|
||||||
@ -1239,7 +1239,7 @@ func setupTestEnv(t *testing.T) testEnv {
|
|||||||
|
|
||||||
type testEnv struct {
|
type testEnv struct {
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
service *SSOSettingsService
|
service *Service
|
||||||
store *ssosettingstests.FakeStore
|
store *ssosettingstests.FakeStore
|
||||||
ac accesscontrol.AccessControl
|
ac accesscontrol.AccessControl
|
||||||
fallbackStrategy *ssosettingstests.FakeFallbackStrategy
|
fallbackStrategy *ssosettingstests.FakeFallbackStrategy
|
||||||
|
30
pkg/services/ssosettings/ssosettingsimpl/usage_stats.go
Normal file
30
pkg/services/ssosettings/ssosettingsimpl/usage_stats.go
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
package ssosettingsimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (s *Service) getUsageStats(ctx context.Context) (map[string]any, error) {
|
||||||
|
m := map[string]any{}
|
||||||
|
|
||||||
|
settings, err := s.store.List(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
configuredInDbCounter := 0
|
||||||
|
for _, setting := range settings {
|
||||||
|
enabledValue := 0
|
||||||
|
if setting.Source == models.DB {
|
||||||
|
configuredInDbCounter++
|
||||||
|
enabledValue = 1
|
||||||
|
}
|
||||||
|
m["stats.sso."+setting.Provider+".config.database.count"] = enabledValue
|
||||||
|
}
|
||||||
|
|
||||||
|
m["stats.sso.configured_in_db.count"] = configuredInDbCounter
|
||||||
|
|
||||||
|
return m, nil
|
||||||
|
}
|
68
pkg/services/ssosettings/ssosettingsimpl/usage_stats_test.go
Normal file
68
pkg/services/ssosettings/ssosettingsimpl/usage_stats_test.go
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
package ssosettingsimpl
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/infra/log"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ssosettings/ssosettingstests"
|
||||||
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
|
"github.com/stretchr/testify/require"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestService_getUsageStats(t *testing.T) {
|
||||||
|
fakeStore := &ssosettingstests.FakeStore{
|
||||||
|
ExpectedSSOSettings: []*models.SSOSettings{
|
||||||
|
{
|
||||||
|
Provider: "google",
|
||||||
|
Source: models.DB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "github",
|
||||||
|
Source: models.System,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "grafana_com",
|
||||||
|
Source: models.System,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "generic_oauth",
|
||||||
|
Source: models.DB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "okta",
|
||||||
|
Source: models.DB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "azuread",
|
||||||
|
Source: models.DB,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Provider: "gitlab",
|
||||||
|
Source: models.DB,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
svc := &Service{
|
||||||
|
logger: log.New("test"),
|
||||||
|
store: fakeStore,
|
||||||
|
cfg: &setting.Cfg{},
|
||||||
|
}
|
||||||
|
|
||||||
|
actual, err := svc.getUsageStats(context.Background())
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
expected := map[string]any{
|
||||||
|
"stats.sso.configured_in_db.count": 5,
|
||||||
|
"stats.sso.azuread.config.database.count": 1,
|
||||||
|
"stats.sso.gitlab.config.database.count": 1,
|
||||||
|
"stats.sso.google.config.database.count": 1,
|
||||||
|
"stats.sso.okta.config.database.count": 1,
|
||||||
|
"stats.sso.generic_oauth.config.database.count": 1,
|
||||||
|
"stats.sso.grafana_com.config.database.count": 0,
|
||||||
|
"stats.sso.github.config.database.count": 0,
|
||||||
|
}
|
||||||
|
|
||||||
|
require.EqualValues(t, expected, actual)
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user