mirror of
https://github.com/inventree/InvenTree.git
synced 2026-09-09 22:30:17 +00:00
Enhanced error message on CSRF failure (#12788)
* Enhanced error message on CSRF failure * Defer to 'detail' field if exists
This commit is contained in:
@@ -113,7 +113,9 @@ def csrf_failure(request, reason=''):
|
||||
"""Custom CSRF failure handler.
|
||||
|
||||
Returns a JSON response for API/headless requests so the frontend can
|
||||
provide a meaningful error message to the user
|
||||
provide a meaningful error message to the user.
|
||||
|
||||
This Includes Django's own message (e.g. "CSRF cookie not set.") alongside the generic hint.
|
||||
"""
|
||||
from django.views.csrf import csrf_failure as django_default
|
||||
|
||||
@@ -123,15 +125,15 @@ def csrf_failure(request, reason=''):
|
||||
or 'application/json' in request.headers.get('Accept', '')
|
||||
or 'application/json' in request.headers.get('Content-Type', '')
|
||||
):
|
||||
return JsonResponse(
|
||||
{
|
||||
'detail': _(
|
||||
'CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly.'
|
||||
)
|
||||
},
|
||||
status=403,
|
||||
detail = _(
|
||||
'CSRF verification failed. Ensure INVENTREE_SITE_URL and INVENTREE_TRUSTED_ORIGINS are configured correctly.'
|
||||
)
|
||||
|
||||
if reason:
|
||||
detail = f'{detail} ({reason})'
|
||||
|
||||
return JsonResponse({'detail': detail}, status=403)
|
||||
|
||||
return django_default(request, reason=reason)
|
||||
|
||||
|
||||
|
||||
@@ -310,7 +310,7 @@ class MiddlewareTests(InvenTreeTestCase):
|
||||
request.META[f'HTTP_{key.upper().replace("-", "_")}'] = value
|
||||
return request
|
||||
|
||||
# API path -> JSON 403 with meaningful message
|
||||
# API path -> JSON 403 with meaningful message, plus Django's own reason
|
||||
response = csrf_failure(
|
||||
make_request('/api/part/'), reason='origin check failed'
|
||||
)
|
||||
@@ -318,9 +318,9 @@ class MiddlewareTests(InvenTreeTestCase):
|
||||
import json
|
||||
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data['detail'], EXPECTED_DETAIL)
|
||||
self.assertEqual(data['detail'], f'{EXPECTED_DETAIL} (origin check failed)')
|
||||
|
||||
# allauth headless path -> JSON 403
|
||||
# allauth headless path -> JSON 403 (no reason supplied -> generic message only)
|
||||
response = csrf_failure(make_request('/_allauth/browser/v1/auth/login'))
|
||||
self.assertEqual(response.status_code, 403)
|
||||
data = json.loads(response.content)
|
||||
@@ -333,16 +333,16 @@ class MiddlewareTests(InvenTreeTestCase):
|
||||
)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data['detail'], EXPECTED_DETAIL)
|
||||
self.assertEqual(data['detail'], f'{EXPECTED_DETAIL} (origin check failed)')
|
||||
|
||||
# Content-Type: application/json header -> JSON 403
|
||||
response = csrf_failure(
|
||||
make_request('/some/other/path/', {'Content-Type': 'application/json'}),
|
||||
reason='origin check failed',
|
||||
reason='CSRF cookie not set.',
|
||||
)
|
||||
self.assertEqual(response.status_code, 403)
|
||||
data = json.loads(response.content)
|
||||
self.assertEqual(data['detail'], EXPECTED_DETAIL)
|
||||
self.assertEqual(data['detail'], f'{EXPECTED_DETAIL} (CSRF cookie not set.)')
|
||||
|
||||
# Plain browser request -> falls back to Django default CSRF page (403 HTML, not JSON)
|
||||
response = csrf_failure(make_request('/web/'), reason='origin check failed')
|
||||
|
||||
@@ -20,7 +20,10 @@ export function extractErrorMessage({
|
||||
let message = '';
|
||||
|
||||
if (error_data) {
|
||||
message = error_data[field ?? 'error'] ?? error_data['non_field_errors'];
|
||||
message =
|
||||
error_data[field ?? 'error'] ??
|
||||
error_data['detail'] ??
|
||||
error_data['non_field_errors'];
|
||||
}
|
||||
|
||||
// No message? Look at the response status codes
|
||||
|
||||
Reference in New Issue
Block a user