refactor(webhooks): address PR review on auth-pass
- webhook_receiver: always run hmac.compare_digest (drop the `not provided or` short-circuit) so the constant-time path is taken regardless of whether the Authorization header is present. - client/webhooks: modernise the new `auth_data` type hint to `dict[str, str] | None` per CLAUDE.md. - tests/client: rename `test_create_webhook_with_auth_headers` → `test_create_webhook_with_static_headers` and use `auth_method="header"` (NC's webhook_listeners only supports "none" and "header"; the previous "bearer" value was invalid). - auth/webhook_routes: extract `_register_preset_webhooks` from `enable_webhook_preset` so the auth-threading behaviour is testable without standing up a Starlette app + auth middleware. - tests/unit: new test_webhook_routes_register covering the helper with secret set / unset, and verifying ids round-trip in order. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.7
parent
224428fca5
commit
f5f05b7c84
@@ -53,7 +53,10 @@ async def handle_nextcloud_webhook(request: Request) -> JSONResponse:
|
||||
if secret:
|
||||
provided = request.headers.get("authorization", "")
|
||||
expected = f"Bearer {secret}"
|
||||
if not provided or not hmac.compare_digest(provided, expected):
|
||||
# Always run compare_digest so the constant-time path is taken even
|
||||
# when the header is missing — `compare_digest("", expected)` returns
|
||||
# False without leaking length information.
|
||||
if not hmac.compare_digest(provided, expected):
|
||||
logger.warning("Webhook rejected: missing or invalid Authorization header")
|
||||
return JSONResponse(
|
||||
{"status": "unauthorized"},
|
||||
|
||||
Reference in New Issue
Block a user