Provisioning: Fix overwrite SecureJSONData on provisioning (#72395)

* Overwrite SecureJSONData on provisioning
This commit is contained in:
Hugo Kiyodi Oshiro 2023-07-27 11:11:43 +02:00 committed by GitHub
parent a4a87f6228
commit a912c970e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 113 additions and 19 deletions

View File

@ -134,6 +134,7 @@ type UpdateDataSourceCommand struct {
ReadOnly bool `json:"-"` ReadOnly bool `json:"-"`
EncryptedSecureJsonData map[string][]byte `json:"-"` EncryptedSecureJsonData map[string][]byte `json:"-"`
UpdateSecretFn UpdateSecretFn `json:"-"` UpdateSecretFn UpdateSecretFn `json:"-"`
IgnoreOldSecureJsonData bool `json:"-"`
} }
// DeleteDataSourceCommand will delete a DataSource based on OrgID as well as the UID (preferred), ID, or Name. // DeleteDataSourceCommand will delete a DataSource based on OrgID as well as the UID (preferred), ID, or Name.

View File

@ -644,9 +644,11 @@ func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *datasources.U
cmd.SecureJsonData = make(map[string]string) cmd.SecureJsonData = make(map[string]string)
} }
for k, v := range decrypted { if !cmd.IgnoreOldSecureJsonData {
if _, ok := cmd.SecureJsonData[k]; !ok { for k, v := range decrypted {
cmd.SecureJsonData[k] = v if _, ok := cmd.SecureJsonData[k]; !ok {
cmd.SecureJsonData[k] = v
}
} }
} }

View File

@ -187,6 +187,96 @@ func TestService_UpdateDataSource(t *testing.T) {
_, err = dsService.UpdateDataSource(context.Background(), cmd) _, err = dsService.UpdateDataSource(context.Background(), cmd)
require.ErrorIs(t, err, datasources.ErrDataSourceNameExists) require.ErrorIs(t, err, datasources.ErrDataSourceNameExists)
}) })
t.Run("should merge cmd.SecureJsonData with db data", func(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
quotaService := quotatest.New(false, nil)
mockPermission := acmock.NewMockedPermissionsService()
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService)
require.NoError(t, err)
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
expectedDbKey := "db-secure-key"
expectedDbValue := "db-secure-value"
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgID: 1,
Name: "test-datasource",
SecureJsonData: map[string]string{
expectedDbKey: expectedDbValue,
},
})
require.NoError(t, err)
expectedOgKey := "cmd-secure-key"
expectedOgValue := "cmd-secure-value"
cmd := &datasources.UpdateDataSourceCommand{
ID: ds.ID,
OrgID: ds.OrgID,
Name: "test-datasource-updated",
SecureJsonData: map[string]string{
expectedOgKey: expectedOgValue,
},
}
ds, err = dsService.UpdateDataSource(context.Background(), cmd)
require.NoError(t, err)
secret, err := dsService.DecryptedValues(context.Background(), ds)
require.NoError(t, err)
assert.Equal(t, secret[expectedDbKey], expectedDbValue)
assert.Equal(t, secret[expectedOgKey], expectedOgValue)
})
t.Run("should preserve cmd.SecureJsonData when cmd.IgnoreOldSecureJsonData=true", func(t *testing.T) {
sqlStore := db.InitTestDB(t)
secretsService := secretsmng.SetupTestService(t, fakes.NewFakeSecretsStore())
secretsStore := secretskvs.NewSQLSecretsKVStore(sqlStore, secretsService, log.New("test.logger"))
quotaService := quotatest.New(false, nil)
mockPermission := acmock.NewMockedPermissionsService()
dsService, err := ProvideService(sqlStore, secretsService, secretsStore, cfg, featuremgmt.WithFeatures(), actest.FakeAccessControl{}, mockPermission, quotaService)
require.NoError(t, err)
mockPermission.On("SetPermissions", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return([]accesscontrol.ResourcePermission{}, nil)
notExpectedDbKey := "db-secure-key"
dbValue := "db-secure-value"
ds, err := dsService.AddDataSource(context.Background(), &datasources.AddDataSourceCommand{
OrgID: 1,
Name: "test-datasource",
SecureJsonData: map[string]string{
notExpectedDbKey: dbValue,
},
})
require.NoError(t, err)
expectedOgKey := "cmd-secure-key"
expectedOgValue := "cmd-secure-value"
cmd := &datasources.UpdateDataSourceCommand{
ID: ds.ID,
OrgID: ds.OrgID,
Name: "test-datasource-updated",
SecureJsonData: map[string]string{
expectedOgKey: expectedOgValue,
},
IgnoreOldSecureJsonData: true,
}
ds, err = dsService.UpdateDataSource(context.Background(), cmd)
require.NoError(t, err)
secret, err := dsService.DecryptedValues(context.Background(), ds)
require.NoError(t, err)
assert.Equal(t, secret[expectedOgKey], expectedOgValue)
_, ok := secret[notExpectedDbKey]
assert.False(t, ok)
})
} }
func TestService_NameScopeResolver(t *testing.T) { func TestService_NameScopeResolver(t *testing.T) {

View File

@ -242,21 +242,22 @@ func createUpdateCommand(ds *upsertDataSourceFromConfig, id int64) *datasources.
} }
return &datasources.UpdateDataSourceCommand{ return &datasources.UpdateDataSourceCommand{
ID: id, ID: id,
UID: ds.UID, UID: ds.UID,
OrgID: ds.OrgID, OrgID: ds.OrgID,
Name: ds.Name, Name: ds.Name,
Type: ds.Type, Type: ds.Type,
Access: datasources.DsAccess(ds.Access), Access: datasources.DsAccess(ds.Access),
URL: ds.URL, URL: ds.URL,
User: ds.User, User: ds.User,
Database: ds.Database, Database: ds.Database,
BasicAuth: ds.BasicAuth, BasicAuth: ds.BasicAuth,
BasicAuthUser: ds.BasicAuthUser, BasicAuthUser: ds.BasicAuthUser,
WithCredentials: ds.WithCredentials, WithCredentials: ds.WithCredentials,
IsDefault: ds.IsDefault, IsDefault: ds.IsDefault,
JsonData: jsonData, JsonData: jsonData,
SecureJsonData: ds.SecureJSONData, SecureJsonData: ds.SecureJSONData,
ReadOnly: !ds.Editable, ReadOnly: !ds.Editable,
IgnoreOldSecureJsonData: true,
} }
} }