e870254
use models::users::user_suspensions;
use sea_orm::{ColumnTrait, Condition, EntityTrait, QueryFilter, QueryOrder};
use serde::{Deserialize, Serialize};
use time::OffsetDateTime;
use uuid::Uuid;
use super::AuthService;
use crate::auth::errors::AuthError;
#[derive(Debug, Clone, Serialize, Deserialize, utoipa::ToSchema)]
pub struct SuspensionDto {
pub id: Uuid,
pub suspension_type: String,
pub reason: Option<String>,
pub starts_at: OffsetDateTime,
pub ends_at: Option<OffsetDateTime>,
}
impl AuthService {
pub async fn active_suspension(&self, uid: i64) -> Result<Option<SuspensionDto>, AuthError> {
let now = OffsetDateTime::now_utc();
let Some(row) = user_suspensions::Entity::find()
.filter(user_suspensions::Column::UserId.eq(uid))
.filter(user_suspensions::Column::RevokedAt.is_null())
.filter(user_suspensions::Column::StartsAt.lte(now))
.filter(
Condition::any()
.add(user_suspensions::Column::EndsAt.is_null())
.add(user_suspensions::Column::EndsAt.gt(now)),
)
.order_by_desc(user_suspensions::Column::StartsAt)
.one(self.db().read())
.await?
else {
return Ok(None);
};
Ok(Some(SuspensionDto {
id: row.id,
suspension_type: match row.suspension_type {
user_suspensions::SuspensionType::Temporary => "temporary",
user_suspensions::SuspensionType::Permanent => "permanent",
}
.to_string(),
reason: row.reason,
starts_at: row.starts_at,
ends_at: row.ends_at,
}))
}
pub async fn assert_not_suspended(&self, uid: i64) -> Result<(), AuthError> {
if self.active_suspension(uid).await?.is_some() {
return Err(AuthError::Forbidden);
}
Ok(())
}
}