From cfbff62c97221293a374e263bd12510a14a97e6f Mon Sep 17 00:00:00 2001 From: Sanjin <102841251+duckduckgrayduck@users.noreply.github.com> Date: Wed, 16 Sep 2026 14:11:46 -0500 Subject: [PATCH] Add details about JWT token usage under authorizations --- config/settings/base.py | 4 ++++ documentcloud/core/utils.py | 42 +++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) diff --git a/config/settings/base.py b/config/settings/base.py index dace4e2f..76957fa2 100644 --- a/config/settings/base.py +++ b/config/settings/base.py @@ -442,6 +442,10 @@ "SERVE_INCLUDE_SCHEMA": False, # OTHER SETTINGS "PREPROCESSING_HOOKS": ["documentcloud.core.utils.custom_preprocessing_hook"], + "POSTPROCESSING_HOOKS": [ + "drf_spectacular.hooks.postprocess_schema_enums", + "documentcloud.core.utils.hide_processing_token", + ], } AUTH_PAGE_LIMIT = env.int("AUTH_PAGE_LIMIT", default=1000) diff --git a/documentcloud/core/utils.py b/documentcloud/core/utils.py index cea83e73..01445de5 100644 --- a/documentcloud/core/utils.py +++ b/documentcloud/core/utils.py @@ -14,6 +14,48 @@ from documentcloud.users.stats_api.models import UserStats +class SquareletJWTAuthenticationScheme(OpenApiAuthenticationExtension): + """Simply lets DRF advertise that you can use a JWT from Accounts to auth""" + + target_class = "documentcloud.core.authentication.SquareletJWTAuthentication" + name = "jwtAuth" + + def get_security_definition(self, auto_schema): + return { + "type": "http", + "scheme": "bearer", + "bearerFormat": "JWT", + "description": ( + "JWT bearer token issued by MuckRock Accounts. " + "Obtain a token from https://accounts.muckrock.com/api/token/ " + "and refresh it at https://accounts.muckrock.com/api/refresh/. " + "Access tokens are valid for 5 minutes and " + "refresh tokens are valid for 24 hours" + "Send it as `Authorization: Bearer `." + ), + } + + +def hide_processing_token( + result, generator, request, public +): # pylint:disable=unused-argument + """Since processing token is defined, we need to have it here + but pop it from security schemes as we are the only ones to use this token style + """ + result.get("components", {}).get("securitySchemes", {}).pop( + "ProcessingTokenAuthentication", None + ) + for path_item in result.get("paths", {}).values(): + for operation in path_item.values(): + if isinstance(operation, dict) and "security" in operation: + operation["security"] = [ + scheme + for scheme in operation["security"] + if "ProcessingTokenAuthentication" not in scheme + ] + return result + + class ProcessingTokenAuthenticationScheme(OpenApiAuthenticationExtension): target_class = "documentcloud.core.authentication.ProcessingTokenAuthentication" name = "ProcessingTokenAuthentication"