feat: get candidate details

This commit is contained in:
Sebastian Pravda 2022-11-08 01:22:10 +01:00
parent 077adfd117
commit 7b4707fae6
5 changed files with 66 additions and 11 deletions

View file

@ -42,6 +42,7 @@ async fn start() -> Result<(), rocket::Error> {
routes::candidate::login, routes::candidate::login,
routes::candidate::whoami, routes::candidate::whoami,
routes::candidate::fill_details, routes::candidate::fill_details,
routes::candidate::get_details,
], ],
) )
.mount( .mount(

View file

@ -21,4 +21,10 @@ pub struct RegisterRequest {
pub struct AdminLoginRequest { pub struct AdminLoginRequest {
pub admin_id: i32, pub admin_id: i32,
pub password: String, pub password: String,
}
#[derive(Serialize, Deserialize)]
#[serde(crate = "rocket::serde")]
pub struct PasswordRequest {
pub password: String,
} }

View file

@ -8,6 +8,7 @@ use rocket::serde::json::Json;
use sea_orm_rocket::Connection; use sea_orm_rocket::Connection;
use crate::requests::PasswordRequest;
use crate::{guards::request::auth::CandidateAuth, pool::Db, requests}; use crate::{guards::request::auth::CandidateAuth, pool::Db, requests};
#[post("/login", data = "<login_form>")] #[post("/login", data = "<login_form>")]
@ -70,3 +71,49 @@ pub async fn fill_details(
Ok("Details added".to_string()) Ok("Details added".to_string())
} }
#[post("/get_details", data = "<password_form>")]
pub async fn get_details(
conn: Connection<'_, Db>,
password_form: Json<PasswordRequest>,
session: CandidateAuth,
) -> Result<Json<UserDetails>, Custom<String>> {
let db = conn.into_inner();
let candidate: entity::candidate::Model = session.into();
let password = password_form.password.clone();
// let handle = tokio::spawn(async move {
let details = CandidateService::decrypt_details(db, candidate.application, password).await.map_err(|e| {
Custom(
Status::from_code(e.code()).unwrap_or_default(),
e.message(),
)
});
details.map(|d| Json(d))
}
// #[post("/details", data = "<password_form>")]
// pub async fn get_details(
// conn: Connection<'_, Db>,
// password_form: Json<PasswordRequest>,
// session: CandidateAuth,
// ) -> Result<String, Custom<String>> {
// let db = conn.into_inner();
// let candidate: entity::candidate::Model = session.into();
// let password = password_form.password.clone();
// let details = CandidateService::decrypt_details(db, candidate.application, password).await;
// if details.is_err() {
// // TODO cleanup
// let e = details.err().unwrap();
// return Err(Custom(
// Status::from_code(e.code()).unwrap_or_default(),
// e.message(),
// ));
// }
// // Ok(Json(details.unwrap()))
// Ok("coming soon".to_string())
// }

View file

@ -11,6 +11,8 @@ use std::iter;
use std::path::Path; use std::path::Path;
use std::str::FromStr; use std::str::FromStr;
use crate::error::ServiceError;
/// Foolproof random 8 char string /// Foolproof random 8 char string
/// only uppercase letters (except for 0 and O) and numbers /// only uppercase letters (except for 0 and O) and numbers
/// TODO tests /// TODO tests
@ -265,14 +267,14 @@ pub async fn encrypt_password_with_recipients(
pub async fn decrypt_password_with_private_key( pub async fn decrypt_password_with_private_key(
password_encrypted: &str, password_encrypted: &str,
key: &str, key: &str,
) -> Result<String, Box<dyn std::error::Error>> { ) -> Result<String, ServiceError> {
let encrypted = base64::decode(password_encrypted)?; let encrypted = base64::decode(password_encrypted).unwrap();
let mut decrypt_buffer = Vec::new(); let mut decrypt_buffer = Vec::new();
age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await?; age_decrypt_with_private_key(encrypted.as_slice(), &mut decrypt_buffer, key).await.unwrap();
Ok(String::from_utf8(decrypt_buffer)?) Ok(String::from_utf8(decrypt_buffer).ok().unwrap())
} }
pub async fn encrypt_file_with_recipients<P: AsRef<Path>>( pub async fn encrypt_file_with_recipients<P: AsRef<Path>>(

View file

@ -1,6 +1,6 @@
use entity::candidate; use entity::candidate;
use sea_orm::{prelude::Uuid, DbConn}; use sea_orm::{prelude::Uuid, DbConn};
use serde::Deserialize; use serde::{Deserialize, Serialize};
use crate::{ use crate::{
crypto::{self, hash_password}, crypto::{self, hash_password},
@ -169,7 +169,7 @@ impl EncryptedUserDetails {
} }
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct UserDetails { pub struct UserDetails {
pub name: String, pub name: String,
pub surname: String, pub surname: String,
@ -273,11 +273,10 @@ impl CandidateService {
candidate_id: i32, candidate_id: i32,
password: String, password: String,
) -> Result<UserDetails, ServiceError> { ) -> Result<UserDetails, ServiceError> {
// compare passwords // TODO: login in api?? // TODO: dedicated function let candidate = match Query::find_candidate_by_id(db, candidate_id).await {
let candidate = Query::find_candidate_by_id(db, candidate_id) Ok(candidate) => candidate.unwrap(),
.await Err(_) => return Err(ServiceError::DbError), // TODO: logging
.map_err(|_| ServiceError::DbError)? };
.ok_or(ServiceError::UserNotFound)?;
match crypto::verify_password((&password).to_string(), candidate.code.clone()).await { match crypto::verify_password((&password).to_string(), candidate.code.clone()).await {
Ok(valid) => { Ok(valid) => {