|
1 | 1 | import django_dynamic_fixture as fixture
|
| 2 | +from corsheaders.middleware import ( |
| 3 | + ACCESS_CONTROL_ALLOW_CREDENTIALS, |
| 4 | + ACCESS_CONTROL_ALLOW_METHODS, |
| 5 | + ACCESS_CONTROL_ALLOW_ORIGIN, |
| 6 | +) |
2 | 7 | from django.test import override_settings
|
3 | 8 | from django.urls import reverse
|
| 9 | +from django_dynamic_fixture import get |
4 | 10 |
|
5 |
| -from readthedocs.builds.constants import LATEST |
| 11 | +from readthedocs.builds.constants import EXTERNAL, LATEST |
| 12 | +from readthedocs.builds.models import Version |
| 13 | +from readthedocs.organizations.models import Organization |
6 | 14 | from readthedocs.projects.constants import PRIVATE, PUBLIC
|
7 | 15 | from readthedocs.projects.models import Domain, HTTPHeader
|
8 | 16 |
|
|
12 | 20 | @override_settings(
|
13 | 21 | PUBLIC_DOMAIN="dev.readthedocs.io",
|
14 | 22 | PUBLIC_DOMAIN_USES_HTTPS=True,
|
| 23 | + RTD_EXTERNAL_VERSION_DOMAIN="dev.readthedocs.build", |
15 | 24 | )
|
16 | 25 | class ProxitoHeaderTests(BaseDocServing):
|
17 | 26 | def test_redirect_headers(self):
|
@@ -159,29 +168,97 @@ def test_hosting_integrations_header(self):
|
159 | 168 | self.assertIsNotNone(r.get("X-RTD-Hosting-Integrations"))
|
160 | 169 | self.assertEqual(r["X-RTD-Hosting-Integrations"], "true")
|
161 | 170 |
|
| 171 | + @override_settings(ALLOW_PRIVATE_REPOS=False) |
| 172 | + def test_cors_headers_external_version(self): |
| 173 | + get( |
| 174 | + Version, |
| 175 | + project=self.project, |
| 176 | + slug="111", |
| 177 | + active=True, |
| 178 | + privacy_level=PUBLIC, |
| 179 | + type=EXTERNAL, |
| 180 | + ) |
| 181 | + |
| 182 | + # Normal request |
| 183 | + r = self.client.get( |
| 184 | + "/en/111/", |
| 185 | + secure=True, |
| 186 | + headers={"host": "project--111.dev.readthedocs.build"}, |
| 187 | + ) |
| 188 | + self.assertEqual(r.status_code, 200) |
| 189 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") |
| 190 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) |
| 191 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") |
| 192 | + |
| 193 | + # Cross-origin request |
| 194 | + r = self.client.get( |
| 195 | + "/en/111/", |
| 196 | + secure=True, |
| 197 | + headers={ |
| 198 | + "host": "project--111.dev.readthedocs.build", |
| 199 | + "origin": "https://example.com", |
| 200 | + }, |
| 201 | + ) |
| 202 | + self.assertEqual(r.status_code, 200) |
| 203 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") |
| 204 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) |
| 205 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") |
| 206 | + |
| 207 | + @override_settings(ALLOW_PRIVATE_REPOS=True, RTD_ALLOW_ORGANIZATIONS=True) |
162 | 208 | def test_cors_headers_private_version(self):
|
163 |
| - version = self.project.versions.get(slug=LATEST) |
164 |
| - version.privacy_level = PRIVATE |
165 |
| - version.save() |
| 209 | + get(Organization, owners=[self.eric], projects=[self.project]) |
| 210 | + self.version.privacy_level = PRIVATE |
| 211 | + self.version.save() |
| 212 | + |
| 213 | + self.client.force_login(self.eric) |
166 | 214 |
|
| 215 | + # Normal request |
167 | 216 | r = self.client.get(
|
168 |
| - "/en/latest/", secure=True, headers={"host": "project.dev.readthedocs.io"} |
| 217 | + "/en/latest/", |
| 218 | + secure=True, |
| 219 | + headers={"host": "project.dev.readthedocs.io"}, |
169 | 220 | )
|
170 | 221 | self.assertEqual(r.status_code, 200)
|
171 |
| - self.assertIsNone(r.get("Access-Control-Allow-Origin")) |
172 |
| - self.assertIsNone(r.get("Access-Control-Allow-Methods")) |
| 222 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, r.headers) |
173 | 223 |
|
| 224 | + # Cross-origin request |
| 225 | + r = self.client.get( |
| 226 | + "/en/latest/", |
| 227 | + secure=True, |
| 228 | + headers={ |
| 229 | + "host": "project.dev.readthedocs.io", |
| 230 | + "origin": "https://example.com", |
| 231 | + }, |
| 232 | + ) |
| 233 | + self.assertEqual(r.status_code, 200) |
| 234 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_ORIGIN, r.headers) |
| 235 | + |
| 236 | + @override_settings(ALLOW_PRIVATE_REPOS=False) |
174 | 237 | def test_cors_headers_public_version(self):
|
175 |
| - version = self.project.versions.get(slug=LATEST) |
176 |
| - version.privacy_level = PUBLIC |
177 |
| - version.save() |
| 238 | + # Normal request |
| 239 | + r = self.client.get( |
| 240 | + "/en/latest/", |
| 241 | + secure=True, |
| 242 | + headers={"host": "project.dev.readthedocs.io"}, |
| 243 | + ) |
| 244 | + self.assertEqual(r.status_code, 200) |
| 245 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") |
| 246 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) |
| 247 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") |
178 | 248 |
|
| 249 | + # Cross-origin request |
179 | 250 | r = self.client.get(
|
180 |
| - "/en/latest/", secure=True, headers={"host": "project.dev.readthedocs.io"} |
| 251 | + "/en/latest/", |
| 252 | + secure=True, |
| 253 | + headers={ |
| 254 | + "host": "project.dev.readthedocs.io", |
| 255 | + "origin": "https://example.com", |
| 256 | + }, |
181 | 257 | )
|
182 | 258 | self.assertEqual(r.status_code, 200)
|
183 |
| - self.assertEqual(r["Access-Control-Allow-Origin"], "*.readthedocs.build") |
184 |
| - self.assertEqual(r["Access-Control-Allow-Methods"], "OPTIONS, GET") |
| 259 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_ORIGIN], "*") |
| 260 | + self.assertNotIn(ACCESS_CONTROL_ALLOW_CREDENTIALS, r.headers) |
| 261 | + self.assertEqual(r[ACCESS_CONTROL_ALLOW_METHODS], "HEAD, OPTIONS, GET") |
185 | 262 |
|
186 | 263 | @override_settings(ALLOW_PRIVATE_REPOS=False)
|
187 | 264 | def test_cache_headers_public_version_with_private_projects_not_allowed(self):
|
|
0 commit comments