use sea_orm::DatabaseConnection;
use std::sync::Arc;
use crate::auth::roles::AuthRole;
#[cfg(feature = "admin-override")]
use crate::auth::admin_override::AdminOverride;
#[derive(Clone, Debug)]
pub struct TenantInfo {
pub name: String,
pub droplet_id: Option<i64>,
pub db_version: i32,
}
impl TenantInfo {
pub fn new(name: impl Into<String>, droplet_id: Option<i64>, db_version: i32) -> Self {
Self {
name: name.into(),
droplet_id,
db_version,
}
}
}
pub struct ContextData {
pub db: DatabaseConnection,
pub user: Option<String>,
pub role: Option<AuthRole>,
pub tenant: Option<Arc<TenantInfo>>,
#[cfg(feature = "admin-override")]
pub admin_override: Option<AdminOverride>,
}
impl ContextData {
pub fn new(
db: DatabaseConnection,
user: Option<String>,
role: Option<AuthRole>,
tenant: Option<TenantInfo>,
#[cfg(feature = "admin-override")] admin_override: Option<AdminOverride>,
) -> Self {
Self {
db,
user,
role,
tenant: tenant.map(Arc::new),
#[cfg(feature = "admin-override")]
admin_override,
}
}
pub fn single_tenant(
db: DatabaseConnection,
user: Option<String>,
role: Option<AuthRole>,
#[cfg(feature = "admin-override")] admin_override: Option<AdminOverride>,
) -> Self {
Self {
db,
user,
role,
tenant: None,
#[cfg(feature = "admin-override")]
admin_override,
}
}
pub fn multi_tenant(
db: DatabaseConnection,
user: Option<String>,
role: Option<AuthRole>,
tenant: TenantInfo,
#[cfg(feature = "admin-override")] admin_override: Option<AdminOverride>,
) -> Self {
Self {
db,
user,
role,
tenant: Some(Arc::new(tenant)),
#[cfg(feature = "admin-override")]
admin_override,
}
}
pub fn is_authenticated(&self) -> bool {
self.user.is_some()
}
pub fn user_id(&self) -> Option<&str> {
self.user.as_deref()
}
pub fn auth_role(&self) -> Option<&AuthRole> {
self.role.as_ref()
}
pub fn is_admin(&self) -> bool {
if self.role.as_ref().is_some_and(|r| r.is_admin()) {
return true;
}
#[cfg(feature = "admin-override")]
if self.admin_override.is_some() {
return true;
}
false
}
#[cfg(feature = "admin-override")]
pub fn admin_override(&self) -> Option<&AdminOverride> {
self.admin_override.as_ref()
}
pub fn tenant_name(&self) -> Option<&str> {
self.tenant.as_ref().map(|t| t.name.as_str())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_tenant_info() {
let info = TenantInfo::new("acme", Some(1), 2);
assert_eq!(info.name, "acme");
assert_eq!(info.droplet_id, Some(1));
assert_eq!(info.db_version, 2);
}
}