mirror of
https://github.com/grafana/grafana.git
synced 2025-08-03 01:42:12 +08:00
SSO: Fix secrets migration for LDAP in SSO settings (#94252)
fix secrets migration for LDAP in SSO settings
This commit is contained in:
@ -7,6 +7,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/infra/db"
|
||||
"github.com/grafana/grafana/pkg/services/encryption"
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||
"github.com/grafana/grafana/pkg/services/secrets"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||
@ -308,26 +309,10 @@ func (s ssoSettingsSecret) ReEncrypt(ctx context.Context, secretsSrv *manager.Se
|
||||
|
||||
for _, result := range results {
|
||||
err := sqlStore.InTransaction(ctx, func(ctx context.Context) error {
|
||||
for field, value := range result.Settings {
|
||||
if ssosettingsimpl.IsSecretField(field) {
|
||||
decrypted, err := s.decryptValue(ctx, value, secretsSrv)
|
||||
if err != nil {
|
||||
logger.Warn("Could not decrypt SSO settings secret", "id", result.ID, "field", field, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if decrypted == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
reencrypted, err := secretsSrv.Encrypt(ctx, decrypted, secrets.WithoutScope())
|
||||
if err != nil {
|
||||
logger.Warn("Could not re-encrypt SSO settings secret", "id", result.ID, "field", field, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
result.Settings[field] = base64.RawStdEncoding.EncodeToString(reencrypted)
|
||||
}
|
||||
result.Settings, err = s.reEncryptSecretsInMap(ctx, result.Settings, secretsSrv, nil, "")
|
||||
if err != nil {
|
||||
logger.Warn("failed re-encrypting SSO settings secret", "id", result.ID, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
@ -378,3 +363,77 @@ func (s ssoSettingsSecret) decryptValue(ctx context.Context, value any, secretsS
|
||||
|
||||
return decrypted, nil
|
||||
}
|
||||
|
||||
func (s ssoSettingsSecret) reEncryptSecretsInMap(ctx context.Context, m map[string]any, secretsSrv *manager.SecretsService, encryptionSrv encryption.Internal, secretKey string) (map[string]any, error) {
|
||||
var err error
|
||||
|
||||
result := make(map[string]any)
|
||||
for k, v := range m {
|
||||
switch v := v.(type) {
|
||||
case string:
|
||||
result[k] = v
|
||||
if ssosettingsimpl.IsSecretField(k) {
|
||||
decrypted, err := s.decryptValue(ctx, v, secretsSrv)
|
||||
if err != nil {
|
||||
logger.Warn("Could not decrypt SSO settings secret", "field", k, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if decrypted == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
var reencrypted []byte
|
||||
if encryptionSrv == nil {
|
||||
reencrypted, err = secretsSrv.Encrypt(ctx, decrypted, secrets.WithoutScope())
|
||||
} else {
|
||||
reencrypted, err = encryptionSrv.Encrypt(ctx, decrypted, secretKey)
|
||||
}
|
||||
if err != nil {
|
||||
logger.Warn("Could not re-encrypt SSO settings secret", "id", "field", k, "error", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
result[k] = base64.RawStdEncoding.EncodeToString(reencrypted)
|
||||
}
|
||||
case []any:
|
||||
result[k], err = s.reEncryptSecretsInSlice(ctx, v, secretsSrv, encryptionSrv, secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case map[string]any:
|
||||
result[k], err = s.reEncryptSecretsInMap(ctx, v, secretsSrv, encryptionSrv, secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
result[k] = v
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
||||
func (s ssoSettingsSecret) reEncryptSecretsInSlice(ctx context.Context, a []any, secretsSrv *manager.SecretsService, encryptionSrv encryption.Internal, secretKey string) ([]any, error) {
|
||||
result := make([]any, 0)
|
||||
for _, v := range a {
|
||||
switch v := v.(type) {
|
||||
case []any:
|
||||
inner, err := s.reEncryptSecretsInSlice(ctx, v, secretsSrv, encryptionSrv, secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, inner)
|
||||
case map[string]any:
|
||||
inner, err := s.reEncryptSecretsInMap(ctx, v, secretsSrv, encryptionSrv, secretKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result = append(result, inner)
|
||||
default:
|
||||
result = append(result, v)
|
||||
}
|
||||
}
|
||||
|
||||
return result, nil
|
||||
}
|
||||
|
@ -11,7 +11,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/ngalert/notifier"
|
||||
"github.com/grafana/grafana/pkg/services/secrets/manager"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings/models"
|
||||
"github.com/grafana/grafana/pkg/services/ssosettings/ssosettingsimpl"
|
||||
)
|
||||
|
||||
func (s simpleSecret) Rollback(
|
||||
@ -317,26 +316,10 @@ func (s ssoSettingsSecret) Rollback(
|
||||
|
||||
for _, result := range results {
|
||||
err := sqlStore.WithTransactionalDbSession(ctx, func(sess *db.Session) error {
|
||||
for field, value := range result.Settings {
|
||||
if ssosettingsimpl.IsSecretField(field) {
|
||||
decrypted, err := s.decryptValue(ctx, value, secretsSrv)
|
||||
if err != nil {
|
||||
logger.Warn("Could not decrypt SSO settings secret", "id", result.ID, "field", field, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if decrypted == nil {
|
||||
continue
|
||||
}
|
||||
|
||||
reencrypted, err := encryptionSrv.Encrypt(ctx, decrypted, secretKey)
|
||||
if err != nil {
|
||||
logger.Warn("Could not re-encrypt SSO settings secret", "id", result.ID, "field", field, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
result.Settings[field] = base64.RawStdEncoding.EncodeToString(reencrypted)
|
||||
}
|
||||
result.Settings, err = s.reEncryptSecretsInMap(ctx, result.Settings, secretsSrv, encryptionSrv, secretKey)
|
||||
if err != nil {
|
||||
logger.Warn("failed rolling back SSO settings secret", "id", result.ID, "error", err)
|
||||
return err
|
||||
}
|
||||
|
||||
err = sqlStore.WithDbSession(ctx, func(sess *db.Session) error {
|
||||
|
Reference in New Issue
Block a user