Skip to content

Commit f80d198

Browse files
committed
fix(oauth): Add atomic status check to deny action
Use the same atomic filter().update() pattern as approval to prevent race condition where denial could overwrite an already-approved device code, causing inconsistent state (ApiAuthorization exists but client receives access_denied).
1 parent 24aa362 commit f80d198

File tree

1 file changed

+9
-2
lines changed

1 file changed

+9
-2
lines changed

src/sentry/web/frontend/oauth_device.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -227,8 +227,15 @@ def _show_approval_form(self, request: HttpRequest, user_code: str) -> HttpRespo
227227

228228
def _handle_deny(self, request: HttpRequest, device_code: ApiDeviceCode) -> HttpResponseBase:
229229
"""Handle deny action for a device code."""
230-
device_code.status = DeviceCodeStatus.DENIED
231-
device_code.save(update_fields=["status"])
230+
# Atomically mark as denied only if still pending (prevents race with approve)
231+
updated = ApiDeviceCode.objects.filter(
232+
id=device_code.id,
233+
status=DeviceCodeStatus.PENDING,
234+
).update(status=DeviceCodeStatus.DENIED)
235+
236+
if not updated:
237+
# Another request already processed this device code
238+
return self._error_response(request, ERR_INVALID_CODE)
232239

233240
metrics.incr("oauth_device.deny", sample_rate=1.0)
234241
logger.info(

0 commit comments

Comments
 (0)