|
3 | 3 | import logging |
4 | 4 | import os.path |
5 | 5 | from pathlib import Path |
| 6 | +import re |
6 | 7 | from typing import Any, Dict, List, Optional, Tuple |
7 | 8 |
|
8 | 9 | from aplus_auth.auth.django import Request |
|
28 | 29 |
|
29 | 30 |
|
30 | 31 | logger = logging.getLogger("access.views") |
| 32 | +LOCAL_DEV_ORIGIN_RE = re.compile(r"^https?://(localhost|127\.0\.0\.1)(:\d+)?$") |
31 | 33 |
|
32 | 34 |
|
33 | 35 | @login_required |
@@ -346,19 +348,33 @@ def publish( |
346 | 348 |
|
347 | 349 |
|
348 | 350 | class LoginView(View): |
| 351 | + @staticmethod |
| 352 | + def _add_cors_headers(request: HttpRequest, response: HttpResponse) -> HttpResponse: |
| 353 | + origin = request.headers.get("Origin") |
| 354 | + if origin and settings.DEBUG and LOCAL_DEV_ORIGIN_RE.match(origin): |
| 355 | + response["Access-Control-Allow-Origin"] = origin |
| 356 | + response["Access-Control-Allow-Credentials"] = "true" |
| 357 | + response["Access-Control-Allow-Headers"] = "Authorization, Content-Type" |
| 358 | + response["Access-Control-Allow-Methods"] = "GET, POST, OPTIONS" |
| 359 | + response.setdefault("Vary", "Origin") |
| 360 | + return response |
| 361 | + |
| 362 | + def options(self, request: HttpRequest, *args: Any, **kwargs: Any) -> HttpResponse: |
| 363 | + return self._add_cors_headers(request, HttpResponse(status=204)) |
| 364 | + |
349 | 365 | def get(self, request): |
350 | 366 | response = render(request, 'access/login.html') |
351 | 367 | response.delete_cookie("AuthToken") |
352 | | - return response |
| 368 | + return self._add_cors_headers(request, response) |
353 | 369 |
|
354 | 370 | def post(self, request): |
355 | 371 | if not hasattr(request, "user") or not request.user.is_authenticated: |
356 | | - return HttpResponse("Invalid token", status=401) |
| 372 | + return self._add_cors_headers(request, HttpResponse("Invalid token", status=401)) |
357 | 373 | else: |
358 | 374 | response = HttpResponse() |
359 | 375 | # secure=not settings.DEBUG so that we do not need https when developing |
360 | 376 | response.set_cookie("AuthToken", str(request.auth), secure=not settings.DEBUG, httponly=True) |
361 | | - return response |
| 377 | + return self._add_cors_headers(request, response) |
362 | 378 |
|
363 | 379 |
|
364 | 380 | def _get_course_exercise_lang( |
|
0 commit comments