Merge pull request #62 from EETagent/logout

This commit is contained in:
Vojtěch Jungmann 2022-11-25 23:32:01 +01:00 committed by GitHub
commit a6f3fbd5c9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 60 additions and 5 deletions

View file

@ -40,6 +40,7 @@ pub fn rocket() -> Rocket<Build>{
"/candidate/",
routes![
routes::candidate::login,
routes::candidate::logout,
routes::candidate::whoami,
routes::candidate::get_details,
],
@ -67,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,

View file

@ -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>> {

View file

@ -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};
@ -51,6 +52,25 @@ pub async fn login(
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")]
pub async fn whoami(session: CandidateAuth) -> Result<String, Custom<String>> {
let candidate: entity::candidate::Model = session.into();

View file

@ -18,9 +18,13 @@ impl Query {
user_id: Option<i32>,
admin_id: Option<i32>,
) -> Result<Vec<session::Model>, DbErr> {
Session::find()
.filter(session::Column::UserId.eq(user_id))
.filter(session::Column::AdminId.eq(admin_id))
if user_id.is_some() {
Session::find()
.filter(session::Column::UserId.eq(user_id))
} else {
Session::find()
.filter(session::Column::AdminId.eq(admin_id))
}
.all(db)
.await
}

View file

@ -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),

View file

@ -131,6 +131,11 @@ impl CandidateService {
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(
db: &DbConn,
candidate: candidate::Model,