Auth: Implement the SSO Settings GET endpoint (#79144)
* Return data in camelCase from the OAuth fb strategy * changes * wip * Add defaults for oauth fb strategy * revert other changes * basic includeDefaults query param implementation * basic secret removal and etag implementation * correct imports * rebase * move default settings filter to models * only replace ClientSecret value if set * first GetForProvider test & use FNV for ETag to avoid Blocklisted import error * add tests * add annotation for the openapi spec & generate spec * remove TODO * use IsSecret, improve tests, remove DefaultOAuthSettings * add comment explaining generateFNVETag * add error handling for generateFNVETag * run go generate * Update pkg/services/ssosettings/api/api.go Co-authored-by: Mihai Doarna <mihai.doarna@grafana.com> * move isSecret to service, create GetForProviderWithRedactedSecrets func * add unit test for GetForProviderWithRedactedSecrets & remove duplicated code * regen openapi/swagger * revert dependency bumps --------- Co-authored-by: Mihaly Gyongyosi <mgyongyosi@users.noreply.github.com> Co-authored-by: Mihai Doarna <mihai.doarna@grafana.com>
This commit is contained in:
co-authored by
Mihai Doarna
Mihaly Gyongyosi
parent
505196bcd5
commit
062e772bb2
@@ -84,6 +84,21 @@ func (s *SSOSettingsService) GetForProvider(ctx context.Context, provider string
|
||||
return storeSettings, nil
|
||||
}
|
||||
|
||||
func (s *SSOSettingsService) GetForProviderWithRedactedSecrets(ctx context.Context, provider string) (*models.SSOSettings, error) {
|
||||
storeSettings, err := s.GetForProvider(ctx, provider)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for k, v := range storeSettings.Settings {
|
||||
if isSecret(k) && v != "" {
|
||||
storeSettings.Settings[k] = "*********"
|
||||
}
|
||||
}
|
||||
|
||||
return storeSettings, nil
|
||||
}
|
||||
|
||||
func (s *SSOSettingsService) List(ctx context.Context) ([]*models.SSOSettings, error) {
|
||||
result := make([]*models.SSOSettings, 0, len(ssosettings.AllOAuthProviders))
|
||||
storedSettings, err := s.store.List(ctx)
|
||||
|
||||
@@ -103,6 +103,99 @@ func TestSSOSettingsService_GetForProvider(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSOSettingsService_GetForProviderWithRedactedSecrets(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
setup func(env testEnv)
|
||||
want *models.SSOSettings
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "should return successfully and redact secrets",
|
||||
setup: func(env testEnv) {
|
||||
env.store.ExpectedSSOSetting = &models.SSOSettings{
|
||||
Provider: "github",
|
||||
Settings: map[string]any{
|
||||
"enabled": true,
|
||||
"secret": "secret",
|
||||
"client_secret": "client_secret",
|
||||
"client_id": "client_id",
|
||||
},
|
||||
Source: models.DB,
|
||||
}
|
||||
},
|
||||
want: &models.SSOSettings{
|
||||
Provider: "github",
|
||||
Settings: map[string]any{
|
||||
"enabled": true,
|
||||
"secret": "*********",
|
||||
"client_secret": "*********",
|
||||
"client_id": "client_id",
|
||||
},
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return error if store returns an error different than not found",
|
||||
setup: func(env testEnv) { env.store.ExpectedError = fmt.Errorf("error") },
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "should fallback to strategy if store returns not found",
|
||||
setup: func(env testEnv) {
|
||||
env.store.ExpectedError = ssosettings.ErrNotFound
|
||||
env.fallbackStrategy.ExpectedIsMatch = true
|
||||
env.fallbackStrategy.ExpectedConfig = map[string]any{"enabled": true}
|
||||
},
|
||||
want: &models.SSOSettings{
|
||||
Provider: "github",
|
||||
Settings: map[string]any{"enabled": true},
|
||||
Source: models.System,
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "should return error if the fallback strategy was not found",
|
||||
setup: func(env testEnv) {
|
||||
env.store.ExpectedError = ssosettings.ErrNotFound
|
||||
env.fallbackStrategy.ExpectedIsMatch = false
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "should return error if fallback strategy returns error",
|
||||
setup: func(env testEnv) {
|
||||
env.store.ExpectedError = ssosettings.ErrNotFound
|
||||
env.fallbackStrategy.ExpectedIsMatch = true
|
||||
env.fallbackStrategy.ExpectedError = fmt.Errorf("error")
|
||||
},
|
||||
want: nil,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testCases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
env := setupTestEnv(t)
|
||||
if tc.setup != nil {
|
||||
tc.setup(env)
|
||||
}
|
||||
|
||||
actual, err := env.service.GetForProviderWithRedactedSecrets(context.Background(), "github")
|
||||
|
||||
if tc.wantErr {
|
||||
require.Error(t, err)
|
||||
return
|
||||
}
|
||||
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tc.want, actual)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSSOSettingsService_List(t *testing.T) {
|
||||
testCases := []struct {
|
||||
name string
|
||||
|
||||
Reference in New Issue
Block a user