# Copyright (c) 2025 Patrick Motsch # All rights reserved. """ Security service for token management operations. Core service - not requested by features directly. """ import logging from typing import Optional, Callable, Any from modules.datamodels.datamodelSecurity import Token from modules.auth import TokenManager logger = logging.getLogger(__name__) class SecurityService: """Security service providing token management operations.""" def __init__(self, context: Any, get_service: Callable[[str], Any]): """Initialize with service center context and resolver.""" self._context = context self._get_service = get_service self._tokenManager = TokenManager() from modules.interfaces.interfaceDbApp import getInterface as getAppInterface self._interfaceDbApp = getAppInterface( context.user, mandateId=context.mandate_id, ) def getFreshToken(self, connectionId: str, secondsBeforeExpiry: int = 30 * 60) -> Optional[Token]: """Get a fresh token for a connection, refreshing when expiring soon.""" try: token = self._interfaceDbApp.getConnectionToken(connectionId) if not token: return None return self._tokenManager.ensureFreshToken( token, secondsBeforeExpiry=secondsBeforeExpiry, saveCallback=lambda t: self._interfaceDbApp.saveConnectionToken(t) ) except Exception as e: logger.error(f"getFreshToken: Error fetching or refreshing token for connection {connectionId}: {e}") return None def refreshToken(self, oldToken: Token) -> Optional[Token]: """Refresh an expired token using the appropriate OAuth service.""" try: return self._tokenManager.refreshToken(oldToken) except Exception as e: logger.error(f"refreshToken: Error refreshing token: {e}") return None def ensureFreshToken(self, token: Token, *, secondsBeforeExpiry: int = 30 * 60, saveCallback: Optional[Callable[[Token], None]] = None) -> Optional[Token]: """Ensure a token is fresh; refresh if expiring within threshold.""" try: return self._tokenManager.ensureFreshToken( token, secondsBeforeExpiry=secondsBeforeExpiry, saveCallback=saveCallback ) except Exception as e: logger.error(f"ensureFreshToken: Error ensuring fresh token: {e}") return None def refreshMicrosoftToken(self, refreshToken: str, userId: str, oldToken: Token) -> Optional[Token]: """Refresh Microsoft OAuth token using refresh token.""" try: return self._tokenManager.refreshMicrosoftToken(refreshToken, userId, oldToken) except Exception as e: logger.error(f"refreshMicrosoftToken: Error refreshing Microsoft token: {e}") return None def refreshGoogleToken(self, refreshToken: str, userId: str, oldToken: Token) -> Optional[Token]: """Refresh Google OAuth token using refresh token.""" try: return self._tokenManager.refreshGoogleToken(refreshToken, userId, oldToken) except Exception as e: logger.error(f"refreshGoogleToken: Error refreshing Google token: {e}") return None