diff --git a/basket/news/tests/api/test_lookup_user.py b/basket/news/tests/api/test_lookup_user.py index b2a60826..db790750 100644 --- a/basket/news/tests/api/test_lookup_user.py +++ b/basket/news/tests/api/test_lookup_user.py @@ -61,6 +61,19 @@ def _user_data(self, **kwargs): def valid_request(self): return self.client.get(self.url, {"token": self.token}) + def test_preflight(self): + resp = self.client.options( + self.url, + content_type="application/json", + HTTP_ORIGIN="https://example.com", + HTTP_ACCESS_CONTROL_REQUEST_METHOD="GET", + ) + assert resp.status_code == 200 + assert resp["Access-Control-Allow-Origin"] == "*" + assert "GET" in resp["Access-Control-Allow-Methods"] + for header in ("content-type", "x-api-key", "authorization"): + assert header in resp["Access-Control-Allow-Headers"] + def test_lookup_user_by_email_authorized_qs(self): # Test lookup by email with an authorized API key in the query string. with patch("basket.news.utils.ctms", spec_set=["get"]) as mock_ctms: diff --git a/basket/news/tests/api/test_newsletters.py b/basket/news/tests/api/test_newsletters.py index fdfbaf75..03be25a8 100644 --- a/basket/news/tests/api/test_newsletters.py +++ b/basket/news/tests/api/test_newsletters.py @@ -35,6 +35,18 @@ def _add_newsletter(self, slug, **kwargs): **kwargs, ) + def test_preflight(self): + resp = self.client.options( + self.url, + content_type="application/json", + HTTP_ORIGIN="https://example.com", + HTTP_ACCESS_CONTROL_REQUEST_METHOD="GET", + ) + assert resp.status_code == 200 + assert resp["Access-Control-Allow-Origin"] == "*" + assert "GET" in resp["Access-Control-Allow-Methods"] + assert "content-type" in resp["Access-Control-Allow-Headers"] + def test_newsletters(self): resp = self.client.get(self.url) data = resp.json() diff --git a/basket/news/tests/api/test_users_recover.py b/basket/news/tests/api/test_users_recover.py index 080b507c..eddbf096 100644 --- a/basket/news/tests/api/test_users_recover.py +++ b/basket/news/tests/api/test_users_recover.py @@ -41,6 +41,18 @@ def _user_data(self, **kwargs): data.update(kwargs) return data + def test_preflight(self): + resp = self.client.options( + self.url, + content_type="application/json", + HTTP_ORIGIN="https://example.com", + HTTP_ACCESS_CONTROL_REQUEST_METHOD="POST", + ) + assert resp.status_code == 200 + assert resp["Access-Control-Allow-Origin"] == "*" + assert "POST" in resp["Access-Control-Allow-Methods"] + assert "content-type" in resp["Access-Control-Allow-Headers"] + def test_blocked_email(self): with patch("basket.news.tasks.send_recovery_message.delay", autospec=True) as mock_send: resp = self.client.post(self.url, {"email": "bad@blocked.com"}, content_type="application/json") diff --git a/basket/settings.py b/basket/settings.py index 871582d0..4f536180 100644 --- a/basket/settings.py +++ b/basket/settings.py @@ -10,6 +10,7 @@ import django_cache_url import markus import sentry_sdk +from corsheaders.defaults import default_headers from everett.manager import ChoiceOf, ConfigManager, ConfigurationMissingError, ListOf from sentry_processor import DesensitizationProcessor from sentry_sdk.integrations.django import DjangoIntegration @@ -232,8 +233,9 @@ def path(*args): CTMS_CLIENT_ID = config("CTMS_CLIENT_ID", default="") CTMS_CLIENT_SECRET = config("CTMS_CLIENT_SECRET", default="") -CORS_ORIGIN_ALLOW_ALL = True -CORS_URLS_REGEX = r"^/(news/|subscribe)" +CORS_ALLOW_ALL_ORIGINS = True +CORS_ALLOW_HEADERS = (*default_headers, "x-api-key") +CORS_URLS_REGEX = r"^/(api/|news/|subscribe)" # view rate limiting RATELIMIT_VIEW = "basket.news.views.ratelimited"