mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-07 16:50:13 +00:00
Merge pull request #62 from EETagent/logout
This commit is contained in:
commit
a6f3fbd5c9
6 changed files with 60 additions and 5 deletions
|
|
@ -40,6 +40,7 @@ pub fn rocket() -> Rocket<Build>{
|
||||||
"/candidate/",
|
"/candidate/",
|
||||||
routes![
|
routes![
|
||||||
routes::candidate::login,
|
routes::candidate::login,
|
||||||
|
routes::candidate::logout,
|
||||||
routes::candidate::whoami,
|
routes::candidate::whoami,
|
||||||
routes::candidate::get_details,
|
routes::candidate::get_details,
|
||||||
],
|
],
|
||||||
|
|
@ -67,6 +68,7 @@ pub fn rocket() -> Rocket<Build>{
|
||||||
"/admin/",
|
"/admin/",
|
||||||
routes![
|
routes![
|
||||||
routes::admin::login,
|
routes::admin::login,
|
||||||
|
routes::admin::logout,
|
||||||
routes::admin::whoami,
|
routes::admin::whoami,
|
||||||
routes::admin::hello,
|
routes::admin::hello,
|
||||||
routes::admin::create_candidate,
|
routes::admin::create_candidate,
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
use portfolio_core::{
|
use portfolio_core::{
|
||||||
crypto::random_8_char_string,
|
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 requests::{AdminLoginRequest, RegisterRequest};
|
||||||
use rocket::http::{Cookie, Status, CookieJar};
|
use rocket::http::{Cookie, Status, CookieJar};
|
||||||
|
|
@ -51,6 +51,25 @@ pub async fn login(
|
||||||
return Ok(response);
|
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")]
|
#[get("/whoami")]
|
||||||
pub async fn whoami(session: AdminAuth) -> Result<String, Custom<String>> {
|
pub async fn whoami(session: AdminAuth) -> Result<String, Custom<String>> {
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,7 @@
|
||||||
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
|
|
||||||
use portfolio_core::candidate_details::ApplicationDetails;
|
use portfolio_core::candidate_details::ApplicationDetails;
|
||||||
|
use portfolio_core::sea_orm::prelude::Uuid;
|
||||||
use portfolio_core::services::application_service::ApplicationService;
|
use portfolio_core::services::application_service::ApplicationService;
|
||||||
use portfolio_core::services::candidate_service::CandidateService;
|
use portfolio_core::services::candidate_service::CandidateService;
|
||||||
use portfolio_core::services::portfolio_service::{PortfolioService, SubmissionProgress};
|
use portfolio_core::services::portfolio_service::{PortfolioService, SubmissionProgress};
|
||||||
|
|
@ -51,6 +52,25 @@ pub async fn login(
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[post("/logout")]
|
||||||
|
pub async fn logout(conn: Connection<'_, Db>, _session: CandidateAuth, 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 = 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"));
|
||||||
|
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
|
|
||||||
#[get("/whoami")]
|
#[get("/whoami")]
|
||||||
pub async fn whoami(session: CandidateAuth) -> Result<String, Custom<String>> {
|
pub async fn whoami(session: CandidateAuth) -> Result<String, Custom<String>> {
|
||||||
let candidate: entity::candidate::Model = session.into();
|
let candidate: entity::candidate::Model = session.into();
|
||||||
|
|
|
||||||
|
|
@ -18,9 +18,13 @@ impl Query {
|
||||||
user_id: Option<i32>,
|
user_id: Option<i32>,
|
||||||
admin_id: Option<i32>,
|
admin_id: Option<i32>,
|
||||||
) -> Result<Vec<session::Model>, DbErr> {
|
) -> Result<Vec<session::Model>, DbErr> {
|
||||||
Session::find()
|
if user_id.is_some() {
|
||||||
.filter(session::Column::UserId.eq(user_id))
|
Session::find()
|
||||||
.filter(session::Column::AdminId.eq(admin_id))
|
.filter(session::Column::UserId.eq(user_id))
|
||||||
|
} else {
|
||||||
|
Session::find()
|
||||||
|
.filter(session::Column::AdminId.eq(admin_id))
|
||||||
|
}
|
||||||
.all(db)
|
.all(db)
|
||||||
.await
|
.await
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
use entity::admin;
|
use entity::admin;
|
||||||
use sea_orm::{prelude::Uuid, DbConn};
|
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};
|
use super::session_service::{AdminUser, SessionService};
|
||||||
|
|
||||||
|
|
@ -38,6 +38,11 @@ impl AdminService {
|
||||||
Ok((session_id, private_key))
|
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> {
|
pub async fn auth(db: &DbConn, session_uuid: Uuid) -> Result<admin::Model, ServiceError> {
|
||||||
match SessionService::auth_user_session(db, session_uuid).await? {
|
match SessionService::auth_user_session(db, session_uuid).await? {
|
||||||
AdminUser::Admin(admin) => Ok(admin),
|
AdminUser::Admin(admin) => Ok(admin),
|
||||||
|
|
|
||||||
|
|
@ -131,6 +131,11 @@ impl CandidateService {
|
||||||
Ok(new_password_plain)
|
Ok(new_password_plain)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn logout(db: &DbConn, session_id: Uuid) -> Result<(), ServiceError> {
|
||||||
|
Mutation::delete_session(db, session_id).await?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub(in crate::services) async fn add_candidate_details(
|
pub(in crate::services) async fn add_candidate_details(
|
||||||
db: &DbConn,
|
db: &DbConn,
|
||||||
candidate: candidate::Model,
|
candidate: candidate::Model,
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue