Skip to content
Clone
a06673b
49 lines 1.8 KB Rust
use db::conn::sea_orm::{EntityTrait, QueryFilter, QueryOrder};
use uuid::Uuid;
use crate::error::{UserError, UserResult};
use crate::features::UserService;
use jwt::session;
use super::types::{ListSessionsQuery, SessionView};
pub async fn list(svc: &UserService, caller: Uuid, q: ListSessionsQuery) -> UserResult<Vec<SessionView>> {
let db = svc.db.reader();
let mut sel = db::user::user_sessions::Entity::find()
.filter(db::user::user_sessions::COLUMN.user_id.eq(caller))
.order_by_desc(db::user::user_sessions::COLUMN.created_at);
if let Some(app_id) = q.app_id {
sel = sel.filter(db::user::user_sessions::COLUMN.app_id.eq(app_id));
}
if !q.include_revoked {
sel = sel.filter(db::user::user_sessions::COLUMN.is_revoked.eq(false));
}
let rows = sel.all(&db).await?;
Ok(rows.into_iter().map(SessionView::from).collect())
}
pub async fn revoke_one(svc: &UserService, caller: Uuid, session_id: Uuid) -> UserResult<()> {
let writer = svc.db.writer();
let row = db::user::user_sessions::Entity::find_by_id(session_id)
.one(&writer)
.await?
.ok_or_else(|| UserError::NotFound(format!("session {session_id}")))?;
if row.user_id != caller {
return Err(UserError::Forbidden(
"cannot revoke other user's session".into(),
));
}
session::revoke_session(&writer, session_id)
.await
.map_err(|e| UserError::Internal(format!("jwt revoke_session: {e}")))?;
Ok(())
}
pub async fn revoke_all(svc: &UserService, caller: Uuid) -> UserResult<u64> {
let writer = svc.db.writer();
let result = db::user::user_sessions::Entity::delete_many()
.filter(db::user::user_sessions::COLUMN.user_id.eq(caller))
.exec(&writer)
.await?;
Ok(result.rows_affected)
}