from __future__ import annotations from dataclasses import dataclass from app.communication.external.http_client import get_http_client from app.core.config import settings @dataclass class OAuthUserInfo: provider: str provider_user_id: str email: str name: str async def get_google_user_info(code: str, redirect_uri: str) -> OAuthUserInfo: client = await get_http_client() token_resp = await client.post( "https://oauth2.googleapis.com/token", data={ "code": code, "client_id": settings.GOOGLE_CLIENT_ID, "client_secret": settings.GOOGLE_CLIENT_SECRET, "redirect_uri": redirect_uri, "grant_type": "authorization_code", }, ) token_resp.raise_for_status() access_token = token_resp.json()["access_token"] user_resp = await client.get( "https://www.googleapis.com/oauth2/v2/userinfo", headers={"Authorization": f"Bearer {access_token}"}, ) user_resp.raise_for_status() data = user_resp.json() return OAuthUserInfo( provider="google", provider_user_id=data["id"], email=data["email"], name=data.get("name", ""), ) async def get_kakao_user_info(code: str, redirect_uri: str) -> OAuthUserInfo: client = await get_http_client() token_resp = await client.post( "https://kauth.kakao.com/oauth/token", data={ "grant_type": "authorization_code", "client_id": settings.KAKAO_CLIENT_ID, "client_secret": settings.KAKAO_CLIENT_SECRET, "redirect_uri": redirect_uri, "code": code, }, ) token_resp.raise_for_status() access_token = token_resp.json()["access_token"] user_resp = await client.get( "https://kapi.kakao.com/v2/user/me", headers={"Authorization": f"Bearer {access_token}"}, ) user_resp.raise_for_status() data = user_resp.json() account = data.get("kakao_account", {}) return OAuthUserInfo( provider="kakao", provider_user_id=str(data["id"]), email=account.get("email", ""), name=account.get("profile", {}).get("nickname", ""), ) async def get_naver_user_info(code: str, redirect_uri: str) -> OAuthUserInfo: client = await get_http_client() token_resp = await client.post( "https://nid.naver.com/oauth2.0/token", data={ "grant_type": "authorization_code", "client_id": settings.NAVER_CLIENT_ID, "client_secret": settings.NAVER_CLIENT_SECRET, "code": code, }, ) token_resp.raise_for_status() access_token = token_resp.json()["access_token"] user_resp = await client.get( "https://openapi.naver.com/v1/nid/me", headers={"Authorization": f"Bearer {access_token}"}, ) user_resp.raise_for_status() data = user_resp.json()["response"] return OAuthUserInfo( provider="naver", provider_user_id=data["id"], email=data.get("email", ""), name=data.get("name", ""), ) OAUTH_PROVIDERS = { "google": get_google_user_info, "kakao": get_kakao_user_info, "naver": get_naver_user_info, }