From ae4791c1fcbf229678e3eb5403cacd2b74730d75 Mon Sep 17 00:00:00 2001 From: Santos Gallegos Date: Thu, 21 Sep 2023 15:56:19 -0500 Subject: [PATCH] Proxyto: Allow CORS on commercial on public docs pages (#10762) Allow CORS on commercial After testing this more thoroughly, allowing cross-origin requests on commercial should be safe for documentation pages. Using `*` doesn't allow credentials, and we are also not allowing cross-origin requests for private versions. Basically we have a double protection :D. --- readthedocs/proxito/middleware.py | 6 ----- readthedocs/proxito/tests/test_headers.py | 31 +++++++++++++++++++++++ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/readthedocs/proxito/middleware.py b/readthedocs/proxito/middleware.py index e65bb1dd801..450c280e1e1 100644 --- a/readthedocs/proxito/middleware.py +++ b/readthedocs/proxito/middleware.py @@ -328,12 +328,6 @@ def add_cors_headers(self, request, response): See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin. """ - - # Disable CORS on "Read the Docs for Business" for now. - # We want to be pretty sure this logic is OK before enabling it there. - if settings.ALLOW_PRIVATE_REPOS: - return - # TODO: se should add these headers to files from docs only, # proxied APIs and other endpoints should not have CORS headers. # These attributes aren't currently set for proxied APIs, but we shuold diff --git a/readthedocs/proxito/tests/test_headers.py b/readthedocs/proxito/tests/test_headers.py index df993a445f6..ec0465fac83 100644 --- a/readthedocs/proxito/tests/test_headers.py +++ b/readthedocs/proxito/tests/test_headers.py @@ -260,6 +260,37 @@ def test_cors_headers_public_version(self): self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") + @override_settings(ALLOW_PRIVATE_REPOS=True, RTD_ALLOW_ORGANIZATIONS=True) + def test_cors_headers_public_version_with_organizations(self): + get(Organization, owners=[self.eric], projects=[self.project]) + + self.client.force_login(self.eric) + + # Normal request + r = self.client.get( + "/en/latest/", + secure=True, + headers={"host": "project.dev.readthedocs.io"}, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") + + # Cross-origin request + r = self.client.get( + "/en/latest/", + secure=True, + headers={ + "host": "project.dev.readthedocs.io", + "origin": "https://example.com", + }, + ) + self.assertEqual(r.status_code, 200) + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") + @override_settings(ALLOW_PRIVATE_REPOS=False) def test_cache_headers_public_version_with_private_projects_not_allowed(self): r = self.client.get(