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:
co-authored by
Mihaly Gyongyosi
parent
40312c527b
commit
e241188f00
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user