Auth: Implement the SSO Settings List endpoint (#80769)

* add list endpoint & initial tests

* add tests and ETag

* format service_test.go

* add list swagger param, generate openAPI, remove ETag, use RedactedPassword

* correct swagger param name

* Align tests to latest changes

* use setting.RedactedValue()

* add string assertion

* lint & require no error on res.Body.Close()

* add custom response type

---------

Co-authored-by: Mihaly Gyongyosi <mgyongyosi@users.noreply.github.com>
This commit is contained in:
colin-stuart
2024-01-19 14:39:09 -05:00
committed by GitHub
co-authored by Mihaly Gyongyosi
parent 40312c527b
commit e241188f00
9 changed files with 579 additions and 29 deletions
@@ -94,8 +94,8 @@ func (s *SSOSettingsService) GetForProviderWithRedactedSecrets(ctx context.Conte
}
for k, v := range storeSettings.Settings {
if isSecret(k) && v != "" {
storeSettings.Settings[k] = setting.RedactedPassword
if strVal, ok := v.(string); ok {
storeSettings.Settings[k] = setting.RedactedValue(k, strVal)
}
}
@@ -130,6 +130,23 @@ func (s *SSOSettingsService) List(ctx context.Context) ([]*models.SSOSettings, e
return result, nil
}
func (s *SSOSettingsService) ListWithRedactedSecrets(ctx context.Context) ([]*models.SSOSettings, error) {
storeSettings, err := s.List(ctx)
if err != nil {
return nil, err
}
for _, storeSetting := range storeSettings {
for k, v := range storeSetting.Settings {
if strVal, ok := v.(string); ok {
storeSetting.Settings[k] = setting.RedactedValue(k, strVal)
}
}
}
return storeSettings, nil
}
func (s *SSOSettingsService) Upsert(ctx context.Context, settings models.SSOSettings) error {
if !isProviderConfigurable(settings.Provider) {
return ssosettings.ErrInvalidProvider.Errorf("provider %s is not configurable", settings.Provider)
@@ -414,6 +414,190 @@ func TestSSOSettingsService_List(t *testing.T) {
},
wantErr: false,
},
{
name: "should return error if any of the fallback strategies was not found",
setup: func(env testEnv) {
env.store.ExpectedSSOSettings = []*models.SSOSettings{}
env.fallbackStrategy.ExpectedIsMatch = false
},
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.List(context.Background())
if tc.wantErr {
require.Error(t, err)
return
}
require.NoError(t, err)
require.ElementsMatch(t, tc.want, actual)
})
}
}
func TestSSOSettingsService_ListWithRedactedSecrets(t *testing.T) {
testCases := []struct {
name string
setup func(env testEnv)
want []*models.SSOSettings
wantErr bool
}{
{
name: "should return successfully",
setup: func(env testEnv) {
env.store.ExpectedSSOSettings = []*models.SSOSettings{
{
Provider: "github",
Settings: map[string]any{
"enabled": true,
"client_secret": base64.RawStdEncoding.EncodeToString([]byte("client_secret")),
"client_id": "client_id",
},
Source: models.DB,
},
{
Provider: "okta",
Settings: map[string]any{
"enabled": false,
"other_secret": base64.RawStdEncoding.EncodeToString([]byte("other_secret")),
"client_id": "client_id",
},
Source: models.DB,
},
}
env.secrets.On("Decrypt", mock.Anything, []byte("client_secret"), mock.Anything).Return([]byte("decrypted-client-secret"), nil).Once()
env.secrets.On("Decrypt", mock.Anything, []byte("other_secret"), mock.Anything).Return([]byte("decrypted-other-secret"), nil).Once()
env.fallbackStrategy.ExpectedIsMatch = true
env.fallbackStrategy.ExpectedConfigs = map[string]map[string]any{
"github": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"okta": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"gitlab": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"generic_oauth": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"google": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"azuread": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"grafana_com": {
"enabled": true,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
}
},
want: []*models.SSOSettings{
{
Provider: "github",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.DB,
},
{
Provider: "okta",
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
"other_secret": "*********",
},
Source: models.DB,
},
{
Provider: "gitlab",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "generic_oauth",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "google",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "azuread",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "grafana_com",
Settings: map[string]any{
"enabled": true,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
},
wantErr: false,
},
{
name: "should return error if store returns an error",
setup: func(env testEnv) { env.store.ExpectedError = fmt.Errorf("error") },
@@ -427,63 +611,119 @@ func TestSSOSettingsService_List(t *testing.T) {
env.fallbackStrategy.ExpectedIsMatch = true
env.fallbackStrategy.ExpectedConfigs = map[string]map[string]any{
"github": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"okta": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"gitlab": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"generic_oauth": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"google": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"azuread": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
"grafana_com": {
"enabled": false,
"enabled": false,
"secret": "secret",
"client_secret": "client_secret",
"client_id": "client_id",
},
}
},
want: []*models.SSOSettings{
{
Provider: "github",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "okta",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "gitlab",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "generic_oauth",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "google",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "azuread",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
{
Provider: "grafana_com",
Settings: map[string]any{"enabled": false},
Source: models.System,
Settings: map[string]any{
"enabled": false,
"secret": "*********",
"client_secret": "*********",
"client_id": "client_id",
},
Source: models.System,
},
},
wantErr: false,
@@ -505,7 +745,7 @@ func TestSSOSettingsService_List(t *testing.T) {
tc.setup(env)
}
actual, err := env.service.List(context.Background())
actual, err := env.service.ListWithRedactedSecrets(context.Background())
if tc.wantErr {
require.Error(t, err)