This commit is contained in:
2024-11-20 00:28:22 +01:00
parent 610d703566
commit aa99075a6b
12 changed files with 197 additions and 72 deletions

View File

@@ -0,0 +1,5 @@
from pydantic import BaseModel
class GetAuthorizationUrlResponse(BaseModel):
authorization_url: str

View File

@@ -0,0 +1,18 @@
from core.config import config
from domain.auth import OAuthProvider
from .providers import get_client
REDIRECT_URI_TEMPLATE = f"https://{config.WEB_APP_HOST}/" + "auth/callback/{service}/"
async def get_authorization_url(provider: OAuthProvider) -> str:
client = get_client(provider)
return await client.get_authorization_url(
redirect_uri=REDIRECT_URI_TEMPLATE.format(
service=provider.value
),
)

View File

@@ -0,0 +1,16 @@
from domain.auth import OAuthProvider
from .providers import get_client
from .authorization_url_getter import REDIRECT_URI_TEMPLATE
async def process_callback(provider: OAuthProvider, code: str) -> tuple[str, str | None]:
client = get_client(provider)
token = await client.get_access_token(
code,
redirect_uri=REDIRECT_URI_TEMPLATE.format(service=provider.value),
)
user_data = await client.get_id_email(token["access_token"])
return user_data

View File

@@ -0,0 +1,10 @@
from .enums import OAuthProvider
from .twitch import twitch_oauth_client
from .getter import get_client
__all__ = [
"OAuthProvider",
"twitch_oauth_client",
"get_client"
]

View File

@@ -0,0 +1,11 @@
from httpx_oauth.oauth2 import OAuth2
from domain.auth import OAuthProvider
from .twitch import twitch_oauth_client
def get_client(provider: OAuthProvider) -> OAuth2:
if provider == OAuthProvider.TWITCH:
return twitch_oauth_client
else:
raise NotImplementedError("Provider is not implemented")

View File

@@ -0,0 +1,34 @@
from twitchAPI.twitch import Twitch, AuthScope
from twitchAPI.helper import first
from httpx_oauth.oauth2 import OAuth2
from core.config import config
class TwithOAuth2(OAuth2):
async def get_id_email(self, token: str):
twitch_client = Twitch(config.TWITCH_CLIENT_ID, config.TWITCH_CLIENT_SECRET)
twitch_client.auto_refresh_auth = False
await twitch_client.set_user_authentication(
token,
[AuthScope.USER_READ_EMAIL],
validate=True
)
me = await first(twitch_client.get_users())
if me is None:
raise Exception("Failed to get user data")
return me.id, me.email
twitch_oauth_client = TwithOAuth2(
config.TWITCH_CLIENT_ID,
config.TWITCH_CLIENT_SECRET,
"https://id.twitch.tv/oauth2/authorize",
"https://id.twitch.tv/oauth2/token",
base_scopes=[AuthScope.USER_READ_EMAIL.value],
)

View File

@@ -1,68 +1,32 @@
from fastapi import APIRouter
from twitchAPI.twitch import Twitch, AuthScope
from twitchAPI.helper import first
from httpx_oauth.oauth2 import OAuth2
from core.config import config
from domain.auth import OAuthProvider, OAuthData
from domain.users import CreateUser
from modules.web_app.services.oauth.process_callback import process_callback
from modules.web_app.services.oauth.authorization_url_getter import get_authorization_url as gen_auth_link
from modules.web_app.serializers.auth import GetAuthorizationUrlResponse
from repositories.users import UserRepository
auth_router = APIRouter(prefix="/auth", tags=["auth"])
class TwithOAuth2(OAuth2):
async def get_id_email(self, token: str):
twitch_client = Twitch(config.TWITCH_CLIENT_ID, config.TWITCH_CLIENT_SECRET)
twitch_client.auto_refresh_auth = False
@auth_router.get("/get_authorization_url/{provider}/")
async def get_authorization_url(provider: OAuthProvider) -> GetAuthorizationUrlResponse:
link = await gen_auth_link(provider)
await twitch_client.set_user_authentication(
token,
[AuthScope.USER_READ_EMAIL],
validate=True
return GetAuthorizationUrlResponse(authorization_url=link)
@auth_router.get("/callback/{provider}/")
async def callback(provider: OAuthProvider, code: str):
user_data = await process_callback(provider, code)
user = await UserRepository.get_or_create_user(
CreateUser(
oauths={provider: OAuthData(id=user_data[0], email=user_data[1])},
is_admin=False,
)
)
me = await first(twitch_client.get_users())
if me is None:
raise Exception("Failed to get user data")
return me.id, me.email
twitch_oauth = TwithOAuth2(
config.TWITCH_CLIENT_ID,
config.TWITCH_CLIENT_SECRET,
"https://id.twitch.tv/oauth2/authorize",
"https://id.twitch.tv/oauth2/token",
base_scopes=[AuthScope.USER_READ_EMAIL.value],
)
REDIRECT_URI_TEMPLATE = f"https://{config.WEB_APP_HOST}/" + "auth/callback/{service}/"
@auth_router.get("/get_authorization_url/{service}/")
async def get_authorization_url(service: str):
link = None
if service == "twitch":
link = await twitch_oauth.get_authorization_url(
redirect_uri=REDIRECT_URI_TEMPLATE.format(service="twitch"),
)
return {"link": link}
@auth_router.get("/callback/{service}/")
async def callback(service: str, code: str):
user_data = None
if service == "twitch":
token = await twitch_oauth.get_access_token(
code,
redirect_uri=REDIRECT_URI_TEMPLATE.format(service="twitch"),
)
user_data = await twitch_oauth.get_id_email(token["access_token"])
return {"user_data": user_data}
return {"user": user.model_dump()}