//! Ports implemented by the infrastructure layer.
use async_trait::async_trait;
use uuid::Uuid;
use crate::auth::{AccessClaims, AuthEvent, RefreshToken};
use crate::host::{Inventory, OsInfo, Package};
use crate::jobs::{JobKind, JobRun, JobStatus};
use crate::settings::SmtpSettings;
use crate::user::{User, UserUpdate};
use crate::DomainError;
#[async_trait]
pub trait UserRepository: Send + Sync {
async fn find_by_id(&self, id: Uuid) -> Result, DomainError>;
async fn find_by_email(&self, email: &str) -> Result , DomainError>;
async fn list(&self) -> Result, DomainError>;
async fn count(&self) -> Result;
async fn count_active_admins(&self) -> Result;
async fn insert(&self, user: &User) -> Result<(), DomainError>;
async fn update(&self, id: Uuid, update: &UserUpdate) -> Result;
async fn set_password_hash(&self, id: Uuid, hash: &str) -> Result<(), DomainError>;
}
#[async_trait]
pub trait RefreshTokenRepository: Send + Sync {
async fn insert(&self, token: &RefreshToken) -> Result<(), DomainError>;
async fn find_by_hash(&self, hash: &str) -> Result, DomainError>;
async fn revoke(&self, id: Uuid) -> Result<(), DomainError>;
async fn revoke_family(&self, family: Uuid) -> Result<(), DomainError>;
}
#[async_trait]
pub trait AuditLog: Send + Sync {
async fn record(&self, event: &AuthEvent) -> Result<(), DomainError>;
}
pub trait PasswordHasher: Send + Sync {
fn hash(&self, password: &str) -> Result;
fn verify(&self, password: &str, hash: &str) -> bool;
}
pub trait AccessTokenIssuer: Send + Sync {
fn issue(&self, user: &User) -> Result;
fn verify(&self, token: &str) -> Result;
}
#[async_trait]
pub trait SettingsRepository: Send + Sync {
async fn get(&self, key: &str) -> Result, DomainError>;
async fn set(&self, key: &str, value: &str) -> Result<(), DomainError>;
}
/// Symmetric encryption for secrets at rest.
pub trait Cipher: Send + Sync {
fn encrypt(&self, plain: &str) -> Result;
fn decrypt(&self, cipher_text: &str) -> Result;
}
#[async_trait]
pub trait Mailer: Send + Sync {
async fn send(
&self,
smtp: &SmtpSettings,
to: &[String],
subject: &str,
body: &str,
) -> Result<(), DomainError>;
}
#[async_trait]
pub trait JobRunRepository: Send + Sync {
async fn insert(&self, run: &JobRun) -> Result<(), DomainError>;
async fn append_log(&self, id: Uuid, line: &str) -> Result<(), DomainError>;
async fn finish(&self, id: Uuid, status: JobStatus) -> Result<(), DomainError>;
async fn get(&self, id: Uuid) -> Result, DomainError>;
async fn list(&self, limit: u32) -> Result, DomainError>;
async fn find_running(&self, kind: JobKind) -> Result, DomainError>;
async fn last_finished(&self, kind: JobKind) -> Result , DomainError>;
}
/// Reads the state of the Debian host.
#[async_trait]
pub trait HostInspector: Send + Sync {
async fn os_info(&self) -> Result;
async fn packages(&self) -> Result, DomainError>;
}
#[async_trait]
pub trait InventoryRepository: Send + Sync {
async fn save(&self, inventory: &Inventory) -> Result<(), DomainError>;
async fn load(&self) -> Result, DomainError>;
}