Skip to content

Commit

Permalink
chore: parse encrypted hook secret
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Jan 8, 2025
1 parent 80c2e05 commit eda27f6
Show file tree
Hide file tree
Showing 7 changed files with 64 additions and 61 deletions.
10 changes: 5 additions & 5 deletions internal/start/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -590,39 +590,39 @@ EOF
env,
"GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_ENABLED=true",
"GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_URI="+hook.URI,
"GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_SECRETS="+hook.Secrets,
"GOTRUE_HOOK_MFA_VERIFICATION_ATTEMPT_SECRETS="+hook.Secrets.Value,
)
}
if hook := utils.Config.Auth.Hook.PasswordVerificationAttempt; hook != nil && hook.Enabled {
env = append(
env,
"GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_ENABLED=true",
"GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_URI="+hook.URI,
"GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_SECRETS="+hook.Secrets,
"GOTRUE_HOOK_PASSWORD_VERIFICATION_ATTEMPT_SECRETS="+hook.Secrets.Value,
)
}
if hook := utils.Config.Auth.Hook.CustomAccessToken; hook != nil && hook.Enabled {
env = append(
env,
"GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_ENABLED=true",
"GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_URI="+hook.URI,
"GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_SECRETS="+hook.Secrets,
"GOTRUE_HOOK_CUSTOM_ACCESS_TOKEN_SECRETS="+hook.Secrets.Value,
)
}
if hook := utils.Config.Auth.Hook.SendSMS; hook != nil && hook.Enabled {
env = append(
env,
"GOTRUE_HOOK_SEND_SMS_ENABLED=true",
"GOTRUE_HOOK_SEND_SMS_URI="+hook.URI,
"GOTRUE_HOOK_SEND_SMS_SECRETS="+hook.Secrets,
"GOTRUE_HOOK_SEND_SMS_SECRETS="+hook.Secrets.Value,
)
}
if hook := utils.Config.Auth.Hook.SendEmail; hook != nil && hook.Enabled {
env = append(
env,
"GOTRUE_HOOK_SEND_EMAIL_ENABLED=true",
"GOTRUE_HOOK_SEND_EMAIL_URI="+hook.URI,
"GOTRUE_HOOK_SEND_EMAIL_SECRETS="+hook.Secrets,
"GOTRUE_HOOK_SEND_EMAIL_SECRETS="+hook.Secrets.Value,
)
}

