File indexing completed on 2026-09-28 09:37:30
0001
0002 """Focused browser CSRF/header checks using synthetic requests, without DB writes."""
0003 import json
0004 import os
0005 from pathlib import Path
0006 import sys
0007 from types import SimpleNamespace
0008 import unittest
0009 sys.path.insert(0,str(Path(__file__).resolve().parents[1]/'src'))
0010 os.environ.setdefault('DJANGO_SETTINGS_MODULE','swf_remote_project.settings')
0011 import django
0012 django.setup()
0013 from django.conf import settings
0014 from django.http import HttpResponse
0015 from django.middleware.csrf import CsrfViewMiddleware
0016 from django.test import RequestFactory, override_settings, SimpleTestCase
0017 from remote_app.teamcomms import browser_csrf, _authenticated_request, _response_headers, proxy
0018
0019 @override_settings(ALLOWED_HOSTS=['epic-devcloud.org'], CSRF_TRUSTED_ORIGINS=['https://epic-devcloud.org'])
0020 class BrowserChecks(SimpleTestCase):
0021 def request(self, method='get', **headers):
0022 r=getattr(RequestFactory(),method)('/prod/teamcomms/browser-csrf',secure=True,HTTP_HOST='epic-devcloud.org',**headers)
0023 r.user=SimpleNamespace(is_authenticated=True,is_active=True)
0024 return r
0025 def test_masked_token_sets_host_cookie_and_protects_posts(self):
0026 middleware=CsrfViewMiddleware(lambda r:HttpResponse())
0027 request=self.request();middleware.process_request(request)
0028 response=middleware.process_response(request,browser_csrf(request))
0029 body=json.loads(response.content)
0030 self.assertEqual(body['header_name'],'X-CSRFToken')
0031 self.assertEqual(len(body['token']),64)
0032 self.assertEqual(response['Cache-Control'],'no-store')
0033 self.assertIn(settings.CSRF_COOKIE_NAME,response.cookies)
0034 secret=response.cookies[settings.CSRF_COOKIE_NAME].value
0035 for token,expected in ((body['token'],None),('',403)):
0036 post=self.request('post',HTTP_X_CSRFTOKEN=token,HTTP_ORIGIN='https://epic-devcloud.org')
0037 post.COOKIES[settings.CSRF_COOKIE_NAME]=secret;middleware.process_request(post)
0038 _,rejection=_authenticated_request(post)
0039 self.assertEqual(rejection.status_code if rejection else None,expected)
0040 def test_endpoint_needs_session_and_get(self):
0041 request=self.request();request.user.is_authenticated=False
0042 self.assertEqual(browser_csrf(request).status_code,401)
0043 self.assertEqual(browser_csrf(self.request(HTTP_AUTHORIZATION='Bearer synthetic')).status_code,401)
0044 self.assertEqual(browser_csrf(self.request('post')).status_code,405)
0045 def test_proxy_preserves_security_headers_and_login_redirect(self):
0046 upstream=SimpleNamespace(headers={'Content-Security-Policy':"default-src 'self'",'X-Content-Type-Options':'nosniff','Referrer-Policy':'same-origin','Set-Cookie':'untrusted=1'})
0047 response=_response_headers(upstream,HttpResponse())
0048 self.assertEqual(response['X-Content-Type-Options'],'nosniff')
0049 self.assertNotIn('Set-Cookie',response)
0050 request=self.request(HTTP_ACCEPT='text/html');request.user.is_authenticated=False
0051 with override_settings(SWF_TEAMCOMMS_SERVICE_TOKEN='fixture-only'):
0052 result=proxy(request,subpath='entries')
0053 self.assertEqual(result.status_code,302)
0054 self.assertIn('next=',result['Location'])
0055 if __name__=='__main__':unittest.main()