Skip to content

Commit 0b63d04

Browse files
committed
make salt an env var
1 parent 751ea11 commit 0b63d04

4 files changed

Lines changed: 20 additions & 30 deletions

File tree

src/sentry/auth/email_verification.py

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import time
77
from typing import Any
88

9+
from django.conf import settings
910
from django.core.signing import BadSignature, SignatureExpired
1011
from django.http import HttpRequest
1112
from django.urls import reverse
@@ -21,10 +22,6 @@
2122
DEFAULT_MAX_AGE_MINUTES = 120
2223

2324

24-
def _get_salt() -> str:
25-
return options.get("auth.signup-verification-email-salt")
26-
27-
2825
def send_signup_verification_email(
2926
request: HttpRequest,
3027
email: str,
@@ -44,7 +41,7 @@ def send_signup_verification_email(
4441
"session_id": request.session.session_key,
4542
"expires_at": time.time() + (max_age_minutes * 60),
4643
}
47-
signed_data = sign(salt=_get_salt(), **payload)
44+
signed_data = sign(salt=settings.SIGNUP_VERIFICATION_EMAIL_SALT, **payload)
4845

4946
url = absolute_uri(reverse("sentry-signup-verify-email", args=[signed_data]))
5047

@@ -82,7 +79,7 @@ def unsign_signup_verification(signed_data: str, request: HttpRequest) -> dict[s
8279
Raises BadSignature, SignatureExpired, ValueError on failure.
8380
"""
8481
try:
85-
payload = unsign(signed_data, salt=_get_salt(), max_age=None)
82+
payload = unsign(signed_data, salt=settings.SIGNUP_VERIFICATION_EMAIL_SALT, max_age=None)
8683
except binascii.Error as e:
8784
# A malformed link is just an invalid signature to us.
8885
raise BadSignature("Malformed verification link") from e

src/sentry/conf/server.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -727,6 +727,11 @@ def env(
727727
# Protect login/registration endpoints during development phase
728728
AUTH_V2_SECRET = os.environ.get("AUTH_V2_SECRET", None)
729729

730+
# Used when signing signup email-verification links
731+
SIGNUP_VERIFICATION_EMAIL_SALT = os.environ.get(
732+
"SIGNUP_VERIFICATION_EMAIL_SALT", "signup-verification-email-salt"
733+
)
734+
730735
# Auth engines and the settings required for them to be listed
731736
AUTH_PROVIDERS = {
732737
"github": ("GITHUB_APP_ID", "GITHUB_API_SECRET"),

src/sentry/options/defaults.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -271,13 +271,6 @@
271271
default=False,
272272
flags=FLAG_ALLOW_EMPTY | FLAG_PRIORITIZE_DISK | FLAG_REQUIRED,
273273
)
274-
register(
275-
"auth.signup-verification-email-salt",
276-
type=String,
277-
default="signup-verification-email-salt",
278-
flags=FLAG_ALLOW_EMPTY | FLAG_PRIORITIZE_DISK | FLAG_AUTOMATOR_MODIFIABLE,
279-
)
280-
281274
# User Settings
282275
register(
283276
"user-settings.signed-url-confirmation-emails-salt",

tests/sentry/auth/test_email_verification.py

Lines changed: 12 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
from unittest import mock
33

44
import pytest
5+
from django.conf import settings
56
from django.core.signing import BadSignature, SignatureExpired
67
from django.test import RequestFactory
78

@@ -13,7 +14,7 @@
1314
from sentry.testutils.silo import control_silo_test
1415
from sentry.utils.signing import sign
1516

16-
TEST_SALT = "test-salt"
17+
SALT = settings.SIGNUP_VERIFICATION_EMAIL_SALT
1718

1819

1920
@control_silo_test
@@ -90,44 +91,38 @@ def setUp(self) -> None:
9091
session.session_key = "s1"
9192
self.request.session = session
9293

93-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
94-
def test_valid_signature(self, mock_salt: mock.MagicMock) -> None:
94+
def test_valid_signature(self) -> None:
9595
exp = time.time() + 300
96-
signed = sign(salt=TEST_SALT, email="[email protected]", session_id="s1", expires_at=exp)
96+
signed = sign(salt=SALT, email="[email protected]", session_id="s1", expires_at=exp)
9797
result = unsign_signup_verification(signed, self.request)
9898
assert result["email"] == "[email protected]"
9999
assert result["session_id"] == "s1"
100100

101-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
102-
def test_expired_link(self, mock_salt: mock.MagicMock) -> None:
101+
def test_expired_link(self) -> None:
103102
exp = time.time() - 1
104-
signed = sign(salt=TEST_SALT, email="[email protected]", session_id="s1", expires_at=exp)
103+
signed = sign(salt=SALT, email="[email protected]", session_id="s1", expires_at=exp)
105104
with pytest.raises(SignatureExpired):
106105
unsign_signup_verification(signed, self.request)
107106

108-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
109-
def test_tampered_signature(self, mock_salt: mock.MagicMock) -> None:
107+
def test_tampered_signature(self) -> None:
110108
exp = time.time() + 300
111-
signed = sign(salt=TEST_SALT, email="[email protected]", session_id="s1", expires_at=exp)
109+
signed = sign(salt=SALT, email="[email protected]", session_id="s1", expires_at=exp)
112110
tampered = signed[:-1] + ("A" if signed[-1] != "A" else "B")
113111
with pytest.raises(BadSignature):
114112
unsign_signup_verification(tampered, self.request)
115113

116-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
117-
def test_malformed_link_throws_bad_sig(self, mock_salt: mock.MagicMock) -> None:
114+
def test_malformed_link_throws_bad_sig(self) -> None:
118115
with pytest.raises(BadSignature):
119116
unsign_signup_verification("not-valid-base64-!!!", self.request)
120117

121-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
122-
def test_wrong_salt(self, mock_salt: mock.MagicMock) -> None:
118+
def test_wrong_salt(self) -> None:
123119
exp = time.time() + 300
124120
signed = sign(salt="wrong-salt", email="[email protected]", session_id="s1", expires_at=exp)
125121
with pytest.raises(BadSignature):
126122
unsign_signup_verification(signed, self.request)
127123

128-
@mock.patch("sentry.auth.email_verification._get_salt", return_value=TEST_SALT)
129-
def test_session_mismatch(self, mock_salt: mock.MagicMock) -> None:
124+
def test_session_mismatch(self) -> None:
130125
exp = time.time() + 300
131-
signed = sign(salt=TEST_SALT, email="[email protected]", session_id="else", expires_at=exp)
126+
signed = sign(salt=SALT, email="[email protected]", session_id="else", expires_at=exp)
132127
with pytest.raises(ValueError, match="Session mismatch"):
133128
unsign_signup_verification(signed, self.request)

0 commit comments

Comments
 (0)