Skip to content

Commit 1cf403e

Browse files
committed
add type checks
1 parent 214576c commit 1cf403e

File tree

1 file changed

+40
-36
lines changed

1 file changed

+40
-36
lines changed

src/sentry/api/authentication.py

Lines changed: 40 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -311,38 +311,54 @@ def authenticate(self, request: Request):
311311
class UserAuthTokenAuthentication(StandardAuthentication):
312312
token_name = b"bearer"
313313

314-
def _find_or_update_token_by_hash(self, token_str: str) -> ApiToken:
314+
def _find_or_update_token_by_hash(self, token_str: str) -> ApiToken | ApiTokenReplica:
315315
"""
316316
Find token by hash or update token's hash value if only found via plaintext.
317+
317318
1. Hash provided plaintext token.
318319
2. Perform lookup based on hashed value.
319320
3. If found, return the token.
320321
4. If not found, search for the token based on its plaintext value.
321322
5. If found, update the token's hashed value and return the token.
322323
6. If not found via hash or plaintext value, raise AuthenticationFailed
324+
325+
Returns `ApiTokenReplica` if running in REGION silo or
326+
`ApiToken` if running in CONTROL silo.
323327
"""
324328

325329
hashed_token = hashlib.sha256(token_str.encode()).hexdigest()
326330

327-
try:
328-
# Try to find the token by its hashed value first
329-
return ApiToken.objects.select_related("user", "application").get(
330-
hashed_token=hashed_token
331-
)
332-
except ApiToken.DoesNotExist:
331+
if SiloMode.get_current_mode() == SiloMode.REGION:
332+
try:
333+
# Try to find the token by its hashed value first
334+
return ApiTokenReplica.objects.get(hashed_token=hashed_token)
335+
except ApiTokenReplica.DoesNotExist:
336+
try:
337+
# If we can't find it by hash, use the plaintext string
338+
return ApiTokenReplica.objects.get(token=token_str)
339+
except ApiTokenReplica.DoesNotExist:
340+
# If the token does not exist by plaintext either, it is not a valid token
341+
raise AuthenticationFailed("Invalid token")
342+
else:
333343
try:
334-
# If we can't find it by hash, use the plaintext string
335-
api_token = ApiToken.objects.select_related("user", "application").get(
336-
token=token_str
344+
# Try to find the token by its hashed value first
345+
return ApiToken.objects.select_related("user", "application").get(
346+
hashed_token=hashed_token
337347
)
338348
except ApiToken.DoesNotExist:
339-
# If the token does not exist by plaintext either, it is not a valid token
340-
raise AuthenticationFailed("Invalid token")
341-
else:
342-
# Update it with the hashed value if found by plaintext
343-
api_token.hashed_token = hashed_token
344-
api_token.save(update_fields=["hashed_token"])
345-
return api_token
349+
try:
350+
# If we can't find it by hash, use the plaintext string
351+
api_token = ApiToken.objects.select_related("user", "application").get(
352+
token=token_str
353+
)
354+
except ApiToken.DoesNotExist:
355+
# If the token does not exist by plaintext either, it is not a valid token
356+
raise AuthenticationFailed("Invalid token")
357+
else:
358+
# Update it with the hashed value if found by plaintext
359+
api_token.hashed_token = hashed_token
360+
api_token.save(update_fields=["hashed_token"])
361+
return api_token
346362

347363
def accepts_auth(self, auth: list[bytes]) -> bool:
348364
if not super().accepts_auth(auth):
@@ -366,26 +382,14 @@ def authenticate_token(self, request: Request, token_str: str) -> tuple[Any, Any
366382
application_is_inactive = False
367383

368384
if not token:
369-
if SiloMode.get_current_mode() == SiloMode.REGION:
370-
try:
371-
# Try to find the token by its hashed value first
372-
hashed_token = hashlib.sha256(token_str.encode()).hexdigest()
373-
atr = token = ApiTokenReplica.objects.get(hashed_token=hashed_token)
374-
except ApiTokenReplica.DoesNotExist:
375-
try:
376-
# If we can't find it by hash, use the plaintext string
377-
atr = token = ApiTokenReplica.objects.get(token=token_str)
378-
except ApiTokenReplica.DoesNotExist:
379-
# If the token does not exist by plaintext either, it is not a valid token
380-
raise AuthenticationFailed("Invalid token")
381-
else:
382-
user = user_service.get_user(user_id=atr.user_id)
383-
application_is_inactive = not atr.application_is_active
384-
else:
385-
at = token = self._find_or_update_token_by_hash(token_str)
386-
user = at.user
385+
token = self._find_or_update_token_by_hash(token_str)
386+
if isinstance(token, ApiTokenReplica): # we're running as a REGION silo
387+
user = user_service.get_user(user_id=token.user_id)
388+
application_is_inactive = not token.application_is_active
389+
else: # the token returned is an ApiToken from the CONTROL silo
390+
user = token.user
387391
application_is_inactive = (
388-
at.application is not None and not at.application.is_active
392+
token.application is not None and not token.application.is_active
389393
)
390394

391395
elif isinstance(token, SystemToken):

0 commit comments

Comments
 (0)