from dataclasses import dataclass from anydi import singleton from fansifter_common.auth.services import AuthService from fansifter_common.auth.types import Permission from dmp.adapters.db import DefaultDB, transactional from dmp.adapters.tiktok import TikTokClient from dmp.adapters.tiktok.exceptions import TikTokClientError from dmp.tiktok.dtos import TikTokUserConnectionResponse from dmp.tiktok.enums import TikTokUserConnectionStatus from dmp.tiktok.services import TikTokUserConnectionService @dataclass(frozen=True) class GetTikTokUserConnectionRequest: identity_id: str user_id: str @singleton class GetTikTokUserConnectionHandler: permission = Permission("ad_connection", "view") def __init__( self, db: DefaultDB, auth_service: AuthService, tiktok_client: TikTokClient, user_connection_service: TikTokUserConnectionService, ) -> None: self.db = db self.auth_service = auth_service self.tiktok_client = tiktok_client self.user_connection_service = user_connection_service @transactional def handle( self, request: GetTikTokUserConnectionRequest ) -> TikTokUserConnectionResponse: user_connection = self.user_connection_service.get_user_connection( identity_id=request.identity_id, user_id=request.user_id, ) if not user_connection: return self.user_connection_service.make_error_response( status=TikTokUserConnectionStatus.NOT_CONNECTED, ) self.auth_service.check_owned_resource( user_connection.identity_id, permission=self.permission, resource_id=user_connection.id, ) if not user_connection.is_valid: return self.user_connection_service.make_error_response( status=TikTokUserConnectionStatus.INVALID, ) access_token = self.user_connection_service.decrypt_token(user_connection.token) try: user = self.tiktok_client.get_user(access_token=access_token) self.user_connection_service.update_user_data(user_connection, user) except TikTokClientError: self.user_connection_service.invalidate_user_connection(user_connection) return self.user_connection_service.make_error_response( status=TikTokUserConnectionStatus.INVALID, ) self.user_connection_service.save_user_connection(user_connection) return self.user_connection_service.make_connected_response(user_connection)