Skip to content

Commit

Permalink
chore: move config copy to diff method
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Nov 12, 2024
1 parent 7d99f80 commit ea34828
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 112 deletions.
31 changes: 14 additions & 17 deletions pkg/config/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -55,40 +55,37 @@ func (a *api) ToUpdatePostgrestConfigBody() v1API.UpdatePostgrestConfigBody {
return body
}

func (a *api) fromRemoteApiConfig(remoteConfig v1API.PostgrestConfigWithJWTSecretResponse) api {
result := *a
if remoteConfig.DbSchema == "" {
result.Enabled = false
return result
func (a *api) fromRemoteApiConfig(remoteConfig v1API.PostgrestConfigWithJWTSecretResponse) {
if a.Enabled = len(remoteConfig.DbSchema) > 0; !a.Enabled {
return
}

result.Enabled = true
// Update Schemas if present in remoteConfig
result.Schemas = strToArr(remoteConfig.DbSchema)
a.Schemas = strToArr(remoteConfig.DbSchema)
// TODO: use slices.Map when upgrade go version
for i, schema := range result.Schemas {
result.Schemas[i] = strings.TrimSpace(schema)
for i, schema := range a.Schemas {
a.Schemas[i] = strings.TrimSpace(schema)
}

// Update ExtraSearchPath if present in remoteConfig
result.ExtraSearchPath = strToArr(remoteConfig.DbExtraSearchPath)
for i, path := range result.ExtraSearchPath {
result.ExtraSearchPath[i] = strings.TrimSpace(path)
a.ExtraSearchPath = strToArr(remoteConfig.DbExtraSearchPath)
for i, path := range a.ExtraSearchPath {
a.ExtraSearchPath[i] = strings.TrimSpace(path)
}

// Update MaxRows if present in remoteConfig
result.MaxRows = cast.IntToUint(remoteConfig.MaxRows)

return result
a.MaxRows = cast.IntToUint(remoteConfig.MaxRows)
}

func (a *api) DiffWithRemote(remoteConfig v1API.PostgrestConfigWithJWTSecretResponse) ([]byte, error) {
copy := *a
// Convert the config values into easily comparable remoteConfig values
currentValue, err := ToTomlBytes(a)
currentValue, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
remoteCompare, err := ToTomlBytes(a.fromRemoteApiConfig(remoteConfig))
copy.fromRemoteApiConfig(remoteConfig)
remoteCompare, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
Expand Down
97 changes: 44 additions & 53 deletions pkg/config/auth.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package config

import (
"maps"
"strconv"
"strings"
"time"
Expand Down Expand Up @@ -201,24 +200,21 @@ func (a *auth) ToUpdateAuthConfigBody() v1API.UpdateAuthConfigBody {
return body
}

func (a *auth) fromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) auth {
result := *a
result.SiteUrl = cast.Val(remoteConfig.SiteUrl, "")
result.AdditionalRedirectUrls = strToArr(cast.Val(remoteConfig.UriAllowList, ""))
result.JwtExpiry = cast.IntToUint(cast.Val(remoteConfig.JwtExp, 0))
result.EnableRefreshTokenRotation = cast.Val(remoteConfig.RefreshTokenRotationEnabled, false)
result.RefreshTokenReuseInterval = cast.IntToUint(cast.Val(remoteConfig.SecurityRefreshTokenReuseInterval, 0))
result.EnableManualLinking = cast.Val(remoteConfig.SecurityManualLinkingEnabled, false)
result.EnableSignup = !cast.Val(remoteConfig.DisableSignup, false)
result.EnableAnonymousSignIns = cast.Val(remoteConfig.ExternalAnonymousUsersEnabled, false)
result.Hook.fromAuthConfig(remoteConfig)
result.MFA.fromAuthConfig(remoteConfig)
result.Sessions.fromAuthConfig(remoteConfig)
result.Email.fromAuthConfig(remoteConfig)
result.Sms.fromAuthConfig(remoteConfig)
result.External = maps.Clone(result.External)
result.External.fromAuthConfig(remoteConfig)
return result
func (a *auth) fromRemoteAuthConfig(remoteConfig v1API.AuthConfigResponse) {
a.SiteUrl = cast.Val(remoteConfig.SiteUrl, "")
a.AdditionalRedirectUrls = strToArr(cast.Val(remoteConfig.UriAllowList, ""))
a.JwtExpiry = cast.IntToUint(cast.Val(remoteConfig.JwtExp, 0))
a.EnableRefreshTokenRotation = cast.Val(remoteConfig.RefreshTokenRotationEnabled, false)
a.RefreshTokenReuseInterval = cast.IntToUint(cast.Val(remoteConfig.SecurityRefreshTokenReuseInterval, 0))
a.EnableManualLinking = cast.Val(remoteConfig.SecurityManualLinkingEnabled, false)
a.EnableSignup = !cast.Val(remoteConfig.DisableSignup, false)
a.EnableAnonymousSignIns = cast.Val(remoteConfig.ExternalAnonymousUsersEnabled, false)
a.Hook.fromAuthConfig(remoteConfig)
a.MFA.fromAuthConfig(remoteConfig)
a.Sessions.fromAuthConfig(remoteConfig)
a.Email.fromAuthConfig(remoteConfig)
a.Sms.fromAuthConfig(remoteConfig)
a.External.fromAuthConfig(remoteConfig)
}

func (h hook) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
Expand Down Expand Up @@ -696,13 +692,15 @@ func (e external) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
}

func (a *auth) DiffWithRemote(projectRef string, remoteConfig v1API.AuthConfigResponse) ([]byte, error) {
hashed := a.hashSecrets(projectRef)
copy := a.Clone()
copy.hashSecrets(projectRef)
// Convert the config values into easily comparable remoteConfig values
currentValue, err := ToTomlBytes(hashed)
currentValue, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
remoteCompare, err := ToTomlBytes(hashed.fromRemoteAuthConfig(remoteConfig))
copy.fromRemoteAuthConfig(remoteConfig)
remoteCompare, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
Expand All @@ -711,53 +709,46 @@ func (a *auth) DiffWithRemote(projectRef string, remoteConfig v1API.AuthConfigRe

const hashPrefix = "hash:"

func (a *auth) hashSecrets(key string) auth {
func (a *auth) hashSecrets(key string) {
hash := func(v string) string {
return hashPrefix + sha256Hmac(key, v)
}
result := *a
if result.Email.Smtp != nil && len(result.Email.Smtp.Pass) > 0 {
copy := *result.Email.Smtp
copy.Pass = hash(result.Email.Smtp.Pass)
result.Email.Smtp = &copy
if a.Email.Smtp != nil && len(a.Email.Smtp.Pass) > 0 {
a.Email.Smtp.Pass = hash(a.Email.Smtp.Pass)
}
// Only hash secrets for locally enabled providers because other envs won't be loaded
switch {
case result.Sms.Twilio.Enabled:
result.Sms.Twilio.AuthToken = hash(result.Sms.Twilio.AuthToken)
case result.Sms.TwilioVerify.Enabled:
result.Sms.TwilioVerify.AuthToken = hash(result.Sms.TwilioVerify.AuthToken)
case result.Sms.Messagebird.Enabled:
result.Sms.Messagebird.AccessKey = hash(result.Sms.Messagebird.AccessKey)
case result.Sms.Textlocal.Enabled:
result.Sms.Textlocal.ApiKey = hash(result.Sms.Textlocal.ApiKey)
case result.Sms.Vonage.Enabled:
result.Sms.Vonage.ApiSecret = hash(result.Sms.Vonage.ApiSecret)
case a.Sms.Twilio.Enabled:
a.Sms.Twilio.AuthToken = hash(a.Sms.Twilio.AuthToken)
case a.Sms.TwilioVerify.Enabled:
a.Sms.TwilioVerify.AuthToken = hash(a.Sms.TwilioVerify.AuthToken)
case a.Sms.Messagebird.Enabled:
a.Sms.Messagebird.AccessKey = hash(a.Sms.Messagebird.AccessKey)
case a.Sms.Textlocal.Enabled:
a.Sms.Textlocal.ApiKey = hash(a.Sms.Textlocal.ApiKey)
case a.Sms.Vonage.Enabled:
a.Sms.Vonage.ApiSecret = hash(a.Sms.Vonage.ApiSecret)
}
if result.Hook.MFAVerificationAttempt.Enabled {
result.Hook.MFAVerificationAttempt.Secrets = hash(result.Hook.MFAVerificationAttempt.Secrets)
if a.Hook.MFAVerificationAttempt.Enabled {
a.Hook.MFAVerificationAttempt.Secrets = hash(a.Hook.MFAVerificationAttempt.Secrets)
}
if result.Hook.PasswordVerificationAttempt.Enabled {
result.Hook.PasswordVerificationAttempt.Secrets = hash(result.Hook.PasswordVerificationAttempt.Secrets)
if a.Hook.PasswordVerificationAttempt.Enabled {
a.Hook.PasswordVerificationAttempt.Secrets = hash(a.Hook.PasswordVerificationAttempt.Secrets)
}
if result.Hook.CustomAccessToken.Enabled {
result.Hook.CustomAccessToken.Secrets = hash(result.Hook.CustomAccessToken.Secrets)
if a.Hook.CustomAccessToken.Enabled {
a.Hook.CustomAccessToken.Secrets = hash(a.Hook.CustomAccessToken.Secrets)
}
if result.Hook.SendSMS.Enabled {
result.Hook.SendSMS.Secrets = hash(result.Hook.SendSMS.Secrets)
if a.Hook.SendSMS.Enabled {
a.Hook.SendSMS.Secrets = hash(a.Hook.SendSMS.Secrets)
}
if result.Hook.SendEmail.Enabled {
result.Hook.SendEmail.Secrets = hash(result.Hook.SendEmail.Secrets)
}
if size := len(a.External); size > 0 {
result.External = make(map[string]provider, size)
if a.Hook.SendEmail.Enabled {
a.Hook.SendEmail.Secrets = hash(a.Hook.SendEmail.Secrets)
}
for name, provider := range a.External {
if provider.Enabled {
provider.Secret = hash(provider.Secret)
}
result.External[name] = provider
a.External[name] = provider
}
// TODO: support SecurityCaptchaSecret in local config
return result
}
20 changes: 13 additions & 7 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,17 +214,23 @@ func (f function) IsEnabled() bool {
return f.Enabled == nil || *f.Enabled
}

func (a *auth) Clone() auth {
copy := *a
copy.External = maps.Clone(a.External)
if a.Email.Smtp != nil {
mailer := *a.Email.Smtp
copy.Email.Smtp = &mailer
}
copy.Email.Template = maps.Clone(a.Email.Template)
copy.Sms.TestOTP = maps.Clone(a.Sms.TestOTP)
return copy
}

func (c *baseConfig) Clone() baseConfig {
copy := *c
copy.Storage.Buckets = maps.Clone(c.Storage.Buckets)
copy.Functions = maps.Clone(c.Functions)
copy.Auth.External = maps.Clone(c.Auth.External)
if c.Auth.Email.Smtp != nil {
mailer := *c.Auth.Email.Smtp
copy.Auth.Email.Smtp = &mailer
}
copy.Auth.Email.Template = maps.Clone(c.Auth.Email.Template)
copy.Auth.Sms.TestOTP = maps.Clone(c.Auth.Sms.TestOTP)
copy.Auth = c.Auth.Clone()
if c.Experimental.Webhooks != nil {
webhooks := *c.Experimental.Webhooks
copy.Experimental.Webhooks = &webhooks
Expand Down
55 changes: 27 additions & 28 deletions pkg/config/db.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,32 +112,29 @@ func (a *settings) ToUpdatePostgresConfigBody() v1API.UpdatePostgresConfigBody {
return body
}

func (a *settings) fromRemoteConfig(remoteConfig v1API.PostgresConfigResponse) settings {
result := *a

result.EffectiveCacheSize = remoteConfig.EffectiveCacheSize
result.LogicalDecodingWorkMem = remoteConfig.LogicalDecodingWorkMem
result.MaintenanceWorkMem = remoteConfig.MaintenanceWorkMem
result.MaxConnections = cast.IntToUintPtr(remoteConfig.MaxConnections)
result.MaxLocksPerTransaction = cast.IntToUintPtr(remoteConfig.MaxLocksPerTransaction)
result.MaxParallelMaintenanceWorkers = cast.IntToUintPtr(remoteConfig.MaxParallelMaintenanceWorkers)
result.MaxParallelWorkers = cast.IntToUintPtr(remoteConfig.MaxParallelWorkers)
result.MaxParallelWorkersPerGather = cast.IntToUintPtr(remoteConfig.MaxParallelWorkersPerGather)
result.MaxReplicationSlots = cast.IntToUintPtr(remoteConfig.MaxReplicationSlots)
result.MaxSlotWalKeepSize = remoteConfig.MaxSlotWalKeepSize
result.MaxStandbyArchiveDelay = remoteConfig.MaxStandbyArchiveDelay
result.MaxStandbyStreamingDelay = remoteConfig.MaxStandbyStreamingDelay
result.MaxWalSenders = cast.IntToUintPtr(remoteConfig.MaxWalSenders)
result.MaxWalSize = remoteConfig.MaxWalSize
result.MaxWorkerProcesses = cast.IntToUintPtr(remoteConfig.MaxWorkerProcesses)
result.SessionReplicationRole = (*SessionReplicationRole)(remoteConfig.SessionReplicationRole)
result.SharedBuffers = remoteConfig.SharedBuffers
result.StatementTimeout = remoteConfig.StatementTimeout
result.TrackCommitTimestamp = remoteConfig.TrackCommitTimestamp
result.WalKeepSize = remoteConfig.WalKeepSize
result.WalSenderTimeout = remoteConfig.WalSenderTimeout
result.WorkMem = remoteConfig.WorkMem
return result
func (a *settings) fromRemoteConfig(remoteConfig v1API.PostgresConfigResponse) {
a.EffectiveCacheSize = remoteConfig.EffectiveCacheSize
a.LogicalDecodingWorkMem = remoteConfig.LogicalDecodingWorkMem
a.MaintenanceWorkMem = remoteConfig.MaintenanceWorkMem
a.MaxConnections = cast.IntToUintPtr(remoteConfig.MaxConnections)
a.MaxLocksPerTransaction = cast.IntToUintPtr(remoteConfig.MaxLocksPerTransaction)
a.MaxParallelMaintenanceWorkers = cast.IntToUintPtr(remoteConfig.MaxParallelMaintenanceWorkers)
a.MaxParallelWorkers = cast.IntToUintPtr(remoteConfig.MaxParallelWorkers)
a.MaxParallelWorkersPerGather = cast.IntToUintPtr(remoteConfig.MaxParallelWorkersPerGather)
a.MaxReplicationSlots = cast.IntToUintPtr(remoteConfig.MaxReplicationSlots)
a.MaxSlotWalKeepSize = remoteConfig.MaxSlotWalKeepSize
a.MaxStandbyArchiveDelay = remoteConfig.MaxStandbyArchiveDelay
a.MaxStandbyStreamingDelay = remoteConfig.MaxStandbyStreamingDelay
a.MaxWalSenders = cast.IntToUintPtr(remoteConfig.MaxWalSenders)
a.MaxWalSize = remoteConfig.MaxWalSize
a.MaxWorkerProcesses = cast.IntToUintPtr(remoteConfig.MaxWorkerProcesses)
a.SessionReplicationRole = (*SessionReplicationRole)(remoteConfig.SessionReplicationRole)
a.SharedBuffers = remoteConfig.SharedBuffers
a.StatementTimeout = remoteConfig.StatementTimeout
a.TrackCommitTimestamp = remoteConfig.TrackCommitTimestamp
a.WalKeepSize = remoteConfig.WalKeepSize
a.WalSenderTimeout = remoteConfig.WalSenderTimeout
a.WorkMem = remoteConfig.WorkMem
}

const pgConfHeader = "\n# supabase [db.settings] configuration\n"
Expand All @@ -152,12 +149,14 @@ func (a *settings) ToPostgresConfig() string {
}

func (a *settings) DiffWithRemote(remoteConfig v1API.PostgresConfigResponse) ([]byte, error) {
copy := *a
// Convert the config values into easily comparable remoteConfig values
currentValue, err := ToTomlBytes(a)
currentValue, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
remoteCompare, err := ToTomlBytes(a.fromRemoteConfig(remoteConfig))
copy.fromRemoteConfig(remoteConfig)
remoteCompare, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/config/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,20 @@ func (s *storage) ToUpdateStorageConfigBody() v1API.UpdateStorageConfigBody {
return body
}

func (s *storage) fromRemoteStorageConfig(remoteConfig v1API.StorageConfigResponse) storage {
result := *s
result.FileSizeLimit = sizeInBytes(remoteConfig.FileSizeLimit)
result.ImageTransformation.Enabled = remoteConfig.Features.ImageTransformation.Enabled
return result
func (s *storage) fromRemoteStorageConfig(remoteConfig v1API.StorageConfigResponse) {
s.FileSizeLimit = sizeInBytes(remoteConfig.FileSizeLimit)
s.ImageTransformation.Enabled = remoteConfig.Features.ImageTransformation.Enabled
}

func (s *storage) DiffWithRemote(remoteConfig v1API.StorageConfigResponse) ([]byte, error) {
copy := *s
// Convert the config values into easily comparable remoteConfig values
currentValue, err := ToTomlBytes(s)
currentValue, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
remoteCompare, err := ToTomlBytes(s.fromRemoteStorageConfig(remoteConfig))
copy.fromRemoteStorageConfig(remoteConfig)
remoteCompare, err := ToTomlBytes(copy)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit ea34828

Please sign in to comment.