diff --git a/relying_party/relying_party/visione_views.py b/relying_party/relying_party/visione_views.py index e704201..1ea4043 100644 --- a/relying_party/relying_party/visione_views.py +++ b/relying_party/relying_party/visione_views.py @@ -1,6 +1,7 @@ import hashlib import hmac import json +import logging import urllib.error import urllib.request from urllib.parse import urlencode @@ -9,6 +10,8 @@ from django.conf import settings from django.http import HttpResponseBadRequest, HttpResponseRedirect, HttpResponseServerError from django.views import View +logger = logging.getLogger(__name__) + class _NoRedirectHandler(urllib.request.HTTPRedirectHandler): def redirect_request(self, req, fp, code, msg, headers, newurl): @@ -24,6 +27,15 @@ def _normalize_fiscal_code(value): return fiscal_code +def _body_preview(raw_body, limit=512): + if not raw_body: + return "" + preview = raw_body[:limit].decode("utf-8", errors="replace").strip() + if len(raw_body) > limit: + return f"{preview}..." + return preview + + class VisioneStartView(View): def get(self, request): state = request.GET.get("state") @@ -95,21 +107,38 @@ class VisioneCompleteView(View): return HttpResponseServerError("Visione backend returned redirect without location") error_body = "" try: - error_body = exc.read().decode("utf-8").strip() + error_body = _body_preview(exc.read()) except Exception: error_body = "" - detail = f" {error_body}" if error_body else "" + detail = f" body={error_body}" if error_body else "" return HttpResponseServerError( f"Visione backend exchange failed: {exc.code}{detail}" ) except Exception as exc: return HttpResponseServerError(f"Visione backend exchange failed: {exc}") + location = response.headers.get("Location") + if location: + return HttpResponseRedirect(location) + try: - payload = response.read().decode("utf-8") + raw_payload = response.read() + payload = raw_payload.decode("utf-8") if raw_payload else "" + content_type = response.headers.get("Content-Type", "") + if payload and "json" not in content_type.lower(): + logger.warning( + "Visione backend exchange returned non-JSON response " + "status=%s content_type=%s body_preview=%s", + getattr(response, "status", None), + content_type, + _body_preview(raw_payload), + ) data = json.loads(payload) if payload else {} except Exception: - return HttpResponseServerError("Visione backend exchange did not redirect") + logger.exception("Visione backend exchange response could not be parsed") + return HttpResponseServerError( + "Visione backend exchange returned invalid JSON" + ) redirect_url = data.get("redirect_url") if redirect_url: