diff --git a/Dockerfile b/Dockerfile index 065469e..7e0d612 100644 --- a/Dockerfile +++ b/Dockerfile @@ -7,7 +7,7 @@ ENV IMAGE_DIRECTORY=/data/images ENV TV_SHOW_DIRECTORY=/data/tv ENV MOVIE_DIRECTORY=/data/movies ENV TORRENT_DIRECTORY=/data/torrents -ENV OAUTH_ENABLED=FALSE +ENV OPENID_ENABLED=FALSE WORKDIR /app COPY media_manager ./media_manager diff --git a/media_manager/auth/config.py b/media_manager/auth/config.py index 79f2f5c..8e49eb7 100644 --- a/media_manager/auth/config.py +++ b/media_manager/auth/config.py @@ -14,11 +14,9 @@ class AuthConfig(BaseSettings): return self._jwt_signing_key -class OAuth2Config(BaseSettings): - model_config = SettingsConfigDict(env_prefix="OAUTH_") +class OpenIdConfig(BaseSettings): + model_config = SettingsConfigDict(env_prefix="OPENID_") client_id: str client_secret: str - authorize_endpoint: str - access_token_endpoint: str - user_info_endpoint: str - name: str = "OAuth2" + configuration_endpoint: str + name: str = "OpenID" diff --git a/media_manager/auth/router.py b/media_manager/auth/router.py index 4ffdcf8..bb21e72 100644 --- a/media_manager/auth/router.py +++ b/media_manager/auth/router.py @@ -2,18 +2,18 @@ from fastapi import APIRouter, Depends from fastapi import status from sqlalchemy import select -from media_manager.auth.config import OAuth2Config +from media_manager.auth.config import OpenIdConfig from media_manager.auth.db import User from media_manager.auth.schemas import UserRead from media_manager.auth.users import current_superuser from media_manager.database import DbSessionDependency -from media_manager.auth.users import oauth_client +from media_manager.auth.users import openid_client users_router = APIRouter() auth_metadata_router = APIRouter() -oauth_enabled = oauth_client is not None +oauth_enabled = openid_client is not None if oauth_enabled: - oauth_config = OAuth2Config() + oauth_config = OpenIdConfig() @users_router.get( diff --git a/media_manager/auth/users.py b/media_manager/auth/users.py index 3b7e4d4..d3da1b3 100644 --- a/media_manager/auth/users.py +++ b/media_manager/auth/users.py @@ -12,11 +12,11 @@ from fastapi_users.authentication import ( JWTStrategy, ) from fastapi_users.db import SQLAlchemyUserDatabase -from httpx_oauth.oauth2 import OAuth2 +from httpx_oauth.clients.openid import OpenID from fastapi.responses import RedirectResponse, Response from starlette import status -from media_manager.auth.config import AuthConfig, OAuth2Config +from media_manager.auth.config import AuthConfig, OpenIdConfig from media_manager.auth.db import User, get_user_db from media_manager.auth.schemas import UserUpdate from media_manager.config import BasicConfig @@ -25,39 +25,20 @@ config = AuthConfig() SECRET = config.token_secret LIFETIME = config.session_lifetime - -class GenericOAuth2(OAuth2): - def __init__(self, user_info_endpoint: str, **kwargs): - super().__init__(**kwargs) - self.user_info_endpoint = user_info_endpoint - - async def get_id_email(self, token: str): - userinfo_endpoint = self.user_info_endpoint - async with httpx.AsyncClient() as client: - resp = await client.get( - userinfo_endpoint, headers={"Authorization": f"Bearer {token}"} - ) - resp.raise_for_status() - data = resp.json() - return data["sub"], data["email"] - - if ( os.getenv("OAUTH_ENABLED") is not None and os.getenv("OAUTH_ENABLED").upper() == "TRUE" ): - oauth2_config = OAuth2Config() - oauth_client = GenericOAuth2( - client_id=oauth2_config.client_id, - client_secret=oauth2_config.client_secret, - name=oauth2_config.name, - authorize_endpoint=oauth2_config.authorize_endpoint, - access_token_endpoint=oauth2_config.access_token_endpoint, - user_info_endpoint=oauth2_config.user_info_endpoint, + openid_config = OpenIdConfig() + openid_client = OpenID( + client_id=openid_config.client_id, + client_secret=openid_config.client_secret, + name=openid_config.name, + openid_configuration_endpoint=openid_config.configuration_endpoint, base_scopes=["openid", "email", "profile"], ) else: - oauth_client = None + openid_client = None # TODO: implement on_xxx methods @@ -111,7 +92,7 @@ class RedirectingCookieTransport(CookieTransport): bearer_transport = BearerTransport(tokenUrl="auth/jwt/login") cookie_transport = CookieTransport(cookie_max_age=LIFETIME) -oauth_cookie_transport = RedirectingCookieTransport(cookie_max_age=LIFETIME) +openid_cookie_transport = RedirectingCookieTransport(cookie_max_age=LIFETIME) bearer_auth_backend = AuthenticationBackend( name="jwt", @@ -123,9 +104,9 @@ cookie_auth_backend = AuthenticationBackend( transport=cookie_transport, get_strategy=get_jwt_strategy, ) -oauth_cookie_auth_backend = AuthenticationBackend( +openid_cookie_auth_backend = AuthenticationBackend( name="cookie", - transport=oauth_cookie_transport, + transport=openid_cookie_transport, get_strategy=get_jwt_strategy, ) diff --git a/media_manager/main.py b/media_manager/main.py index 601ddce..f09b3cb 100644 --- a/media_manager/main.py +++ b/media_manager/main.py @@ -87,7 +87,7 @@ app.add_middleware( import uvicorn from fastapi.staticfiles import StaticFiles -from media_manager.auth.users import oauth_client +from media_manager.auth.users import openid_client from media_manager.auth.users import SECRET as AUTH_USERS_SECRET from media_manager.auth.router import users_router as custom_users_router from media_manager.auth.router import auth_metadata_router @@ -96,7 +96,7 @@ from media_manager.auth.users import ( bearer_auth_backend, fastapi_users, cookie_auth_backend, - oauth_cookie_auth_backend, + openid_cookie_auth_backend, ) @@ -129,7 +129,7 @@ app.include_router( # All users route router app.include_router(custom_users_router, tags=["users"]) # OAuth Metadata Router -app.include_router(auth_metadata_router, tags=["oauth"]) +app.include_router(auth_metadata_router, tags=["openid"]) # User Router app.include_router( fastapi_users.get_users_router(UserRead, UserUpdate), @@ -137,16 +137,16 @@ app.include_router( tags=["users"], ) # OAuth2 Routers -if oauth_client is not None: +if openid_client is not None: app.include_router( fastapi_users.get_oauth_router( - oauth_client, - oauth_cookie_auth_backend, + openid_client, + openid_cookie_auth_backend, AUTH_USERS_SECRET, associate_by_email=True, is_verified_by_default=True, ), - prefix=f"/auth/cookie/{oauth_client.name}", + prefix=f"/auth/cookie/{openid_client.name}", tags=["oauth"], )