From e5f48ebfee23992a5e89960a7227c3d458dc258d Mon Sep 17 00:00:00 2001 From: PR0I Date: Tue, 6 Jan 2026 17:07:25 -0500 Subject: [PATCH] backfilling hotfixes into main --- backend/app/settings.py | 19 +++++++++++-------- backend/app/urls.py | 2 +- backend/npdfhir/serializers.py | 4 ++-- backend/npdfhir/tests/test_basic_views.py | 8 ++++++++ backend/npdfhir/urls.py | 2 +- backend/npdfhir/utils.py | 18 ++++++++---------- backend/npdfhir/views.py | 9 ++++++--- 7 files changed, 37 insertions(+), 25 deletions(-) diff --git a/backend/app/settings.py b/backend/app/settings.py index 4d6c0113..3fa0439b 100644 --- a/backend/app/settings.py +++ b/backend/app/settings.py @@ -92,10 +92,16 @@ CORS_ALLOW_ALL_ORIGINS = True CORS_ALLOWED_METHODS = ["GET"] -CSRF_COOKIE_SECURE = config("DJANGO_CSRF_COOKIE_SECURE", cast=bool, default=False) # Only if using HTTPS -CSRF_COOKIE_HTTPONLY = config("DJANGO_CSRF_COOKIE_HTTPONLY", cast=bool, default=False) # Must be False for JavaScript access +CSRF_COOKIE_SECURE = config( + "DJANGO_CSRF_COOKIE_SECURE", cast=bool, default=False +) # Only if using HTTPS +CSRF_COOKIE_HTTPONLY = config( + "DJANGO_CSRF_COOKIE_HTTPONLY", cast=bool, default=False +) # Must be False for JavaScript access CSRF_COOKIE_SAMESITE = config("DJANGO_CSRF_COOKIE_SAMESITE", default="Lax") # or 'Strict' or 'None' -CSRF_TRUSTED_ORIGINS = config("DJANGO_CSRF_TRUSTED_DOMAINS", default="").split(",") # Add your domains +CSRF_TRUSTED_ORIGINS = config("DJANGO_CSRF_TRUSTED_DOMAINS", default="").split( + "," +) # Add your domains if DEBUG: # in development, allow the frontend app to POST forms to the backend @@ -226,6 +232,7 @@ "rest_framework.authentication.SessionAuthentication", ], "DEFAULT_SCHEMA_CLASS": "drf_spectacular.openapi.AutoSchema", + "DEFAULT_RENDERER_CLASSES": ("rest_framework.renderers.JSONRenderer",), } SPECTACULAR_SETTINGS = { @@ -322,11 +329,7 @@ "handlers": ["console"], "level": LOG_LEVEL, }, - 'django.security.csrf': { - 'handlers': ['console'], - 'level': LOG_LEVEL, - 'propagate': False - }, + "django.security.csrf": {"handlers": ["console"], "level": LOG_LEVEL, "propagate": False}, }, } diff --git a/backend/app/urls.py b/backend/app/urls.py index 951bd7ea..b176207e 100644 --- a/backend/app/urls.py +++ b/backend/app/urls.py @@ -48,7 +48,7 @@ # See app/tests/test_routing.py for validation tests to ensure that changes # inside npdfhir.urls don't break our routing configuration. path("fhir/", include("npdfhir.urls")), - path("fhir", npdfhir_router.get_api_root_view, name="api-root"), + path("fhir", npdfhir_router.get_api_root_view(), name="api-root"), path("admin/", admin.site.urls), # everything else goes to provider_directory path("", include("provider_directory.urls")), diff --git a/backend/npdfhir/serializers.py b/backend/npdfhir/serializers.py index 9affe6d9..d8e6d028 100644 --- a/backend/npdfhir/serializers.py +++ b/backend/npdfhir/serializers.py @@ -613,11 +613,11 @@ class CapabilityStatementSerializer(serializers.Serializer): Serializer for FHIR CapablityStatement resource """ - def to_representation(self, instance): + def to_representation(self): request = self.context.get("request") baseURL = request.build_absolute_uri("/fhir") metadataURL = request.build_absolute_uri(reverse("fhir-metadata")) - schemaData = get_schema_data(request, "schema") + schemaData = get_schema_data(request) capability_statement = CapabilityStatement( url=metadataURL, diff --git a/backend/npdfhir/tests/test_basic_views.py b/backend/npdfhir/tests/test_basic_views.py index cc3d949f..015eedb5 100644 --- a/backend/npdfhir/tests/test_basic_views.py +++ b/backend/npdfhir/tests/test_basic_views.py @@ -11,3 +11,11 @@ def test_health_view(self): res_obj = response.json() self.assertEqual(response.status_code, status.HTTP_200_OK) self.assertEqual(res_obj["status"], "healthy") + + def test_fhir_endpoint_list_without_slash(self): + response = self.client.get("/fhir") + self.assertEqual(response.status_code, status.HTTP_200_OK) + + def test_fhir_endpoint_list_with_slash(self): + response = self.client.get("/fhir/") + self.assertEqual(response.status_code, status.HTTP_200_OK) diff --git a/backend/npdfhir/urls.py b/backend/npdfhir/urls.py index 5c7b0b76..4ffb33c8 100644 --- a/backend/npdfhir/urls.py +++ b/backend/npdfhir/urls.py @@ -14,7 +14,7 @@ re_path("docs/redoc/?", SpectacularRedocView.as_view(url_name="schema"), name="schema-redoc"), re_path("docs/?", SpectacularSwaggerView.as_view(url_name="schema"), name="schema-swagger-ui"), path("healthCheck", views.health, name="healthCheck"), - path("metadata", views.FHIRCapabilityStatementView.as_view(), name="fhir-metadata"), + path("metadata/?", views.FHIRCapabilityStatementView.as_view(), name="fhir-metadata"), # Router URLs # everything else is passed to the rest_framework router to manage path("", include(router.urls), name="index"), diff --git a/backend/npdfhir/utils.py b/backend/npdfhir/utils.py index 3c5882a0..f6d62f90 100644 --- a/backend/npdfhir/utils.py +++ b/backend/npdfhir/utils.py @@ -1,7 +1,7 @@ from django.urls import reverse from fhir.resources.R4B.address import Address from fhir.resources.R4B.reference import Reference -from rest_framework.test import APIClient +from drf_spectacular.views import SpectacularJSONAPIView def SmartyStreetstoFHIR(address): @@ -17,15 +17,13 @@ def SmartyStreetstoFHIR(address): ) -def get_schema_data(request, url_name, additional_args=None): - client = APIClient() - if request.user: - # reuse the authenticated user from the active request to make the - # internal request to retrieve the current schema - client.force_authenticate(user=request.user) - schema_url = reverse(url_name, kwargs=additional_args) - response = client.get(schema_url) - return response.data +def get_schema_data(request): + schema_view = SpectacularJSONAPIView.as_view() + response = schema_view(request._request) + # The response contains the schema data in its .data attribute + schema_data = response.data + + return schema_data def genReference(url_name, identifier, request): diff --git a/backend/npdfhir/views.py b/backend/npdfhir/views.py index 161f88ec..c25d72fd 100644 --- a/backend/npdfhir/views.py +++ b/backend/npdfhir/views.py @@ -552,7 +552,10 @@ def get(self, request): """ Query metadata about this FHIR instance, represented as FHIR CapabilityStatement resource """ - serializer = CapabilityStatementSerializer(context={"request": request}) - response = serializer.to_representation(None) + serialized_capability_statement = CapabilityStatementSerializer( + context={"request": request} + ) + + response = Response(serialized_capability_statement.to_representation()) - return Response(response) + return response