OAuth 관리자 진입 경로 정규화

This commit is contained in:
Yun Chan 2026-07-03 19:46:05 +09:00
parent f41066e3e8
commit 998acb44b0
3 changed files with 205 additions and 2 deletions

View file

@ -58,6 +58,7 @@ GOOGLE_TOKENINFO_URL = "https://oauth2.googleapis.com/tokeninfo"
OAUTH_STATE_TTL_SECONDS = 10 * 60
OAUTH_STATE_COOKIE_NAME = "__Host-vignette_oauth_state"
DEV_OAUTH_STATE_COOKIE_NAME = "vignette_oauth_state"
GENERIC_ADMIN_ENTRY_PATHS = {"/", "/learn", "/teach", "/login", "/onboarding"}
@dataclass(slots=True)
@ -343,6 +344,29 @@ def _safe_next_path(next_path: str | None) -> str:
return next_path
def _is_generic_admin_entry_path(next_path: str) -> bool:
path = urlsplit(_safe_next_path(next_path)).path.rstrip("/") or "/"
return path in GENERIC_ADMIN_ENTRY_PATHS
def _post_login_next_path(
next_path: str,
*,
email: str,
role: Role,
managed_user: ManagedUser | None,
) -> str:
safe_next = _safe_next_path(next_path)
stored_admin_access = managed_user.admin_access if managed_user is not None else False
if _is_generic_admin_entry_path(safe_next) and has_admin_access(
email,
role.value,
stored_admin_access,
):
return "/admin"
return safe_next
def _url_origin(value: str | None) -> str | None:
if not value:
return None
@ -951,7 +975,13 @@ async def callback(
)
return _oauth_callback_error("inactive_user", request)
response = RedirectResponse(_frontend_url(stored.next_path, request), status_code=302)
next_path = _post_login_next_path(
stored.next_path,
email=email,
role=role,
managed_user=managed_user,
)
response = RedirectResponse(_frontend_url(next_path, request), status_code=302)
_set_session_cookie(response, sid)
_delete_oauth_state_cookie(response)
return response
@ -1010,7 +1040,13 @@ async def saml_acs(request: Request) -> RedirectResponse:
except InactiveUserError:
return _frontend_login_redirect("inactive_user", request)
response = RedirectResponse(_frontend_url(stored.next_path, request), status_code=302)
next_path = _post_login_next_path(
stored.next_path,
email=email,
role=role,
managed_user=managed_user,
)
response = RedirectResponse(_frontend_url(next_path, request), status_code=302)
_set_session_cookie(response, sid)
return response