use serde::{Deserialize, Serialize};
use std::collections::HashMap;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum IdentityProvider {
Oidc,
Saml,
Okta,
Auth0,
AzureAd,
Custom,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub enum AuthMethod {
Password,
Mfa,
Sso,
Certificate,
ApiKey,
ServiceAccount,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct IdentityPrincipal {
pub id: String,
pub provider: IdentityProvider,
pub issuer: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub display_name: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub email_verified: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization_id: Option<String>,
#[serde(default)]
pub teams: Vec<String>,
#[serde(default)]
pub roles: Vec<String>,
#[serde(default)]
pub attributes: HashMap<String, serde_json::Value>,
pub authenticated_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub auth_method: Option<AuthMethod>,
#[serde(skip_serializing_if = "Option::is_none")]
pub expires_at: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(rename_all = "lowercase")]
pub enum OrganizationTier {
Free,
Pro,
Enterprise,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct OrganizationContext {
pub id: String,
pub name: String,
pub tier: OrganizationTier,
#[serde(skip_serializing_if = "Option::is_none")]
pub settings: Option<serde_json::Value>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct GeoLocation {
#[serde(skip_serializing_if = "Option::is_none")]
pub country: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub region: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub city: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub latitude: Option<f64>,
#[serde(skip_serializing_if = "Option::is_none")]
pub longitude: Option<f64>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct RequestContext {
pub request_id: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub source_ip: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub user_agent: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub geo_location: Option<GeoLocation>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_vpn: Option<bool>,
#[serde(skip_serializing_if = "Option::is_none")]
pub is_corporate_network: Option<bool>,
pub timestamp: String,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SessionMetadata {
pub auth_method: AuthMethod,
#[serde(skip_serializing_if = "Option::is_none")]
pub idp_issuer: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub token_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub parent_session_id: Option<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub tags: Option<Vec<String>>,
}
#[derive(Clone, Debug, Serialize, Deserialize)]
pub struct SessionContext {
pub session_id: String,
pub identity: IdentityPrincipal,
pub created_at: String,
pub last_activity_at: String,
pub expires_at: String,
#[serde(skip_serializing_if = "Option::is_none")]
pub organization: Option<OrganizationContext>,
#[serde(default)]
pub effective_roles: Vec<String>,
#[serde(default)]
pub effective_permissions: Vec<String>,
#[serde(skip_serializing_if = "Option::is_none")]
pub request: Option<RequestContext>,
#[serde(skip_serializing_if = "Option::is_none")]
pub metadata: Option<SessionMetadata>,
#[serde(skip_serializing_if = "Option::is_none")]
pub state: Option<HashMap<String, serde_json::Value>>,
}