use chrono::{DateTime, Utc}; use serde::{Deserialize, Serialize}; /// Core domain model for OAuth2 clients #[derive(Debug, Clone, PartialEq)] pub struct OAuthClient { pub client_id: String, pub client_name: String, pub redirect_uris: Vec, pub scopes: Vec, pub grant_types: Vec, pub response_types: Vec, pub is_active: bool, pub created_at: DateTime, pub updated_at: DateTime, } /// Core domain model for authorization codes #[derive(Debug, Clone, PartialEq)] pub struct AuthorizationCode { pub code: String, pub client_id: String, pub user_id: String, pub redirect_uri: String, pub scopes: Vec, pub expires_at: DateTime, pub created_at: DateTime, pub is_used: bool, // PKCE fields pub code_challenge: Option, pub code_challenge_method: Option, } /// Core domain model for access tokens #[derive(Debug, Clone, PartialEq)] pub struct AccessToken { pub token_id: String, pub client_id: String, pub user_id: String, pub scopes: Vec, pub expires_at: DateTime, pub created_at: DateTime, pub is_revoked: bool, } /// Core domain model for refresh tokens #[derive(Debug, Clone, PartialEq)] pub struct RefreshToken { pub token_id: String, pub access_token_id: String, pub client_id: String, pub user_id: String, pub scopes: Vec, pub expires_at: DateTime, pub created_at: DateTime, pub is_revoked: bool, } /// Domain model for audit events #[derive(Debug, Clone, PartialEq)] pub struct AuditEvent { pub event_type: String, pub client_id: Option, pub user_id: Option, pub ip_address: Option, pub user_agent: Option, pub details: Option, pub success: bool, pub timestamp: DateTime, } /// Domain model for rate limiting #[derive(Debug, Clone, PartialEq)] pub struct RateLimit { pub identifier: String, pub endpoint: String, pub count: u32, pub window_start: DateTime, pub window_duration_minutes: u32, } /// JWT token claims for domain use #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct TokenClaims { pub sub: String, // Subject (user ID) pub iss: String, // Issuer pub aud: String, // Audience (client ID) pub exp: u64, // Expiration time pub iat: u64, // Issued at pub jti: String, // JWT ID (token ID) pub scope: Option, // Granted scopes } /// OAuth2 authorization request #[derive(Debug, Clone, PartialEq)] pub struct AuthorizationRequest { pub client_id: String, pub redirect_uri: String, pub response_type: String, pub scope: Option, pub state: Option, // PKCE pub code_challenge: Option, pub code_challenge_method: Option, } /// OAuth2 token request #[derive(Debug, Clone, PartialEq)] pub struct TokenRequest { pub grant_type: String, pub code: Option, // For authorization_code grant pub refresh_token: Option, // For refresh_token grant pub redirect_uri: Option, // For authorization_code grant pub client_id: String, pub client_secret: Option, // PKCE pub code_verifier: Option, } /// Result of successful authorization #[derive(Debug, Clone, PartialEq)] pub struct AuthorizationResult { pub redirect_url: String, } /// Result of successful token generation #[derive(Debug, Clone, PartialEq)] pub struct TokenResult { pub access_token: String, pub token_type: String, pub expires_in: u64, pub refresh_token: Option, pub scope: Option, } /// OAuth2 error with domain context #[derive(Debug, Clone, PartialEq)] pub struct OAuthError { pub error_code: String, pub description: Option, pub uri: Option, } impl OAuthError { pub fn invalid_request(description: &str) -> Self { Self { error_code: "invalid_request".to_string(), description: Some(description.to_string()), uri: None, } } pub fn invalid_client(description: &str) -> Self { Self { error_code: "invalid_client".to_string(), description: Some(description.to_string()), uri: None, } } pub fn invalid_grant(description: &str) -> Self { Self { error_code: "invalid_grant".to_string(), description: Some(description.to_string()), uri: None, } } pub fn unsupported_grant_type(description: &str) -> Self { Self { error_code: "unsupported_grant_type".to_string(), description: Some(description.to_string()), uri: None, } } pub fn server_error(description: &str) -> Self { Self { error_code: "server_error".to_string(), description: Some(description.to_string()), uri: None, } } } /// User representation for OAuth2 flows #[derive(Debug, Clone, PartialEq)] pub struct User { pub id: String, pub username: Option, pub email: Option, pub is_active: bool, } /// Scope representation #[derive(Debug, Clone, PartialEq)] pub struct Scope { pub name: String, pub description: Option, } impl Scope { pub fn openid() -> Self { Self { name: "openid".to_string(), description: Some("OpenID Connect scope".to_string()), } } pub fn profile() -> Self { Self { name: "profile".to_string(), description: Some("Access to user profile information".to_string()), } } pub fn email() -> Self { Self { name: "email".to_string(), description: Some("Access to user email address".to_string()), } } }