개선관리 요구사항과 Google 로그인을 완료

This commit is contained in:
Yun Chan 2026-08-28 16:07:09 +09:00
parent cc0a15b7c6
commit 2a39636163
112 changed files with 10166 additions and 527 deletions

View file

@ -221,6 +221,25 @@ def validate_google_identity_domain(
return normalized_email
def validate_google_identity(
*,
email: str | None,
email_verified: bool,
) -> str:
"""Accept every Google account whose email claim is present and verified.
Google has already validated the account before issuing the ID token. The
application deliberately does not impose an email-domain or pre-registration
gate on top of that provider identity.
"""
normalized_email = _normalize_email(email)
if not normalized_email or not _email_domain(normalized_email):
raise HTTPException(status.HTTP_403_FORBIDDEN, detail="email claim is required")
if not email_verified:
raise HTTPException(status.HTTP_403_FORBIDDEN, detail="email is not verified")
return normalized_email
async def validate_login_identity_email(
*,
email: str | None,
@ -774,7 +793,10 @@ async def auth_config(request: Request) -> AuthConfigResponse:
google_oauth_configured=google_ready,
saml_configured=saml_ready,
providers=_auth_provider_statuses(),
allowed_email_domains=sorted(allowed_email_domains()),
# Google OIDC accepts every provider-verified email. Keep the legacy
# setting for dev-login/SAML policy, but do not advertise it as a Google
# restriction to the browser.
allowed_email_domains=[],
redirect_uri=settings.oauth_redirect_uri,
dev_login_enabled=_dev_login_available(request),
)
@ -937,19 +959,18 @@ async def callback(
return _oauth_callback_error("issuer_mismatch", request)
try:
email, managed_user = await validate_login_identity_email(
email = validate_google_identity(
email=claims.get("email"),
email_verified=claims.get("email_verified") in {True, "true", "True", "1", 1},
hosted_domain=claims.get("hd"),
)
except HTTPException:
_log_oauth_callback_failure(
request,
"domain_not_allowed",
"id_token_invalid",
email_domain=_email_domain(str(claims.get("email") or "")),
hosted_domain=_normalize_domain(str(claims.get("hd") or "")),
)
return _oauth_callback_error("domain_not_allowed", request)
return _oauth_callback_error("id_token_invalid", request)
managed_user = await get_managed_user_by_email(email)
role = _role_for_managed_user(managed_user, _role_for_email(email))
display_name = str(claims.get("name") or email)
cohort_ids = _cohort_ids_for_managed_user(
@ -967,6 +988,7 @@ async def callback(
role=role.value,
cohort_ids=cohort_ids,
external_id=external_id,
account_status="approved",
)
except InactiveUserError:
_log_oauth_callback_failure(