mirror of
https://github.com/grafana/grafana.git
synced 2025-09-17 15:32:52 +08:00
Auth: Remove ssoSettingsApi feature toggle (#107528)
* Remove ssoSettingsApi feature toggle * Clean up * lint * Fix tests
This commit is contained in:
@ -50,7 +50,6 @@ Most [generally available](https://grafana.com/docs/release-life-cycle/#general-
|
|||||||
| `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | Yes |
|
| `dashboardSceneForViewers` | Enables dashboard rendering using Scenes for viewer roles | Yes |
|
||||||
| `dashboardSceneSolo` | Enables rendering dashboards using scenes for solo panels | Yes |
|
| `dashboardSceneSolo` | Enables rendering dashboards using scenes for solo panels | Yes |
|
||||||
| `dashboardScene` | Enables dashboard rendering using scenes for all roles | Yes |
|
| `dashboardScene` | Enables dashboard rendering using scenes for all roles | Yes |
|
||||||
| `ssoSettingsApi` | Enables the SSO settings API and the OAuth configuration UIs in Grafana | Yes |
|
|
||||||
| `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | Yes |
|
| `logsInfiniteScrolling` | Enables infinite scrolling for the Logs panel in Explore and Dashboards | Yes |
|
||||||
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
|
| `logRowsPopoverMenu` | Enable filtering menu displayed when text of a log line is selected | Yes |
|
||||||
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
|
| `alertingQueryOptimization` | Optimizes eligible queries in order to reduce load on datasources | |
|
||||||
|
@ -393,11 +393,6 @@ export interface FeatureToggles {
|
|||||||
*/
|
*/
|
||||||
pdfTables?: boolean;
|
pdfTables?: boolean;
|
||||||
/**
|
/**
|
||||||
* Enables the SSO settings API and the OAuth configuration UIs in Grafana
|
|
||||||
* @default true
|
|
||||||
*/
|
|
||||||
ssoSettingsApi?: boolean;
|
|
||||||
/**
|
|
||||||
* Allow pan and zoom in canvas panel
|
* Allow pan and zoom in canvas panel
|
||||||
*/
|
*/
|
||||||
canvasPanelPanZoom?: boolean;
|
canvasPanelPanZoom?: boolean;
|
||||||
|
@ -254,18 +254,15 @@ func (hs *HTTPServer) registerRoutes() {
|
|||||||
|
|
||||||
adminAuthPageEvaluator := func() ac.Evaluator {
|
adminAuthPageEvaluator := func() ac.Evaluator {
|
||||||
authnSettingsEval := ssoutils.EvalAuthenticationSettings(hs.Cfg)
|
authnSettingsEval := ssoutils.EvalAuthenticationSettings(hs.Cfg)
|
||||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
|
||||||
return ac.EvalAny(authnSettingsEval, ssoutils.OauthSettingsEvaluator(hs.Cfg))
|
return ac.EvalAny(authnSettingsEval, ssoutils.OauthSettingsEvaluator(hs.Cfg))
|
||||||
}
|
|
||||||
return authnSettingsEval
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r.Get("/admin/authentication", authorize(adminAuthPageEvaluator()), hs.Index)
|
r.Get("/admin/authentication", authorize(adminAuthPageEvaluator()), hs.Index)
|
||||||
r.Get("/admin/authentication/ldap", authorize(ac.EvalPermission(ac.ActionLDAPStatusRead)), hs.Index)
|
r.Get("/admin/authentication/ldap", authorize(ac.EvalPermission(ac.ActionLDAPStatusRead)), hs.Index)
|
||||||
if hs.Features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
|
||||||
providerParam := ac.Parameter(":provider")
|
providerParam := ac.Parameter(":provider")
|
||||||
r.Get("/admin/authentication/:provider", authorize(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsOAuth(providerParam))), hs.Index)
|
r.Get("/admin/authentication/:provider", authorize(ac.EvalPermission(ac.ActionSettingsRead, ac.ScopeSettingsOAuth(providerParam))), hs.Index)
|
||||||
}
|
|
||||||
|
|
||||||
// authed api
|
// authed api
|
||||||
r.Group("/api", func(apiRoute routing.RouteRegister) {
|
r.Group("/api", func(apiRoute routing.RouteRegister) {
|
||||||
|
@ -99,7 +99,7 @@ func setupTestEnvironment(t *testing.T, cfg *setting.Cfg, features featuremgmt.F
|
|||||||
pluginsCDNService: pluginsCDN,
|
pluginsCDNService: pluginsCDN,
|
||||||
pluginAssets: pluginsAssets,
|
pluginAssets: pluginsAssets,
|
||||||
namespacer: request.GetNamespaceMapper(cfg),
|
namespacer: request.GetNamespaceMapper(cfg),
|
||||||
SocialService: socialimpl.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeCacheStorage(), nil, &ssosettingstests.MockService{}),
|
SocialService: socialimpl.ProvideService(cfg, features, &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeCacheStorage(), nil, ssosettingstests.NewFakeService()),
|
||||||
managedPluginsService: managedplugins.NewNoop(),
|
managedPluginsService: managedplugins.NewNoop(),
|
||||||
tracer: tracing.InitializeTracerForTest(),
|
tracer: tracing.InitializeTracerForTest(),
|
||||||
DataSourcesService: &datafakes.FakeDataSourceService{},
|
DataSourcesService: &datafakes.FakeDataSourceService{},
|
||||||
|
@ -106,9 +106,7 @@ func NewAzureADProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapper
|
|||||||
appendUniqueScope(provider.Config, social.OfflineAccessScope)
|
appendUniqueScope(provider.Config, social.OfflineAccessScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.AzureADProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.AzureADProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -841,7 +841,7 @@ func TestSocialAzureAD_UserInfo(t *testing.T) {
|
|||||||
tt.fields.cfg,
|
tt.fields.cfg,
|
||||||
ProvideOrgRoleMapper(tt.fields.cfg,
|
ProvideOrgRoleMapper(tt.fields.cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures(),
|
featuremgmt.WithFeatures(),
|
||||||
cache)
|
cache)
|
||||||
|
|
||||||
@ -1019,7 +1019,7 @@ func TestSocialAzureAD_SkipOrgRole(t *testing.T) {
|
|||||||
tt.fields.cfg,
|
tt.fields.cfg,
|
||||||
ProvideOrgRoleMapper(tt.fields.cfg,
|
ProvideOrgRoleMapper(tt.fields.cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures(),
|
featuremgmt.WithFeatures(),
|
||||||
cache)
|
cache)
|
||||||
|
|
||||||
@ -1119,7 +1119,7 @@ func TestSocialAzureAD_InitializeExtraFields(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) {
|
||||||
s := NewAzureADProvider(tc.settings, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures(), nil)
|
s := NewAzureADProvider(tc.settings, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures(), nil)
|
||||||
|
|
||||||
require.Equal(t, tc.want.forceUseGraphAPI, s.forceUseGraphAPI)
|
require.Equal(t, tc.want.forceUseGraphAPI, s.forceUseGraphAPI)
|
||||||
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
||||||
@ -1280,7 +1280,7 @@ func TestSocialAzureAD_Validate(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) {
|
||||||
s := NewAzureADProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures(), nil)
|
s := NewAzureADProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures(), nil)
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -1360,7 +1360,7 @@ func TestSocialAzureAD_Reload(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) {
|
||||||
s := NewAzureADProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures(), nil)
|
s := NewAzureADProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures(), nil)
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
@ -1417,7 +1417,7 @@ func TestSocialAzureAD_Reload_ExtraFields(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) {
|
||||||
s := NewAzureADProvider(tc.info, setting.NewCfg(), nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures(), remotecache.FakeCacheStorage{})
|
s := NewAzureADProvider(tc.info, setting.NewCfg(), nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures(), remotecache.FakeCacheStorage{})
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -79,9 +79,7 @@ func NewGenericOAuthProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMa
|
|||||||
allowedOrganizations: allowedOrganizations,
|
allowedOrganizations: allowedOrganizations,
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.GenericOAuthProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.GenericOAuthProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -458,7 +458,7 @@ func TestUserInfoSearchesForEmailAndOrgRoles(t *testing.T) {
|
|||||||
EmailAttributePath: "email",
|
EmailAttributePath: "email",
|
||||||
}, cfg,
|
}, cfg,
|
||||||
orgRoleMapper,
|
orgRoleMapper,
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
provider.info.RoleAttributePath = tc.RoleAttributePath
|
provider.info.RoleAttributePath = tc.RoleAttributePath
|
||||||
@ -507,7 +507,7 @@ func TestUserInfoSearchesForEmailAndOrgRoles(t *testing.T) {
|
|||||||
EmailAttributePath: "email",
|
EmailAttributePath: "email",
|
||||||
}, cfg,
|
}, cfg,
|
||||||
orgRoleMapper,
|
orgRoleMapper,
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
body, err := json.Marshal(map[string]any{"info": map[string]any{"roles": []string{"engineering", "SRE"}}})
|
body, err := json.Marshal(map[string]any{"info": map[string]any{"roles": []string{"engineering", "SRE"}}})
|
||||||
@ -600,7 +600,7 @@ func TestUserInfoSearchesForLogin(t *testing.T) {
|
|||||||
},
|
},
|
||||||
}, setting.NewCfg(),
|
}, setting.NewCfg(),
|
||||||
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -700,7 +700,7 @@ func TestUserInfoSearchesForName(t *testing.T) {
|
|||||||
},
|
},
|
||||||
setting.NewCfg(),
|
setting.NewCfg(),
|
||||||
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
@ -782,7 +782,7 @@ func TestUserInfoSearchesForGroup(t *testing.T) {
|
|||||||
ApiUrl: ts.URL,
|
ApiUrl: ts.URL,
|
||||||
}, setting.NewCfg(),
|
}, setting.NewCfg(),
|
||||||
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
ProvideOrgRoleMapper(setting.NewCfg(), orgtest.NewOrgServiceFake()),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
token := &oauth2.Token{
|
token := &oauth2.Token{
|
||||||
@ -802,7 +802,7 @@ func TestUserInfoSearchesForGroup(t *testing.T) {
|
|||||||
func TestPayloadCompression(t *testing.T) {
|
func TestPayloadCompression(t *testing.T) {
|
||||||
provider := NewGenericOAuthProvider(&social.OAuthInfo{
|
provider := NewGenericOAuthProvider(&social.OAuthInfo{
|
||||||
EmailAttributePath: "email",
|
EmailAttributePath: "email",
|
||||||
}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
Name string
|
Name string
|
||||||
@ -957,7 +957,7 @@ func TestSocialGenericOAuth_InitializeExtraFields(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) {
|
||||||
s := NewGenericOAuthProvider(tc.settings, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGenericOAuthProvider(tc.settings, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
require.Equal(t, tc.want.nameAttributePath, s.nameAttributePath)
|
require.Equal(t, tc.want.nameAttributePath, s.nameAttributePath)
|
||||||
require.Equal(t, tc.want.loginAttributePath, s.loginAttributePath)
|
require.Equal(t, tc.want.loginAttributePath, s.loginAttributePath)
|
||||||
@ -1176,7 +1176,7 @@ func TestSocialGenericOAuth_Validate(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) {
|
||||||
s := NewGenericOAuthProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGenericOAuthProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -1256,7 +1256,7 @@ func TestSocialGenericOAuth_Reload(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) {
|
||||||
s := NewGenericOAuthProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGenericOAuthProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
@ -1354,7 +1354,7 @@ func TestGenericOAuth_Reload_ExtraFields(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) {
|
||||||
s := NewGenericOAuthProvider(tc.info, setting.NewCfg(), nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGenericOAuthProvider(tc.info, setting.NewCfg(), nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -85,9 +85,7 @@ func NewGitHubProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapper *
|
|||||||
provider.log.Warn("Failed to parse team ids. Team ids must be a list of numbers.", "teamIds", teamIdsSplitted)
|
provider.log.Warn("Failed to parse team ids. Team ids must be a list of numbers.", "teamIds", teamIdsSplitted)
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.GitHubProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.GitHubProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -390,7 +390,7 @@ func TestSocialGitHub_UserInfo(t *testing.T) {
|
|||||||
}, cfg,
|
}, cfg,
|
||||||
ProvideOrgRoleMapper(cfg,
|
ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
token := &oauth2.Token{
|
token := &oauth2.Token{
|
||||||
@ -471,7 +471,7 @@ func TestSocialGitHub_InitializeExtraFields(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) {
|
||||||
s := NewGitHubProvider(tc.settings, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitHubProvider(tc.settings, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
require.Equal(t, tc.want.teamIds, s.teamIds)
|
require.Equal(t, tc.want.teamIds, s.teamIds)
|
||||||
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
||||||
@ -598,7 +598,7 @@ func TestSocialGitHub_Validate(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) {
|
||||||
s := NewGitHubProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitHubProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -679,7 +679,7 @@ func TestSocialGitHub_Reload(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) {
|
||||||
s := NewGitHubProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitHubProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
@ -738,7 +738,7 @@ func TestGitHub_Reload_ExtraFields(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) {
|
||||||
s := NewGitHubProvider(tc.info, setting.NewCfg(), nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitHubProvider(tc.info, setting.NewCfg(), nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -57,9 +57,7 @@ func NewGitLabProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapper *
|
|||||||
SocialBase: newSocialBase(social.GitlabProviderName, orgRoleMapper, info, features, cfg),
|
SocialBase: newSocialBase(social.GitlabProviderName, orgRoleMapper, info, features, cfg),
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.GitlabProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.GitlabProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -209,7 +209,7 @@ func TestSocialGitlab_UserInfo(t *testing.T) {
|
|||||||
SkipOrgRoleSync: tt.Cfg.SkipOrgRoleSync,
|
SkipOrgRoleSync: tt.Cfg.SkipOrgRoleSync,
|
||||||
OrgMapping: tt.Cfg.OrgMapping,
|
OrgMapping: tt.Cfg.OrgMapping,
|
||||||
// OrgAttributePath: "",
|
// OrgAttributePath: "",
|
||||||
}, cfg, orgMapper, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
}, cfg, orgMapper, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
w.Header().Set("Content-Type", "application/json")
|
w.Header().Set("Content-Type", "application/json")
|
||||||
@ -398,7 +398,7 @@ func TestSocialGitlab_extractFromToken(t *testing.T) {
|
|||||||
},
|
},
|
||||||
&setting.Cfg{
|
&setting.Cfg{
|
||||||
AutoAssignOrgRole: "",
|
AutoAssignOrgRole: "",
|
||||||
}, nil, &ssosettingstests.MockService{},
|
}, nil, ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
// Test case: successful extraction
|
// Test case: successful extraction
|
||||||
@ -489,7 +489,7 @@ func TestSocialGitlab_GetGroupsNextPage(t *testing.T) {
|
|||||||
defer mockServer.Close()
|
defer mockServer.Close()
|
||||||
|
|
||||||
// Create a SocialGitlab instance with the mock server URL
|
// Create a SocialGitlab instance with the mock server URL
|
||||||
s := NewGitLabProvider(&social.OAuthInfo{ApiUrl: mockServer.URL}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitLabProvider(&social.OAuthInfo{ApiUrl: mockServer.URL}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
// Call getGroups and verify that it returns all groups
|
// Call getGroups and verify that it returns all groups
|
||||||
expectedGroups := []string{"admins", "editors", "viewers", "serveradmins"}
|
expectedGroups := []string{"admins", "editors", "viewers", "serveradmins"}
|
||||||
@ -611,7 +611,7 @@ func TestSocialGitlab_Validate(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) {
|
||||||
s := NewGitLabProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitLabProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -692,7 +692,7 @@ func TestSocialGitlab_Reload(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) {
|
||||||
s := NewGitLabProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGitLabProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
|
@ -58,9 +58,7 @@ func NewGoogleProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapper *
|
|||||||
provider.log.Warn("Using legacy Google API URL, please update your configuration")
|
provider.log.Warn("Using legacy Google API URL, please update your configuration")
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.GoogleProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.GoogleProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ func TestSocialGoogle_retrieveGroups(t *testing.T) {
|
|||||||
AutoAssignOrgRole: "",
|
AutoAssignOrgRole: "",
|
||||||
},
|
},
|
||||||
nil,
|
nil,
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
got, err := s.retrieveGroups(context.Background(), tt.args.client, tt.args.userData)
|
got, err := s.retrieveGroups(context.Background(), tt.args.client, tt.args.userData)
|
||||||
@ -693,7 +693,7 @@ func TestSocialGoogle_UserInfo(t *testing.T) {
|
|||||||
},
|
},
|
||||||
cfg,
|
cfg,
|
||||||
ProvideOrgRoleMapper(cfg, &orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
ProvideOrgRoleMapper(cfg, &orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
gotData, err := s.UserInfo(context.Background(), tt.args.client, tt.args.token)
|
gotData, err := s.UserInfo(context.Background(), tt.args.client, tt.args.token)
|
||||||
@ -834,7 +834,7 @@ func TestSocialGoogle_Validate(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) {
|
||||||
s := NewGoogleProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGoogleProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -915,7 +915,7 @@ func TestSocialGoogle_Reload(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) {
|
||||||
s := NewGoogleProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGoogleProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
@ -968,7 +968,7 @@ func TestIsHDAllowed(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
info := &social.OAuthInfo{}
|
info := &social.OAuthInfo{}
|
||||||
info.AllowedDomains = tc.allowedDomains
|
info.AllowedDomains = tc.allowedDomains
|
||||||
s := NewGoogleProvider(info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGoogleProvider(info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
s.validateHD = tc.validateHD
|
s.validateHD = tc.validateHD
|
||||||
err := s.isHDAllowed(tc.email)
|
err := s.isHDAllowed(tc.email)
|
||||||
|
|
||||||
|
@ -57,9 +57,7 @@ func NewGrafanaComProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapp
|
|||||||
allowedOrganizations: allowedOrganizations,
|
allowedOrganizations: allowedOrganizations,
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.GrafanaComProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.GrafanaComProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ func TestSocialGrafanaCom_UserInfo(t *testing.T) {
|
|||||||
provider := NewGrafanaComProvider(social.NewOAuthInfo(),
|
provider := NewGrafanaComProvider(social.NewOAuthInfo(),
|
||||||
cfg,
|
cfg,
|
||||||
ProvideOrgRoleMapper(cfg, &orgtest.FakeOrgService{}),
|
ProvideOrgRoleMapper(cfg, &orgtest.FakeOrgService{}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
type conf struct {
|
type conf struct {
|
||||||
@ -140,7 +140,7 @@ func TestSocialGrafanaCom_InitializeExtraFields(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) {
|
||||||
s := NewGrafanaComProvider(tc.settings, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGrafanaComProvider(tc.settings, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
require.Equal(t, tc.want.allowedOrganizations, s.allowedOrganizations)
|
||||||
})
|
})
|
||||||
@ -209,7 +209,7 @@ func TestSocialGrafanaCom_Validate(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) {
|
||||||
s := NewGrafanaComProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGrafanaComProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -309,7 +309,7 @@ func TestSocialGrafanaCom_Reload(t *testing.T) {
|
|||||||
cfg := &setting.Cfg{
|
cfg := &setting.Cfg{
|
||||||
GrafanaComURL: GrafanaComURL,
|
GrafanaComURL: GrafanaComURL,
|
||||||
}
|
}
|
||||||
s := NewGrafanaComProvider(tc.info, cfg, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGrafanaComProvider(tc.info, cfg, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
@ -370,7 +370,7 @@ func TestSocialGrafanaCom_Reload_ExtraFields(t *testing.T) {
|
|||||||
cfg := &setting.Cfg{
|
cfg := &setting.Cfg{
|
||||||
GrafanaComURL: GrafanaComURL,
|
GrafanaComURL: GrafanaComURL,
|
||||||
}
|
}
|
||||||
s := NewGrafanaComProvider(tc.info, cfg, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewGrafanaComProvider(tc.info, cfg, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -54,9 +54,7 @@ func NewOktaProvider(info *social.OAuthInfo, cfg *setting.Cfg, orgRoleMapper *Or
|
|||||||
appendUniqueScope(provider.Config, social.OfflineAccessScope)
|
appendUniqueScope(provider.Config, social.OfflineAccessScope)
|
||||||
}
|
}
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettings.RegisterReloadable(social.OktaProviderName, provider)
|
||||||
ssoSettings.RegisterReloadable(social.OktaProviderName, provider)
|
|
||||||
}
|
|
||||||
|
|
||||||
return provider
|
return provider
|
||||||
}
|
}
|
||||||
|
@ -200,7 +200,7 @@ func TestSocialOkta_UserInfo(t *testing.T) {
|
|||||||
cfg,
|
cfg,
|
||||||
ProvideOrgRoleMapper(cfg,
|
ProvideOrgRoleMapper(cfg,
|
||||||
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
&orgtest.FakeOrgService{ExpectedOrgs: []*org.OrgDTO{{ID: 4, Name: "Org4"}, {ID: 5, Name: "Org5"}}}),
|
||||||
&ssosettingstests.MockService{},
|
ssosettingstests.NewFakeService(),
|
||||||
featuremgmt.WithFeatures())
|
featuremgmt.WithFeatures())
|
||||||
|
|
||||||
// create a oauth2 token with a id_token
|
// create a oauth2 token with a id_token
|
||||||
@ -372,7 +372,7 @@ func TestSocialOkta_Validate(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) {
|
||||||
s := NewOktaProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewOktaProvider(&social.OAuthInfo{}, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
if tc.requester == nil {
|
if tc.requester == nil {
|
||||||
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
tc.requester = &user.SignedInUser{IsGrafanaAdmin: false}
|
||||||
@ -452,7 +452,7 @@ func TestSocialOkta_Reload(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) {
|
||||||
s := NewOktaProvider(tc.info, &setting.Cfg{}, nil, &ssosettingstests.MockService{}, featuremgmt.WithFeatures())
|
s := NewOktaProvider(tc.info, &setting.Cfg{}, nil, ssosettingstests.NewFakeService(), featuremgmt.WithFeatures())
|
||||||
|
|
||||||
err := s.Reload(context.Background(), tc.settings)
|
err := s.Reload(context.Background(), tc.settings)
|
||||||
if tc.expectError {
|
if tc.expectError {
|
||||||
|
@ -25,11 +25,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
|
||||||
allOauthes = []string{social.GitHubProviderName, social.GitlabProviderName, social.GoogleProviderName, social.GenericOAuthProviderName, social.GrafanaNetProviderName,
|
|
||||||
social.GrafanaComProviderName, social.AzureADProviderName, social.OktaProviderName}
|
|
||||||
)
|
|
||||||
|
|
||||||
type SocialService struct {
|
type SocialService struct {
|
||||||
cfg *setting.Cfg
|
cfg *setting.Cfg
|
||||||
|
|
||||||
@ -53,56 +48,30 @@ func ProvideService(cfg *setting.Cfg,
|
|||||||
|
|
||||||
usageStats.RegisterMetricsFunc(ss.getUsageStats)
|
usageStats.RegisterMetricsFunc(ss.getUsageStats)
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
allSettings, err := ssoSettings.List(context.Background())
|
||||||
allSettings, err := ssoSettings.List(context.Background())
|
if err != nil {
|
||||||
|
ss.log.Error("Failed to get SSO settings", "error", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, ssoSetting := range allSettings {
|
||||||
|
// ignore non-oauth2 providers
|
||||||
|
if !slices.Contains(ssosettings.AllOAuthProviders, ssoSetting.Provider) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
info, err := connectors.CreateOAuthInfoFromKeyValuesWithLogging(ss.log, ssoSetting.Provider, ssoSetting.Settings)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ss.log.Error("Failed to get SSO settings", "error", err)
|
ss.log.Error("Failed to create OAuthInfo for provider", "error", err, "provider", ssoSetting.Provider)
|
||||||
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, ssoSetting := range allSettings {
|
conn, err := createOAuthConnector(ssoSetting.Provider, info, cfg, orgRoleMapper, ssoSettings, features, cache)
|
||||||
// ignore non-oauth2 providers
|
if err != nil {
|
||||||
if !slices.Contains(ssosettings.AllOAuthProviders, ssoSetting.Provider) {
|
ss.log.Error("Failed to create OAuth provider", "error", err, "provider", ssoSetting.Provider)
|
||||||
continue
|
continue
|
||||||
}
|
|
||||||
|
|
||||||
info, err := connectors.CreateOAuthInfoFromKeyValuesWithLogging(ss.log, ssoSetting.Provider, ssoSetting.Settings)
|
|
||||||
if err != nil {
|
|
||||||
ss.log.Error("Failed to create OAuthInfo for provider", "error", err, "provider", ssoSetting.Provider)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, err := createOAuthConnector(ssoSetting.Provider, info, cfg, orgRoleMapper, ssoSettings, features, cache)
|
|
||||||
if err != nil {
|
|
||||||
ss.log.Error("Failed to create OAuth provider", "error", err, "provider", ssoSetting.Provider)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ss.socialMap[ssoSetting.Provider] = conn
|
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
for _, name := range allOauthes {
|
|
||||||
sec := cfg.Raw.Section("auth." + name)
|
|
||||||
|
|
||||||
settingsKVs := convertIniSectionToMap(sec)
|
ss.socialMap[ssoSetting.Provider] = conn
|
||||||
|
|
||||||
info, err := connectors.CreateOAuthInfoFromKeyValuesWithLogging(ss.log, name, settingsKVs)
|
|
||||||
if err != nil {
|
|
||||||
ss.log.Error("Failed to create OAuthInfo for provider", "error", err, "provider", name)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if !info.Enabled {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
if name == social.GrafanaNetProviderName {
|
|
||||||
name = social.GrafanaComProviderName
|
|
||||||
}
|
|
||||||
|
|
||||||
conn, _ := createOAuthConnector(name, info, cfg, orgRoleMapper, ssoSettings, features, cache)
|
|
||||||
|
|
||||||
ss.socialMap[name] = conn
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ss.registerSupportBundleCollectors(bundleRegistry)
|
ss.registerSupportBundleCollectors(bundleRegistry)
|
||||||
|
@ -4,6 +4,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/go-cmp/cmp"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"gopkg.in/ini.v1"
|
"gopkg.in/ini.v1"
|
||||||
|
|
||||||
@ -28,26 +29,14 @@ func TestMain(m *testing.M) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIntegrationSocialService_ProvideService(t *testing.T) {
|
func TestIntegrationSocialService_ProvideService(t *testing.T) {
|
||||||
type testEnv struct {
|
|
||||||
features featuremgmt.FeatureToggles
|
|
||||||
}
|
|
||||||
testCases := []struct {
|
testCases := []struct {
|
||||||
name string
|
name string
|
||||||
setup func(t *testing.T, env *testEnv)
|
setup func(t *testing.T)
|
||||||
expectedSocialMapLength int
|
expectedSocialMapLength int
|
||||||
expectedGenericOAuthSkipOrgRoleSync bool
|
expectedGenericOAuthSkipOrgRoleSync bool
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "should load only enabled social connectors when ssoSettingsApi is disabled",
|
name: "should load all social connectors when ssoSettingsApi is enabled",
|
||||||
setup: nil,
|
|
||||||
expectedSocialMapLength: 1,
|
|
||||||
expectedGenericOAuthSkipOrgRoleSync: false,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
name: "should load all social connectors when ssoSettingsApi is enabled",
|
|
||||||
setup: func(t *testing.T, env *testEnv) {
|
|
||||||
env.features = featuremgmt.WithFeatures(featuremgmt.FlagSsoSettingsApi)
|
|
||||||
},
|
|
||||||
expectedSocialMapLength: 7,
|
expectedSocialMapLength: 7,
|
||||||
expectedGenericOAuthSkipOrgRoleSync: false,
|
expectedGenericOAuthSkipOrgRoleSync: false,
|
||||||
},
|
},
|
||||||
@ -88,17 +77,14 @@ func TestIntegrationSocialService_ProvideService(t *testing.T) {
|
|||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
|
||||||
env := &testEnv{
|
|
||||||
features: featuremgmt.WithFeatures(),
|
|
||||||
}
|
|
||||||
if tc.setup != nil {
|
if tc.setup != nil {
|
||||||
tc.setup(t, env)
|
tc.setup(t)
|
||||||
}
|
}
|
||||||
|
|
||||||
usageInsights := &usagestats.UsageStatsMock{}
|
usageInsights := &usagestats.UsageStatsMock{}
|
||||||
supportBundle := supportbundlestest.NewFakeBundleService()
|
supportBundle := supportbundlestest.NewFakeBundleService()
|
||||||
|
|
||||||
socialService := ProvideService(cfg, env.features, usageInsights, supportBundle, remotecache.NewFakeStore(t), nil, ssoSettingsSvc)
|
socialService := ProvideService(cfg, featuremgmt.WithFeatures(), usageInsights, supportBundle, remotecache.NewFakeStore(t), nil, ssoSettingsSvc)
|
||||||
require.Equal(t, tc.expectedSocialMapLength, len(socialService.GetOAuthProviders()))
|
require.Equal(t, tc.expectedSocialMapLength, len(socialService.GetOAuthProviders()))
|
||||||
|
|
||||||
genericOAuthInfo := socialService.GetOAuthInfoProvider("generic_oauth")
|
genericOAuthInfo := socialService.GetOAuthInfoProvider("generic_oauth")
|
||||||
@ -160,6 +146,9 @@ func TestIntegrationSocialService_ProvideService_GrafanaComGrafanaNet(t *testing
|
|||||||
TokenUrl: "/api/oauth2/token",
|
TokenUrl: "/api/oauth2/token",
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
ClientId: "grafanaComClientId",
|
ClientId: "grafanaComClientId",
|
||||||
|
Extra: map[string]string{
|
||||||
|
"allowed_organizations": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -178,6 +167,9 @@ func TestIntegrationSocialService_ProvideService_GrafanaComGrafanaNet(t *testing
|
|||||||
TokenUrl: "/api/oauth2/token",
|
TokenUrl: "/api/oauth2/token",
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
ClientId: "grafanaNetClientId",
|
ClientId: "grafanaNetClientId",
|
||||||
|
Extra: map[string]string{
|
||||||
|
"allowed_organizations": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -196,6 +188,9 @@ func TestIntegrationSocialService_ProvideService_GrafanaComGrafanaNet(t *testing
|
|||||||
TokenUrl: "/api/oauth2/token",
|
TokenUrl: "/api/oauth2/token",
|
||||||
Enabled: true,
|
Enabled: true,
|
||||||
ClientId: "grafanaComClientId",
|
ClientId: "grafanaComClientId",
|
||||||
|
Extra: map[string]string{
|
||||||
|
"allowed_organizations": "",
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -208,28 +203,19 @@ func TestIntegrationSocialService_ProvideService_GrafanaComGrafanaNet(t *testing
|
|||||||
[auth.grafananet]
|
[auth.grafananet]
|
||||||
enabled = false
|
enabled = false
|
||||||
client_id = grafanaNetClientId`,
|
client_id = grafanaNetClientId`,
|
||||||
expectedGrafanaComOAuthInfo: nil,
|
expectedGrafanaComOAuthInfo: &social.OAuthInfo{
|
||||||
|
AuthStyle: "inheader",
|
||||||
|
AuthUrl: "/oauth2/authorize",
|
||||||
|
TokenUrl: "/api/oauth2/token",
|
||||||
|
Enabled: false,
|
||||||
|
ClientId: "grafanaComClientId",
|
||||||
|
Extra: map[string]string{
|
||||||
|
"allowed_organizations": "",
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg := setting.NewCfg()
|
|
||||||
secrets := secretsfake.NewMockService(t)
|
|
||||||
accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
|
||||||
sqlStore := db.InitTestDB(t)
|
|
||||||
|
|
||||||
ssoSettingsSvc := ssosettingsimpl.ProvideService(
|
|
||||||
cfg,
|
|
||||||
sqlStore,
|
|
||||||
accessControl,
|
|
||||||
routing.NewRouteRegister(),
|
|
||||||
featuremgmt.WithFeatures(),
|
|
||||||
secrets,
|
|
||||||
&usagestats.UsageStatsMock{},
|
|
||||||
nil,
|
|
||||||
nil,
|
|
||||||
&licensing.OSSLicensingService{},
|
|
||||||
)
|
|
||||||
|
|
||||||
for _, tc := range testCases {
|
for _, tc := range testCases {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
iniFile, err := ini.Load([]byte(tc.rawIniContent))
|
iniFile, err := ini.Load([]byte(tc.rawIniContent))
|
||||||
@ -238,8 +224,45 @@ func TestIntegrationSocialService_ProvideService_GrafanaComGrafanaNet(t *testing
|
|||||||
cfg := setting.NewCfg()
|
cfg := setting.NewCfg()
|
||||||
cfg.Raw = iniFile
|
cfg.Raw = iniFile
|
||||||
|
|
||||||
|
secrets := secretsfake.NewMockService(t)
|
||||||
|
accessControl := acimpl.ProvideAccessControl(featuremgmt.WithFeatures())
|
||||||
|
sqlStore := db.InitTestDB(t)
|
||||||
|
|
||||||
|
ssoSettingsSvc := ssosettingsimpl.ProvideService(
|
||||||
|
cfg,
|
||||||
|
sqlStore,
|
||||||
|
accessControl,
|
||||||
|
routing.NewRouteRegister(),
|
||||||
|
featuremgmt.WithFeatures(),
|
||||||
|
secrets,
|
||||||
|
&usagestats.UsageStatsMock{},
|
||||||
|
nil,
|
||||||
|
nil,
|
||||||
|
&licensing.OSSLicensingService{},
|
||||||
|
)
|
||||||
|
|
||||||
socialService := ProvideService(cfg, featuremgmt.WithFeatures(), &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeStore(t), nil, ssoSettingsSvc)
|
socialService := ProvideService(cfg, featuremgmt.WithFeatures(), &usagestats.UsageStatsMock{}, supportbundlestest.NewFakeBundleService(), remotecache.NewFakeStore(t), nil, ssoSettingsSvc)
|
||||||
require.EqualValues(t, tc.expectedGrafanaComOAuthInfo, socialService.GetOAuthInfoProvider("grafana_com"))
|
|
||||||
|
// Create a custom comparison that treats nil slices as equal to empty slices for the tests
|
||||||
|
opts := cmp.Options{
|
||||||
|
cmp.Transformer("normalizeSlice", func(s []string) []string {
|
||||||
|
if s == nil {
|
||||||
|
return []string{}
|
||||||
|
}
|
||||||
|
return s
|
||||||
|
}),
|
||||||
|
cmp.Transformer("normalizeMap", func(m map[string]string) map[string]string {
|
||||||
|
if m == nil {
|
||||||
|
return map[string]string{}
|
||||||
|
}
|
||||||
|
return m
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
|
||||||
|
actual := socialService.GetOAuthInfoProvider("grafana_com")
|
||||||
|
if diff := cmp.Diff(tc.expectedGrafanaComOAuthInfo, actual, opts); diff != "" {
|
||||||
|
t.Errorf("OAuthInfo mismatch (-want +got):\n%s", diff)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -58,8 +58,7 @@ func ProvideRegistration(
|
|||||||
var passwordClients []authn.PasswordClient
|
var passwordClients []authn.PasswordClient
|
||||||
|
|
||||||
// always register LDAP if LDAP is enabled in SSO settings
|
// always register LDAP if LDAP is enabled in SSO settings
|
||||||
ssoSettingsLDAP := features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) && features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP)
|
if cfg.LDAPAuthEnabled || features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
|
||||||
if cfg.LDAPAuthEnabled || ssoSettingsLDAP {
|
|
||||||
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService)
|
ldap := clients.ProvideLDAP(cfg, ldapService, userService, authInfoService)
|
||||||
proxyClients = append(proxyClients, ldap)
|
proxyClients = append(proxyClients, ldap)
|
||||||
passwordClients = append(passwordClients, ldap)
|
passwordClients = append(passwordClients, ldap)
|
||||||
|
@ -651,15 +651,6 @@ var (
|
|||||||
FrontendOnly: false,
|
FrontendOnly: false,
|
||||||
Owner: grafanaOperatorExperienceSquad,
|
Owner: grafanaOperatorExperienceSquad,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
Name: "ssoSettingsApi",
|
|
||||||
Description: "Enables the SSO settings API and the OAuth configuration UIs in Grafana",
|
|
||||||
Stage: FeatureStageGeneralAvailability,
|
|
||||||
Expression: "true",
|
|
||||||
AllowSelfServe: true,
|
|
||||||
FrontendOnly: false,
|
|
||||||
Owner: identityAccessTeam,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
Name: "canvasPanelPanZoom",
|
Name: "canvasPanelPanZoom",
|
||||||
Description: "Allow pan and zoom in canvas panel",
|
Description: "Allow pan and zoom in canvas panel",
|
||||||
|
@ -86,7 +86,6 @@ dashboardScene,GA,@grafana/dashboards-squad,false,false,true
|
|||||||
dashboardNewLayouts,experimental,@grafana/dashboards-squad,false,false,true
|
dashboardNewLayouts,experimental,@grafana/dashboards-squad,false,false,true
|
||||||
panelFilterVariable,experimental,@grafana/dashboards-squad,false,false,true
|
panelFilterVariable,experimental,@grafana/dashboards-squad,false,false,true
|
||||||
pdfTables,preview,@grafana/grafana-operator-experience-squad,false,false,false
|
pdfTables,preview,@grafana/grafana-operator-experience-squad,false,false,false
|
||||||
ssoSettingsApi,GA,@grafana/identity-access-team,false,false,false
|
|
||||||
canvasPanelPanZoom,preview,@grafana/dataviz-squad,false,false,true
|
canvasPanelPanZoom,preview,@grafana/dataviz-squad,false,false,true
|
||||||
logsInfiniteScrolling,GA,@grafana/observability-logs,false,false,true
|
logsInfiniteScrolling,GA,@grafana/observability-logs,false,false,true
|
||||||
logRowsPopoverMenu,GA,@grafana/observability-logs,false,false,true
|
logRowsPopoverMenu,GA,@grafana/observability-logs,false,false,true
|
||||||
|
|
@ -355,10 +355,6 @@ const (
|
|||||||
// Enables generating table data as PDF in reporting
|
// Enables generating table data as PDF in reporting
|
||||||
FlagPdfTables = "pdfTables"
|
FlagPdfTables = "pdfTables"
|
||||||
|
|
||||||
// FlagSsoSettingsApi
|
|
||||||
// Enables the SSO settings API and the OAuth configuration UIs in Grafana
|
|
||||||
FlagSsoSettingsApi = "ssoSettingsApi"
|
|
||||||
|
|
||||||
// FlagCanvasPanelPanZoom
|
// FlagCanvasPanelPanZoom
|
||||||
// Allow pan and zoom in canvas panel
|
// Allow pan and zoom in canvas panel
|
||||||
FlagCanvasPanelPanZoom = "canvasPanelPanZoom"
|
FlagCanvasPanelPanZoom = "canvasPanelPanZoom"
|
||||||
|
@ -2839,7 +2839,8 @@
|
|||||||
"metadata": {
|
"metadata": {
|
||||||
"name": "ssoSettingsApi",
|
"name": "ssoSettingsApi",
|
||||||
"resourceVersion": "1750434297879",
|
"resourceVersion": "1750434297879",
|
||||||
"creationTimestamp": "2023-11-08T09:50:01Z"
|
"creationTimestamp": "2023-11-08T09:50:01Z",
|
||||||
|
"deletionTimestamp": "2025-07-02T14:16:57Z"
|
||||||
},
|
},
|
||||||
"spec": {
|
"spec": {
|
||||||
"description": "Enables the SSO settings API and the OAuth configuration UIs in Grafana",
|
"description": "Enables the SSO settings API and the OAuth configuration UIs in Grafana",
|
||||||
|
@ -56,7 +56,7 @@ func ProvideService(cfg *setting.Cfg, features featuremgmt.FeatureToggles, ssoSe
|
|||||||
ssoSettings: ssoSettings,
|
ssoSettings: ssoSettings,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) && s.features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
|
if s.features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsLDAP) {
|
||||||
s.ssoSettings.RegisterReloadable(social.LDAPProviderName, s)
|
s.ssoSettings.RegisterReloadable(social.LDAPProviderName, s)
|
||||||
|
|
||||||
ldapSettings, err := s.ssoSettings.GetForProvider(context.Background(), social.LDAPProviderName)
|
ldapSettings, err := s.ssoSettings.GetForProvider(context.Background(), social.LDAPProviderName)
|
||||||
|
@ -6,7 +6,6 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/services/featuremgmt"
|
|
||||||
"github.com/grafana/grafana/pkg/services/ldap"
|
"github.com/grafana/grafana/pkg/services/ldap"
|
||||||
"github.com/grafana/grafana/pkg/services/ssosettings/models"
|
"github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
@ -309,7 +308,6 @@ func TestReload(t *testing.T) {
|
|||||||
for _, tt := range testCases {
|
for _, tt := range testCases {
|
||||||
t.Run(tt.description, func(t *testing.T) {
|
t.Run(tt.description, func(t *testing.T) {
|
||||||
ldapImpl := &LDAPImpl{
|
ldapImpl := &LDAPImpl{
|
||||||
features: featuremgmt.WithManager(featuremgmt.FlagSsoSettingsApi),
|
|
||||||
loadingMutex: &sync.Mutex{},
|
loadingMutex: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -544,7 +542,6 @@ func TestValidate(t *testing.T) {
|
|||||||
for _, tt := range testCases {
|
for _, tt := range testCases {
|
||||||
t.Run(tt.description, func(t *testing.T) {
|
t.Run(tt.description, func(t *testing.T) {
|
||||||
ldapImpl := &LDAPImpl{
|
ldapImpl := &LDAPImpl{
|
||||||
features: featuremgmt.WithManager(featuremgmt.FlagSsoSettingsApi),
|
|
||||||
loadingMutex: &sync.Mutex{},
|
loadingMutex: &sync.Mutex{},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,7 +183,7 @@ func (s *ServiceImpl) getAdminNode(c *contextmodel.ReqContext) (*navtree.NavLink
|
|||||||
configNodes = append(configNodes, usersNode)
|
configNodes = append(configNodes, usersNode)
|
||||||
|
|
||||||
if authConfigUIAvailable && hasAccess(ssoutils.EvalAuthenticationSettings(s.cfg)) ||
|
if authConfigUIAvailable && hasAccess(ssoutils.EvalAuthenticationSettings(s.cfg)) ||
|
||||||
(hasAccess(ssoutils.OauthSettingsEvaluator(s.cfg)) && s.features.IsEnabled(ctx, featuremgmt.FlagSsoSettingsApi)) {
|
hasAccess(ssoutils.OauthSettingsEvaluator(s.cfg)) {
|
||||||
configNodes = append(configNodes, &navtree.NavLink{
|
configNodes = append(configNodes, &navtree.NavLink{
|
||||||
Text: "Authentication",
|
Text: "Authentication",
|
||||||
Id: "authentication",
|
Id: "authentication",
|
||||||
|
@ -93,10 +93,8 @@ func ProvideService(cfg *setting.Cfg, sqlStore db.DB, ac ac.AccessControl,
|
|||||||
|
|
||||||
usageStats.RegisterMetricsFunc(svc.getUsageStats)
|
usageStats.RegisterMetricsFunc(svc.getUsageStats)
|
||||||
|
|
||||||
if features.IsEnabledGlobally(featuremgmt.FlagSsoSettingsApi) {
|
ssoSettingsApi := api.ProvideApi(svc, routeRegister, ac)
|
||||||
ssoSettingsApi := api.ProvideApi(svc, routeRegister, ac)
|
ssoSettingsApi.RegisterAPIEndpoints()
|
||||||
ssoSettingsApi.RegisterAPIEndpoints()
|
|
||||||
}
|
|
||||||
|
|
||||||
return svc
|
return svc
|
||||||
}
|
}
|
||||||
|
119
pkg/services/ssosettings/ssosettingstests/service_fake.go
Normal file
119
pkg/services/ssosettings/ssosettingstests/service_fake.go
Normal file
@ -0,0 +1,119 @@
|
|||||||
|
package ssosettingstests
|
||||||
|
|
||||||
|
import (
|
||||||
|
context "context"
|
||||||
|
|
||||||
|
"github.com/grafana/grafana/pkg/apimachinery/identity"
|
||||||
|
"github.com/grafana/grafana/pkg/services/ssosettings"
|
||||||
|
models "github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||||
|
)
|
||||||
|
|
||||||
|
var _ ssosettings.Service = (*FakeService)(nil)
|
||||||
|
|
||||||
|
type FakeService struct {
|
||||||
|
ExpectedSSOSetting *models.SSOSettings
|
||||||
|
ExpectedSSOSettings []*models.SSOSettings
|
||||||
|
ExpectedError error
|
||||||
|
ExpectedReloadablesRegistry map[string]ssosettings.Reloadable
|
||||||
|
|
||||||
|
ActualSSOSettings models.SSOSettings
|
||||||
|
ActualPatchData map[string]any
|
||||||
|
ActualProvider string
|
||||||
|
ActualRequester identity.Requester
|
||||||
|
|
||||||
|
ListFn func(ctx context.Context) ([]*models.SSOSettings, error)
|
||||||
|
ListWithRedactedSecretsFn func(ctx context.Context) ([]*models.SSOSettings, error)
|
||||||
|
GetForProviderFn func(ctx context.Context, provider string) (*models.SSOSettings, error)
|
||||||
|
GetForProviderWithRedactedSecretsFn func(ctx context.Context, provider string) (*models.SSOSettings, error)
|
||||||
|
UpsertFn func(ctx context.Context, settings *models.SSOSettings, requester identity.Requester) error
|
||||||
|
DeleteFn func(ctx context.Context, provider string) error
|
||||||
|
PatchFn func(ctx context.Context, provider string, data map[string]any) error
|
||||||
|
RegisterReloadableFn func(provider string, reloadable ssosettings.Reloadable)
|
||||||
|
ReloadFn func(ctx context.Context, provider string)
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewFakeService() *FakeService {
|
||||||
|
return &FakeService{
|
||||||
|
ExpectedReloadablesRegistry: make(map[string]ssosettings.Reloadable),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) List(ctx context.Context) ([]*models.SSOSettings, error) {
|
||||||
|
if f.ListFn != nil {
|
||||||
|
return f.ListFn(ctx)
|
||||||
|
}
|
||||||
|
return f.ExpectedSSOSettings, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) ListWithRedactedSecrets(ctx context.Context) ([]*models.SSOSettings, error) {
|
||||||
|
if f.ListWithRedactedSecretsFn != nil {
|
||||||
|
return f.ListWithRedactedSecretsFn(ctx)
|
||||||
|
}
|
||||||
|
return f.ExpectedSSOSettings, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) GetForProvider(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||||
|
if f.GetForProviderFn != nil {
|
||||||
|
return f.GetForProviderFn(ctx, provider)
|
||||||
|
}
|
||||||
|
f.ActualProvider = provider
|
||||||
|
return f.ExpectedSSOSetting, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) GetForProviderWithRedactedSecrets(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||||
|
if f.GetForProviderWithRedactedSecretsFn != nil {
|
||||||
|
return f.GetForProviderWithRedactedSecretsFn(ctx, provider)
|
||||||
|
}
|
||||||
|
f.ActualProvider = provider
|
||||||
|
return f.ExpectedSSOSetting, f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) Upsert(ctx context.Context, settings *models.SSOSettings, requester identity.Requester) error {
|
||||||
|
if f.UpsertFn != nil {
|
||||||
|
return f.UpsertFn(ctx, settings, requester)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ActualSSOSettings = *settings
|
||||||
|
f.ActualRequester = requester
|
||||||
|
|
||||||
|
return f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) Delete(ctx context.Context, provider string) error {
|
||||||
|
if f.DeleteFn != nil {
|
||||||
|
return f.DeleteFn(ctx, provider)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ActualProvider = provider
|
||||||
|
|
||||||
|
return f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) Patch(ctx context.Context, provider string, data map[string]any) error {
|
||||||
|
if f.PatchFn != nil {
|
||||||
|
return f.PatchFn(ctx, provider, data)
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ActualProvider = provider
|
||||||
|
f.ActualPatchData = data
|
||||||
|
|
||||||
|
return f.ExpectedError
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) RegisterReloadable(provider string, reloadable ssosettings.Reloadable) {
|
||||||
|
if f.RegisterReloadableFn != nil {
|
||||||
|
f.RegisterReloadableFn(provider, reloadable)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ExpectedReloadablesRegistry[provider] = reloadable
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *FakeService) Reload(ctx context.Context, provider string) {
|
||||||
|
if f.ReloadFn != nil {
|
||||||
|
f.ReloadFn(ctx, provider)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
f.ActualProvider = provider
|
||||||
|
}
|
@ -53,7 +53,7 @@ export async function getAuthProviderStatus(providerId: string): Promise<AuthPro
|
|||||||
|
|
||||||
export function initAuthConfig() {
|
export function initAuthConfig() {
|
||||||
// skip the LDAP provider if it is enabled by SSO settings
|
// skip the LDAP provider if it is enabled by SSO settings
|
||||||
if (config.featureToggles.ssoSettingsApi && config.featureToggles.ssoSettingsLDAP) {
|
if (config.featureToggles.ssoSettingsLDAP) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { lastValueFrom } from 'rxjs';
|
import { lastValueFrom } from 'rxjs';
|
||||||
|
|
||||||
import { config, getBackendSrv, isFetchError } from '@grafana/runtime';
|
import { getBackendSrv, isFetchError } from '@grafana/runtime';
|
||||||
import { contextSrv } from 'app/core/core';
|
import { contextSrv } from 'app/core/core';
|
||||||
import { AccessControlAction, Settings, ThunkResult, UpdateSettingsQuery } from 'app/types';
|
import { AccessControlAction, Settings, ThunkResult, UpdateSettingsQuery } from 'app/types';
|
||||||
|
|
||||||
@ -37,9 +37,6 @@ export function loadSettings(showSpinner = true): ThunkResult<Promise<Settings>>
|
|||||||
|
|
||||||
export function loadProviders(provider = ''): ThunkResult<Promise<SSOProvider[]>> {
|
export function loadProviders(provider = ''): ThunkResult<Promise<SSOProvider[]>> {
|
||||||
return async (dispatch) => {
|
return async (dispatch) => {
|
||||||
if (!config.featureToggles.ssoSettingsApi) {
|
|
||||||
return [];
|
|
||||||
}
|
|
||||||
const result = await getBackendSrv().get(`/api/v1/sso-settings${provider ? `/${provider}` : ''}`);
|
const result = await getBackendSrv().get(`/api/v1/sso-settings${provider ? `/${provider}` : ''}`);
|
||||||
dispatch(providersLoaded(provider ? [result] : result));
|
dispatch(providersLoaded(provider ? [result] : result));
|
||||||
return result;
|
return result;
|
||||||
|
@ -301,7 +301,7 @@ export function getAppRoutes(): RouteDescriptor[] {
|
|||||||
path: '/admin/authentication',
|
path: '/admin/authentication',
|
||||||
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
||||||
component:
|
component:
|
||||||
config.licenseInfo.enabledFeatures?.saml || config.ldapEnabled || config.featureToggles.ssoSettingsApi
|
config.licenseInfo.enabledFeatures?.saml || config.ldapEnabled
|
||||||
? SafeDynamicImport(
|
? SafeDynamicImport(
|
||||||
() =>
|
() =>
|
||||||
import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/AuthProvidersListPage')
|
import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/AuthProvidersListPage')
|
||||||
@ -319,11 +319,9 @@ export function getAppRoutes(): RouteDescriptor[] {
|
|||||||
{
|
{
|
||||||
path: '/admin/authentication/:provider',
|
path: '/admin/authentication/:provider',
|
||||||
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
roles: () => contextSrv.evaluatePermission([AccessControlAction.SettingsWrite]),
|
||||||
component: config.featureToggles.ssoSettingsApi
|
component: SafeDynamicImport(
|
||||||
? SafeDynamicImport(
|
() => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/ProviderConfigPage')
|
||||||
() => import(/* webpackChunkName: "AdminAuthentication" */ '../features/auth-config/ProviderConfigPage')
|
),
|
||||||
)
|
|
||||||
: () => <Navigate replace to="/admin" />,
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: '/admin/settings',
|
path: '/admin/settings',
|
||||||
|
Reference in New Issue
Block a user