Source code for app.domain.accounts.services._user_oauth_account

from __future__ import annotations

from datetime import UTC, datetime
from typing import TYPE_CHECKING, Any

from advanced_alchemy.repository import SQLAlchemyAsyncRepository
from advanced_alchemy.service import SQLAlchemyAsyncRepositoryService

from app.db import models as m

if TYPE_CHECKING:
    from uuid import UUID

    from httpx_oauth.oauth2 import OAuth2Token


[docs] class UserOAuthAccountService(SQLAlchemyAsyncRepositoryService[m.UserOAuthAccount]): """Handles database operations for user OAuth external authorization."""
[docs] class Repo(SQLAlchemyAsyncRepository[m.UserOAuthAccount]): """User SQLAlchemy Repository.""" model_type = m.UserOAuthAccount
repository_type = Repo
[docs] async def create_or_update_oauth_account( self, user_id: UUID, provider: str, oauth_data: dict[str, Any], token_data: OAuth2Token, ) -> m.UserOAuthAccount: """Create or update OAuth account with token data.""" account_id = oauth_data.get("id", oauth_data.get("sub", "")) account_email = oauth_data.get("email", "") return await self.link_or_update_oauth( user_id=user_id, provider=provider, account_id=account_id, account_email=account_email, access_token=token_data["access_token"], refresh_token=token_data.get("refresh_token"), expires_at=token_data.get("expires_at"), scopes=token_data.get("scope"), provider_user_data=oauth_data, last_login_at=datetime.now(UTC), )
[docs] async def get_by_provider_account_id( self, provider: str, account_id: str, ) -> m.UserOAuthAccount | None: """Get an OAuth account by provider and account ID.""" return await self.get_one_or_none(oauth_name=provider, account_id=account_id)