Expand Down
57 changes: 21 additions & 36 deletions pkg/config/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ type (
hookConfig struct {
Enabled bool `toml:"enabled"`
URI string `toml:"uri"`
Secrets string `toml:"secrets"`
Secrets Secret `toml:"secrets"`
}

sessions struct {
Expand Down Expand Up @@ -265,41 +265,41 @@ func (h hook) toAuthConfigBody(body *v1API.UpdateAuthConfigBody) {
if hook := h.CustomAccessToken; hook != nil {
if body.HookCustomAccessTokenEnabled = &hook.Enabled; hook.Enabled {
body.HookCustomAccessTokenUri = &hook.URI
if len(hook.Secrets) > 0 {
body.HookCustomAccessTokenSecrets = &hook.Secrets
if len(hook.Secrets.Value) > 0 {
body.HookCustomAccessTokenSecrets = &hook.Secrets.Value
}
}
}
if hook := h.SendEmail; hook != nil {
if body.HookSendEmailEnabled = &hook.Enabled; hook.Enabled {
body.HookSendEmailUri = &hook.URI
if len(hook.Secrets) > 0 {
body.HookSendEmailSecrets = &hook.Secrets
if len(hook.Secrets.Value) > 0 {
body.HookSendEmailSecrets = &hook.Secrets.Value
}
}
}
if hook := h.SendSMS; hook != nil {
if body.HookSendSmsEnabled = &hook.Enabled; hook.Enabled {
body.HookSendSmsUri = &hook.URI
if len(hook.Secrets) > 0 {
body.HookSendSmsSecrets = &hook.Secrets
if len(hook.Secrets.Value) > 0 {
body.HookSendSmsSecrets = &hook.Secrets.Value
}
}
}
// Enterprise and team only features
if hook := h.MFAVerificationAttempt; hook != nil {
if body.HookMfaVerificationAttemptEnabled = &hook.Enabled; hook.Enabled {
body.HookMfaVerificationAttemptUri = &hook.URI
if len(hook.Secrets) > 0 {
body.HookMfaVerificationAttemptSecrets = &hook.Secrets
if len(hook.Secrets.Value) > 0 {
body.HookMfaVerificationAttemptSecrets = &hook.Secrets.Value
}
}
}
if hook := h.PasswordVerificationAttempt; hook != nil {
if body.HookPasswordVerificationAttemptEnabled = &hook.Enabled; hook.Enabled {
body.HookPasswordVerificationAttemptUri = &hook.URI
if len(hook.Secrets) > 0 {
body.HookPasswordVerificationAttemptSecrets = &hook.Secrets
if len(hook.Secrets.Value) > 0 {
body.HookPasswordVerificationAttemptSecrets = &hook.Secrets.Value
}
}
}
Expand All @@ -310,26 +310,26 @@ func (h *hook) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
// Ignore disabled hooks because their envs are not loaded
if hook.Enabled {
hook.URI = cast.Val(remoteConfig.HookCustomAccessTokenUri, "")
if hook.Secrets != hashPrefix {
hook.Secrets = hashPrefix + cast.Val(remoteConfig.HookCustomAccessTokenSecrets, "")
if len(hook.Secrets.SHA256) > 0 {
hook.Secrets.SHA256 = cast.Val(remoteConfig.HookCustomAccessTokenSecrets, "")
}
}
hook.Enabled = cast.Val(remoteConfig.HookCustomAccessTokenEnabled, false)
}
if hook := h.SendEmail; hook != nil {
if hook.Enabled {
hook.URI = cast.Val(remoteConfig.HookSendEmailUri, "")
if hook.Secrets != hashPrefix {
hook.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendEmailSecrets, "")
if len(hook.Secrets.SHA256) > 0 {
hook.Secrets.SHA256 = cast.Val(remoteConfig.HookSendEmailSecrets, "")
}
}
hook.Enabled = cast.Val(remoteConfig.HookSendEmailEnabled, false)
}
if hook := h.SendSMS; hook != nil {
if hook.Enabled {
hook.URI = cast.Val(remoteConfig.HookSendSmsUri, "")
if hook.Secrets != hashPrefix {
hook.Secrets = hashPrefix + cast.Val(remoteConfig.HookSendSmsSecrets, "")
if len(hook.Secrets.SHA256) > 0 {
hook.Secrets.SHA256 = cast.Val(remoteConfig.HookSendSmsSecrets, "")
}
}
hook.Enabled = cast.Val(remoteConfig.HookSendSmsEnabled, false)
Expand All @@ -338,17 +338,17 @@ func (h *hook) fromAuthConfig(remoteConfig v1API.AuthConfigResponse) {
if hook := h.MFAVerificationAttempt; hook != nil {
if hook.Enabled {
hook.URI = cast.Val(remoteConfig.HookMfaVerificationAttemptUri, "")
if hook.Secrets != hashPrefix {
hook.Secrets = hashPrefix + cast.Val(remoteConfig.HookMfaVerificationAttemptSecrets, "")
if len(hook.Secrets.SHA256) > 0 {
hook.Secrets.SHA256 = cast.Val(remoteConfig.HookMfaVerificationAttemptSecrets, "")
}
}
hook.Enabled = cast.Val(remoteConfig.HookMfaVerificationAttemptEnabled, false)
}
if hook := h.PasswordVerificationAttempt; hook != nil {
if hook.Enabled {
hook.URI = cast.Val(remoteConfig.HookPasswordVerificationAttemptUri, "")
if hook.Secrets != hashPrefix {
hook.Secrets = hashPrefix + cast.Val(remoteConfig.HookPasswordVerificationAttemptSecrets, "")
if len(hook.Secrets.SHA256) > 0 {
hook.Secrets.SHA256 = cast.Val(remoteConfig.HookPasswordVerificationAttemptSecrets, "")
}
}
hook.Enabled = cast.Val(remoteConfig.HookPasswordVerificationAttemptEnabled, false)
Expand Down Expand Up @@ -978,21 +978,6 @@ func (a *auth) HashSecrets(key string) {
}
return hashPrefix + sha256Hmac(key, v)
}
if a.Hook.MFAVerificationAttempt != nil && a.Hook.MFAVerificationAttempt.Enabled {
a.Hook.MFAVerificationAttempt.Secrets = hash(a.Hook.MFAVerificationAttempt.Secrets)
}
if a.Hook.PasswordVerificationAttempt != nil && a.Hook.PasswordVerificationAttempt.Enabled {
a.Hook.PasswordVerificationAttempt.Secrets = hash(a.Hook.PasswordVerificationAttempt.Secrets)
}
if a.Hook.CustomAccessToken != nil && a.Hook.CustomAccessToken.Enabled {
a.Hook.CustomAccessToken.Secrets = hash(a.Hook.CustomAccessToken.Secrets)
}
if a.Hook.SendSMS != nil && a.Hook.SendSMS.Enabled {
a.Hook.SendSMS.Secrets = hash(a.Hook.SendSMS.Secrets)
}
if a.Hook.SendEmail != nil && 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)
Expand Down
32 changes: 25 additions & 7 deletions pkg/config/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -124,22 +124,34 @@ func TestHookDiff(t *testing.T) {
CustomAccessToken: &hookConfig{
Enabled: true,
URI: "http://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
SendSMS: &hookConfig{
Enabled: true,
URI: "http://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
SendEmail: &hookConfig{
Enabled: true,
URI: "https://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
MFAVerificationAttempt: &hookConfig{
Enabled: true,
URI: "https://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
PasswordVerificationAttempt: &hookConfig{
Enabled: true,
Expand Down Expand Up @@ -177,7 +189,7 @@ func TestHookDiff(t *testing.T) {
SendSMS: &hookConfig{
Enabled: false,
URI: "https://example.com",
Secrets: "test-secret",
Secrets: Secret{Value: "test-secret"},
},
SendEmail: &hookConfig{
Enabled: false,
Expand Down Expand Up @@ -215,12 +227,18 @@ func TestHookDiff(t *testing.T) {
CustomAccessToken: &hookConfig{
Enabled: true,
URI: "http://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
SendSMS: &hookConfig{
Enabled: true,
URI: "https://example.com",
Secrets: "test-secret",
Secrets: Secret{
Value: "test-secret",
SHA256: "ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252",
},
},
SendEmail: &hookConfig{
Enabled: true,
Expand Down
8 changes: 4 additions & 4 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -1075,18 +1075,18 @@ func (h *hookConfig) validate(hookType string) (err error) {
}
switch strings.ToLower(parsed.Scheme) {
case "http", "https":
if len(h.Secrets) == 0 {
if len(h.Secrets.Value) == 0 {
return errors.Errorf("Missing required field in config: auth.hook.%s.secrets", hookType)
} else if err := assertEnvLoaded(h.Secrets); err != nil {
} else if err := assertEnvLoaded(h.Secrets.Value); err != nil {
return err
}
for _, secret := range strings.Split(h.Secrets, "|") {
for _, secret := range strings.Split(h.Secrets.Value, "|") {
if !hookSecretPattern.MatchString(secret) {
return errors.Errorf(`Invalid hook config: auth.hook.%s.secrets must be formatted as "v1,whsec_<base64_encoded_secret>"`, hookType)
}
}
case "pg-functions":
if len(h.Secrets) > 0 {
if len(h.Secrets.Value) > 0 {
return errors.Errorf("Invalid hook config: auth.hook.%s.secrets is unsupported for pg-functions URI", hookType)
}
default:
Expand Down
10 changes: 5 additions & 5 deletions pkg/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,15 +214,15 @@ func TestValidateHookURI(t *testing.T) {
hookConfig: hookConfig{
Enabled: true,
URI: "http://example.com",
Secrets: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw==",
Secrets: Secret{Value: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw=="},
},
},
{
name: "valid https URL",
hookConfig: hookConfig{
Enabled: true,
URI: "https://example.com",
Secrets: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw==",
Secrets: Secret{Value: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw=="},
},
},
{
Expand All @@ -237,7 +237,7 @@ func TestValidateHookURI(t *testing.T) {
hookConfig: hookConfig{
Enabled: true,
URI: "ftp://example.com",
Secrets: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw==",
Secrets: Secret{Value: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw=="},
},
errorMsg: "Invalid hook config: auth.hook.invalid URI with unsupported scheme.uri should be a HTTP, HTTPS, or pg-functions URI",
},
Expand All @@ -246,7 +246,7 @@ func TestValidateHookURI(t *testing.T) {
hookConfig: hookConfig{
Enabled: true,
URI: "http://a b.com",
Secrets: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw==",
Secrets: Secret{Value: "v1,whsec_aWxpa2VzdXBhYmFzZXZlcnltdWNoYW5kaWhvcGV5b3Vkb3Rvbw=="},
},
errorMsg: "failed to parse template url: parse \"http://a b.com\": invalid character \" \" in host name",
},
Expand All @@ -263,7 +263,7 @@ func TestValidateHookURI(t *testing.T) {
hookConfig: hookConfig{
Enabled: true,
URI: "pg-functions://functionName",
Secrets: "test-secret",
Secrets: Secret{Value: "test-secret"},
},
errorMsg: "Invalid hook config: auth.hook.valid pg-functions URI with unsupported secrets.secrets is unsupported for pg-functions URI",
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ diff remote[auth] local[auth]
-enabled = true
+enabled = false
uri = "https://example.com"
secrets = "test-secret"
secrets = ""
[hook.send_email]
-enabled = true
+enabled = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ diff remote[auth] local[auth]
-enabled = false
+enabled = true
uri = "pg-functions://postgres/public/verifyMFA"
secrets = "hash:"
secrets = ""
[hook.custom_access_token]
-enabled = false
-uri = "pg-functions://postgres/public/customToken"
-secrets = "hash:"
-secrets = ""
+enabled = true
+uri = "http://example.com"
+secrets = "hash:ce62bb9bcced294fd4afe668f8ab3b50a89cf433093c526fffa3d0e46bf55252"
Expand All @@ -26,6 +26,6 @@ diff remote[auth] local[auth]
-uri = "https://example.com"
+enabled = true
+uri = "pg-functions://postgres/public/sendEmail"
secrets = "hash:"
secrets = ""

[mfa]

0 comments on commit eda27f6

Please sign in to comment.