""" Data models for Microsoft integration. """ from pydantic import BaseModel, Field from typing import List, Dict, Any, Optional from datetime import datetime import uuid # Get all attributes of the model def getModelAttributes(modelClass): return [attr for attr in dir(modelClass) if not callable(getattr(modelClass, attr)) and not attr.startswith('_') and attr not in ('metadata', 'query', 'query_class', 'label', 'field_labels')] class Label(BaseModel): """Label for an attribute or a class with support for multiple languages""" default: str translations: Dict[str, str] = {} def getLabel(self, language: str = None): """Returns the label in the specified language, or the default value if not available""" if language and language in self.translations: return self.translations[language] return self.default class MsftToken(BaseModel): """Data model for Microsoft authentication token""" id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Unique ID of the token") access_token: str = Field(description="Microsoft access token") refresh_token: str = Field(description="Microsoft refresh token") expires_in: int = Field(description="Token expiration time in seconds") token_type: str = Field(description="Type of token (usually 'bearer')") expires_at: float = Field(description="Timestamp when token expires") user_info: Optional[Dict[str, Any]] = Field(None, description="User information from Microsoft") _mandateId: str = Field(description="Mandate ID associated with the token") _userId: str = Field(description="User ID associated with the token") label: Label = Field( default=Label(default="Microsoft Token", translations={"en": "Microsoft Token", "fr": "Jeton Microsoft"}), description="Label for the class" ) # Labels for attributes fieldLabels: Dict[str, Label] = { "id": Label(default="ID", translations={}), "access_token": Label(default="Access Token", translations={"en": "Access Token", "fr": "Jeton d'accès"}), "refresh_token": Label(default="Refresh Token", translations={"en": "Refresh Token", "fr": "Jeton de rafraîchissement"}), "expires_in": Label(default="Expires In", translations={"en": "Expires In", "fr": "Expire dans"}), "token_type": Label(default="Token Type", translations={"en": "Token Type", "fr": "Type de jeton"}), "expires_at": Label(default="Expires At", translations={"en": "Expires At", "fr": "Expire à"}), "user_info": Label(default="User Info", translations={"en": "User Info", "fr": "Info utilisateur"}), "_mandateId": Label(default="Mandate ID", translations={"en": "Mandate ID", "fr": "ID de mandat"}), "_userId": Label(default="User ID", translations={"en": "User ID", "fr": "ID utilisateur"}) } class MsftUserInfo(BaseModel): """Data model for Microsoft user information""" name: str = Field(description="User's display name") email: str = Field(description="User's email address") id: str = Field(description="User's Microsoft ID") label: Label = Field( default=Label(default="Microsoft User Info", translations={"en": "Microsoft User Info", "fr": "Info utilisateur Microsoft"}), description="Label for the class" ) # Labels for attributes fieldLabels: Dict[str, Label] = { "name": Label(default="Name", translations={"en": "Name", "fr": "Nom"}), "email": Label(default="Email", translations={"en": "Email", "fr": "E-mail"}), "id": Label(default="ID", translations={}) } # Response models for Microsoft routes class MsftAuthStatus(BaseModel): """Response model for Microsoft authentication status""" authenticated: bool message: Optional[str] = None user: Optional[MsftUserInfo] = None class MsftTokenResponse(BaseModel): """Response model for Microsoft token""" token: MsftToken class MsftSaveTokenResponse(BaseModel): """Response model for saving Microsoft token""" success: bool message: str token: Optional[MsftToken] = None