mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-18 14:01:04 +00:00
feat: logout only current session, admin logout endpoint
This commit is contained in:
parent
35f591fb67
commit
492fc5618f
5 changed files with 41 additions and 9 deletions
|
|
@ -68,6 +68,7 @@ pub fn rocket() -> Rocket<Build>{
|
|||
"/admin/",
|
||||
routes![
|
||||
routes::admin::login,
|
||||
routes::admin::logout,
|
||||
routes::admin::whoami,
|
||||
routes::admin::hello,
|
||||
routes::admin::create_candidate,
|
||||
|
|
|
|||
|
|
@ -2,7 +2,7 @@ use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
|||
|
||||
use portfolio_core::{
|
||||
crypto::random_8_char_string,
|
||||
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService, portfolio_service::PortfolioService}, responses::CandidateResponse, candidate_details::ApplicationDetails,
|
||||
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService, portfolio_service::PortfolioService}, responses::CandidateResponse, candidate_details::ApplicationDetails, sea_orm::prelude::Uuid,
|
||||
};
|
||||
use requests::{AdminLoginRequest, RegisterRequest};
|
||||
use rocket::http::{Cookie, Status, CookieJar};
|
||||
|
|
@ -51,6 +51,25 @@ pub async fn login(
|
|||
return Ok(response);
|
||||
}
|
||||
|
||||
#[post("/logout")]
|
||||
pub async fn logout(conn: Connection<'_, Db>, _session: AdminAuth, cookies: &CookieJar<'_>,) -> Result<(), Custom<String>> {
|
||||
let db = conn.into_inner();
|
||||
|
||||
let cookie = cookies.get_private("id") // unwrap would be safe here because of the auth guard
|
||||
.ok_or(Custom(Status::Unauthorized, "No session cookie".to_string()))?;
|
||||
let session_id = Uuid::try_parse(cookie.value()) // unwrap would be safe here because of the auth guard
|
||||
.map_err(|e| Custom(Status::BadRequest, e.to_string()))?;
|
||||
|
||||
let res = AdminService::logout(db, session_id)
|
||||
.await
|
||||
.map_err(|e| Custom(Status::from_code(e.code()).unwrap_or(Status::InternalServerError), e.to_string()))?;
|
||||
|
||||
cookies.remove_private(Cookie::named("id"));
|
||||
cookies.remove_private(Cookie::named("key"));
|
||||
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
|
||||
#[get("/whoami")]
|
||||
pub async fn whoami(session: AdminAuth) -> Result<String, Custom<String>> {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||
|
||||
use portfolio_core::candidate_details::ApplicationDetails;
|
||||
use portfolio_core::sea_orm::prelude::Uuid;
|
||||
use portfolio_core::services::application_service::ApplicationService;
|
||||
use portfolio_core::services::candidate_service::CandidateService;
|
||||
use portfolio_core::services::portfolio_service::{PortfolioService, SubmissionProgress};
|
||||
|
|
@ -52,16 +53,22 @@ pub async fn login(
|
|||
}
|
||||
|
||||
#[post("/logout")]
|
||||
pub async fn logout(conn: Connection<'_, Db>, session: CandidateAuth, cookies: &CookieJar<'_>,) -> Result<(), Custom<String>> {
|
||||
pub async fn logout(conn: Connection<'_, Db>, _session: CandidateAuth, cookies: &CookieJar<'_>,) -> Result<(), Custom<String>> {
|
||||
let db = conn.into_inner();
|
||||
let candidate: entity::candidate::Model = session.into();
|
||||
|
||||
let cookie = cookies.get_private("id") // unwrap would be safe here because of the auth guard
|
||||
.ok_or(Custom(Status::Unauthorized, "No session cookie".to_string()))?;
|
||||
let session_id = Uuid::try_parse(cookie.value()) // unwrap would be safe here because of the auth guard
|
||||
.map_err(|e| Custom(Status::BadRequest, e.to_string()))?;
|
||||
|
||||
let res = CandidateService::logout(db, session_id)
|
||||
.await
|
||||
.map_err(|e| Custom(Status::from_code(e.code()).unwrap_or(Status::InternalServerError), e.to_string()))?;
|
||||
|
||||
cookies.remove_private(Cookie::named("id"));
|
||||
cookies.remove_private(Cookie::named("key"));
|
||||
|
||||
CandidateService::logout(db, candidate.application)
|
||||
.await
|
||||
.map_err(|e| Custom(Status::from_code(e.code()).unwrap_or(Status::InternalServerError), e.to_string()))
|
||||
Ok(res)
|
||||
}
|
||||
|
||||
#[get("/whoami")]
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use entity::admin;
|
||||
use sea_orm::{prelude::Uuid, DbConn};
|
||||
|
||||
use crate::{crypto, error::ServiceError, Query};
|
||||
use crate::{crypto, error::ServiceError, Query, Mutation};
|
||||
|
||||
use super::session_service::{AdminUser, SessionService};
|
||||
|
||||
|
|
@ -38,6 +38,11 @@ impl AdminService {
|
|||
Ok((session_id, private_key))
|
||||
}
|
||||
|
||||
pub async fn logout(db: &DbConn, session_id: Uuid) -> Result<(), ServiceError> {
|
||||
Mutation::delete_session(db, session_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn auth(db: &DbConn, session_uuid: Uuid) -> Result<admin::Model, ServiceError> {
|
||||
match SessionService::auth_user_session(db, session_uuid).await? {
|
||||
AdminUser::Admin(admin) => Ok(admin),
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ impl CandidateService {
|
|||
Ok(new_password_plain)
|
||||
}
|
||||
|
||||
pub async fn logout(db: &DbConn, id: i32) -> Result<(), ServiceError> {
|
||||
SessionService::revoke_all_sessions(db, Some(id), None).await?;
|
||||
pub async fn logout(db: &DbConn, session_id: Uuid) -> Result<(), ServiceError> {
|
||||
Mutation::delete_session(db, session_id).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue