1
+ import logging
1
2
import re
2
3
3
4
from django .conf import settings
@@ -57,6 +58,21 @@ def assertMaskedSecretCorrect(self, masked_secret, secret):
57
58
actual = _unmask_cipher_token (masked_secret )
58
59
self .assertEqual (actual , secret )
59
60
61
+ def assertForbiddenReason (
62
+ self , response , logger_cm , reason , levelno = logging .WARNING
63
+ ):
64
+ self .assertEqual (
65
+ records_len := len (logger_cm .records ),
66
+ 1 ,
67
+ f"Unexpected number of records for { logger_cm = } in { levelno = } (expected 1, "
68
+ f"got { records_len } )." ,
69
+ )
70
+ record = logger_cm .records [0 ]
71
+ self .assertEqual (record .getMessage (), "Forbidden (%s): " % reason )
72
+ self .assertEqual (record .levelno , levelno )
73
+ self .assertEqual (record .status_code , 403 )
74
+ self .assertEqual (response .status_code , 403 )
75
+
60
76
61
77
class CsrfFunctionTests (CsrfFunctionTestMixin , SimpleTestCase ):
62
78
def test_unmask_cipher_token (self ):
@@ -347,8 +363,7 @@ def _check_bad_or_missing_cookie(self, cookie, expected):
347
363
mw .process_request (req )
348
364
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
349
365
resp = mw .process_view (req , post_form_view , (), {})
350
- self .assertEqual (403 , resp .status_code )
351
- self .assertEqual (cm .records [0 ].getMessage (), "Forbidden (%s): " % expected )
366
+ self .assertForbiddenReason (resp , cm , expected )
352
367
353
368
def test_no_csrf_cookie (self ):
354
369
"""
@@ -373,9 +388,8 @@ def _check_bad_or_missing_token(
373
388
mw .process_request (req )
374
389
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
375
390
resp = mw .process_view (req , post_form_view , (), {})
376
- self .assertEqual (403 , resp .status_code )
377
391
self .assertEqual (resp ["Content-Type" ], "text/html; charset=utf-8" )
378
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % expected )
392
+ self .assertForbiddenReason ( resp , cm , expected )
379
393
380
394
def test_csrf_cookie_bad_or_missing_token (self ):
381
395
"""
@@ -480,18 +494,12 @@ def test_put_and_delete_rejected(self):
480
494
mw = CsrfViewMiddleware (post_form_view )
481
495
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
482
496
resp = mw .process_view (req , post_form_view , (), {})
483
- self .assertEqual (403 , resp .status_code )
484
- self .assertEqual (
485
- cm .records [0 ].getMessage (), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
486
- )
497
+ self .assertForbiddenReason (resp , cm , REASON_NO_CSRF_COOKIE )
487
498
488
499
req = self ._get_request (method = "DELETE" )
489
500
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
490
501
resp = mw .process_view (req , post_form_view , (), {})
491
- self .assertEqual (403 , resp .status_code )
492
- self .assertEqual (
493
- cm .records [0 ].getMessage (), "Forbidden (%s): " % REASON_NO_CSRF_COOKIE
494
- )
502
+ self .assertForbiddenReason (resp , cm , REASON_NO_CSRF_COOKIE )
495
503
496
504
def test_put_and_delete_allowed (self ):
497
505
"""
@@ -879,11 +887,7 @@ def test_reading_post_data_raises_unreadable_post_error(self):
879
887
mw .process_request (req )
880
888
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
881
889
resp = mw .process_view (req , post_form_view , (), {})
882
- self .assertEqual (resp .status_code , 403 )
883
- self .assertEqual (
884
- cm .records [0 ].getMessage (),
885
- "Forbidden (%s): " % REASON_CSRF_TOKEN_MISSING ,
886
- )
890
+ self .assertForbiddenReason (resp , cm , REASON_CSRF_TOKEN_MISSING )
887
891
888
892
def test_reading_post_data_raises_os_error (self ):
889
893
"""
@@ -908,9 +912,8 @@ def test_bad_origin_bad_domain(self):
908
912
self .assertIs (mw ._origin_verified (req ), False )
909
913
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
910
914
response = mw .process_view (req , post_form_view , (), {})
911
- self .assertEqual (response .status_code , 403 )
912
915
msg = REASON_BAD_ORIGIN % req .META ["HTTP_ORIGIN" ]
913
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % msg )
916
+ self .assertForbiddenReason ( response , cm , msg )
914
917
915
918
@override_settings (ALLOWED_HOSTS = ["www.example.com" ])
916
919
def test_bad_origin_null_origin (self ):
@@ -923,9 +926,8 @@ def test_bad_origin_null_origin(self):
923
926
self .assertIs (mw ._origin_verified (req ), False )
924
927
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
925
928
response = mw .process_view (req , post_form_view , (), {})
926
- self .assertEqual (response .status_code , 403 )
927
929
msg = REASON_BAD_ORIGIN % req .META ["HTTP_ORIGIN" ]
928
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % msg )
930
+ self .assertForbiddenReason ( response , cm , msg )
929
931
930
932
@override_settings (ALLOWED_HOSTS = ["www.example.com" ])
931
933
def test_bad_origin_bad_protocol (self ):
@@ -939,9 +941,8 @@ def test_bad_origin_bad_protocol(self):
939
941
self .assertIs (mw ._origin_verified (req ), False )
940
942
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
941
943
response = mw .process_view (req , post_form_view , (), {})
942
- self .assertEqual (response .status_code , 403 )
943
944
msg = REASON_BAD_ORIGIN % req .META ["HTTP_ORIGIN" ]
944
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % msg )
945
+ self .assertForbiddenReason ( response , cm , msg )
945
946
946
947
@override_settings (
947
948
ALLOWED_HOSTS = ["www.example.com" ],
@@ -966,9 +967,8 @@ def test_bad_origin_csrf_trusted_origin_bad_protocol(self):
966
967
self .assertIs (mw ._origin_verified (req ), False )
967
968
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
968
969
response = mw .process_view (req , post_form_view , (), {})
969
- self .assertEqual (response .status_code , 403 )
970
970
msg = REASON_BAD_ORIGIN % req .META ["HTTP_ORIGIN" ]
971
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % msg )
971
+ self .assertForbiddenReason ( response , cm , msg )
972
972
self .assertEqual (mw .allowed_origins_exact , {"http://no-match.com" })
973
973
self .assertEqual (
974
974
mw .allowed_origin_subdomains ,
@@ -992,9 +992,8 @@ def test_bad_origin_cannot_be_parsed(self):
992
992
self .assertIs (mw ._origin_verified (req ), False )
993
993
with self .assertLogs ("django.security.csrf" , "WARNING" ) as cm :
994
994
response = mw .process_view (req , post_form_view , (), {})
995
- self .assertEqual (response .status_code , 403 )
996
995
msg = REASON_BAD_ORIGIN % req .META ["HTTP_ORIGIN" ]
997
- self .assertEqual ( cm . records [ 0 ]. getMessage (), "Forbidden (%s): " % msg )
996
+ self .assertForbiddenReason ( response , cm , msg )
998
997
999
998
@override_settings (ALLOWED_HOSTS = ["www.example.com" ])
1000
999
def test_good_origin_insecure (self ):
0 commit comments