From 2533f210155b852b22a21a42a8443950f41878be Mon Sep 17 00:00:00 2001 From: Guilherme Caulada <guilherme.caulada@grafana.com> Date: Mon, 2 May 2022 11:29:13 -0300 Subject: [PATCH] DataSource: Fix secure json data reset on datasource update (#48557) * Fix secure json data reset on datasource update * Update fillWithSecureJSONData to use DecryptedValues * Remove unecessary conversion * Move fillWithSecureJsonData logic to datasource service * Add sanity check for nil secure json data --- pkg/api/datasources.go | 32 ------------------ .../datasources/service/datasource_service.go | 33 ++++++++++++++++--- 2 files changed, 29 insertions(+), 36 deletions(-) diff --git a/pkg/api/datasources.go b/pkg/api/datasources.go index 7eb21d0562c..a35471d31fa 100644 --- a/pkg/api/datasources.go +++ b/pkg/api/datasources.go @@ -302,11 +302,6 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response { return response.Error(403, "Cannot update read-only data source", nil) } - err = hs.fillWithSecureJSONData(c.Req.Context(), &cmd) - if err != nil { - return response.Error(500, "Failed to update datasource", err) - } - err = hs.DataSourcesService.UpdateDataSource(c.Req.Context(), &cmd) if err != nil { if errors.Is(err, models.ErrDataSourceUpdatingOldVersion) { @@ -339,33 +334,6 @@ func (hs *HTTPServer) UpdateDataSource(c *models.ReqContext) response.Response { }) } -func (hs *HTTPServer) fillWithSecureJSONData(ctx context.Context, cmd *models.UpdateDataSourceCommand) error { - if len(cmd.SecureJsonData) == 0 { - return nil - } - - ds, err := hs.getRawDataSourceById(ctx, cmd.Id, cmd.OrgId) - if err != nil { - return err - } - - if ds.ReadOnly { - return models.ErrDatasourceIsReadOnly - } - - for k, v := range ds.SecureJsonData { - if _, ok := cmd.SecureJsonData[k]; !ok { - decrypted, err := hs.SecretsService.Decrypt(ctx, v) - if err != nil { - return err - } - cmd.SecureJsonData[k] = string(decrypted) - } - } - - return nil -} - func (hs *HTTPServer) getRawDataSourceById(ctx context.Context, id int64, orgID int64) (*models.DataSource, error) { query := models.GetDataSourceQuery{ Id: id, diff --git a/pkg/services/datasources/service/datasource_service.go b/pkg/services/datasources/service/datasource_service.go index 24c9ff6b47c..572ea48c1ca 100644 --- a/pkg/services/datasources/service/datasource_service.go +++ b/pkg/services/datasources/service/datasource_service.go @@ -192,10 +192,6 @@ func (s *Service) DeleteDataSource(ctx context.Context, cmd *models.DeleteDataSo func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSourceCommand) error { var err error - secret, err := json.Marshal(cmd.SecureJsonData) - if err != nil { - return err - } query := &models.GetDataSourceQuery{ Id: cmd.Id, @@ -206,6 +202,11 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSo return err } + err = s.fillWithSecureJSONData(ctx, cmd, query.Result) + if err != nil { + return err + } + err = s.SQLStore.UpdateDataSource(ctx, cmd) if err != nil { return err @@ -218,6 +219,11 @@ func (s *Service) UpdateDataSource(ctx context.Context, cmd *models.UpdateDataSo } } + secret, err := json.Marshal(cmd.SecureJsonData) + if err != nil { + return err + } + return s.SecretsStore.Set(ctx, cmd.OrgId, cmd.Name, secretType, string(secret)) } @@ -559,3 +565,22 @@ func awsServiceNamespace(dsType string) string { panic(fmt.Sprintf("Unsupported datasource %q", dsType)) } } + +func (s *Service) fillWithSecureJSONData(ctx context.Context, cmd *models.UpdateDataSourceCommand, ds *models.DataSource) error { + decrypted, err := s.DecryptedValues(ctx, ds) + if err != nil { + return err + } + + if cmd.SecureJsonData == nil { + cmd.SecureJsonData = make(map[string]string) + } + + for k, v := range decrypted { + if _, ok := cmd.SecureJsonData[k]; !ok { + cmd.SecureJsonData[k] = v + } + } + + return nil +}