Skip to content

Commit 441a96f

Browse files
committed
feat: 개발용 쿠키 설정 엔드포인트 및 헬스 체크 API 추가
1 parent d3c4f17 commit 441a96f

3 files changed

Lines changed: 66 additions & 3 deletions

File tree

app/core/route/dev/set_cookie.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
from contextlib import suppress
2+
from typing import Literal
3+
4+
from django.http import HttpRequest, HttpResponse, HttpResponseBadRequest
5+
from django.views.decorators.csrf import csrf_exempt
6+
from django.views.decorators.http import require_http_methods
7+
8+
_BOOL_TRUE_VALUES = frozenset({"true", "1", "yes", "on"})
9+
_SAME_SITE_VALUES = frozenset({"lax", "strict", "none"})
10+
_RESPONSE_BODY = """\
11+
<!doctype html>
12+
<html>
13+
<head>
14+
<meta charset=utf-8>
15+
<title>Synced</title>
16+
</head>
17+
<body>
18+
<h2>.pycon.kr scope cookie sync complete</h2>
19+
<p>You can close this tab and proceed with the social login.</p>
20+
</body>
21+
</html>"""
22+
23+
24+
def _parse_int(s: str | None) -> int | None:
25+
with suppress(ValueError):
26+
return int(s.strip())
27+
return None
28+
29+
30+
def _parse_bool(s: str | None) -> bool:
31+
return s.strip().lower() in _BOOL_TRUE_VALUES if s else None
32+
33+
34+
def _parse_samesite(s: str | None) -> Literal["Lax", "Strict", "None"] | None:
35+
if not s:
36+
return None
37+
38+
s = s.strip().lower()
39+
return s.capitalize() if s in _SAME_SITE_VALUES else None
40+
41+
42+
@csrf_exempt
43+
@require_http_methods(["POST"])
44+
def dev_set_cookie(request: HttpRequest) -> HttpResponse:
45+
if not (name := request.POST.get("name", "").strip()):
46+
return HttpResponseBadRequest("name required")
47+
if not (value := request.POST.get("value", "").strip()):
48+
return HttpResponseBadRequest("value required")
49+
50+
response = HttpResponse(_RESPONSE_BODY, content_type="text/html; charset=utf-8")
51+
response.set_cookie(
52+
name,
53+
value,
54+
max_age=_parse_int(request.POST.get("max_age")),
55+
domain=request.POST.get("domain", "").strip() or None,
56+
secure=_parse_bool(request.POST.get("secure")),
57+
httponly=_parse_bool(request.POST.get("httponly")),
58+
samesite=_parse_samesite(request.POST.get("samesite")),
59+
)
60+
return response

app/core/urls.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,13 +15,15 @@
1515
2. Add a URL to urlpatterns: path('blog/', include('blog.urls'))
1616
"""
1717

18-
import core.health_check
1918
from django.conf import settings
2019
from django.conf.urls.static import static
2120
from django.contrib import admin
2221
from django.urls import include, path, re_path, resolvers
2322
from drf_spectacular.views import SpectacularAPIView, SpectacularSwaggerView
2423

24+
from app.core.route.dev.set_cookie import dev_set_cookie
25+
from app.core.route.health_check import livez, readyz
26+
2527
# type: ignore[assignment]
2628
v1_apis: list[resolvers.URLPattern | resolvers.URLResolver] = [
2729
path("cms/", include("cms.urls")),
@@ -39,8 +41,8 @@
3941

4042
urlpatterns = [
4143
# Health Check
42-
path("readyz/", core.health_check.readyz),
43-
path("livez/", core.health_check.livez),
44+
path("readyz/", readyz),
45+
path("livez/", livez),
4446
# Admin
4547
path("admin/", admin.site.urls),
4648
# Django-Allauth
@@ -58,4 +60,5 @@
5860
if settings.DEBUG:
5961
urlpatterns += [
6062
path("api/schema/v1/swagger/", SpectacularSwaggerView.as_view(url_name="v1-schema"), name="swagger-v1-ui"),
63+
path("dev/set-cookie/", dev_set_cookie, name="dev-set-cookie"),
6164
]

0 commit comments

Comments
 (0)