mirror of
https://github.com/danbulant/Portfolio
synced 2026-07-05 02:50:47 +00:00
feat: get candidate admin endpoint
This commit is contained in:
parent
4375b9d932
commit
0ffe203c5a
4 changed files with 37 additions and 29 deletions
|
|
@ -68,6 +68,7 @@ async fn start() -> Result<(), rocket::Error> {
|
||||||
routes::admin::whoami,
|
routes::admin::whoami,
|
||||||
routes::admin::hello,
|
routes::admin::hello,
|
||||||
routes::admin::create_candidate,
|
routes::admin::create_candidate,
|
||||||
|
routes::admin::get_candidate,
|
||||||
],
|
],
|
||||||
)
|
)
|
||||||
.mount(
|
.mount(
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use std::net::SocketAddr;
|
||||||
|
|
||||||
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}, responses::CandidateResponse,
|
services::{admin_service::AdminService, candidate_service::CandidateService, application_service::ApplicationService}, responses::CandidateResponse, candidate_details::ApplicationDetails,
|
||||||
};
|
};
|
||||||
use requests::{AdminLoginRequest, RegisterRequest};
|
use requests::{AdminLoginRequest, RegisterRequest};
|
||||||
use rocket::http::{Cookie, Status, CookieJar};
|
use rocket::http::{Cookie, Status, CookieJar};
|
||||||
|
|
@ -98,7 +98,27 @@ pub async fn list_candidates(
|
||||||
|
|
||||||
let candidates = CandidateService::list_candidates(private_key, db, field)
|
let candidates = CandidateService::list_candidates(private_key, db, field)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| Custom(Status::InternalServerError, e.to_string()))?;
|
.map_err(|e| Custom(Status::from_code(e.code()).unwrap(), e.to_string()))?;
|
||||||
|
|
||||||
Ok(Json(candidates))
|
Ok(Json(candidates))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/candidate/<id>")]
|
||||||
|
pub async fn get_candidate(
|
||||||
|
conn: Connection<'_, Db>,
|
||||||
|
session: AdminAuth,
|
||||||
|
id: i32,
|
||||||
|
) -> Result<Json<ApplicationDetails>, Custom<String>> {
|
||||||
|
let db = conn.into_inner();
|
||||||
|
let private_key = session.get_private_key();
|
||||||
|
|
||||||
|
let details = ApplicationService::decrypt_all_details(
|
||||||
|
private_key,
|
||||||
|
db,
|
||||||
|
id
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.map_err(|e| Custom(Status::from_code(e.code()).unwrap(), e.to_string()))?;
|
||||||
|
|
||||||
|
Ok(Json(details))
|
||||||
|
}
|
||||||
|
|
@ -12,7 +12,6 @@ use sea_orm_rocket::Connection;
|
||||||
|
|
||||||
use crate::guards::data::letter::Letter;
|
use crate::guards::data::letter::Letter;
|
||||||
use crate::guards::data::portfolio::Portfolio;
|
use crate::guards::data::portfolio::Portfolio;
|
||||||
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>")]
|
||||||
|
|
@ -83,18 +82,21 @@ pub async fn add_details(
|
||||||
Ok("Details added".to_string())
|
Ok("Details added".to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[post("/get_details", data = "<password_form>")]
|
#[post("/get_details")]
|
||||||
pub async fn get_details(
|
pub async fn get_details(
|
||||||
conn: Connection<'_, Db>,
|
conn: Connection<'_, Db>,
|
||||||
password_form: Json<PasswordRequest>,
|
session: CandidateAuth
|
||||||
session: CandidateAuth,
|
|
||||||
) -> Result<Json<ApplicationDetails>, Custom<String>> {
|
) -> Result<Json<ApplicationDetails>, Custom<String>> {
|
||||||
let db = conn.into_inner();
|
let db = conn.into_inner();
|
||||||
|
let private_key = session.get_private_key();
|
||||||
let candidate: entity::candidate::Model = session.into();
|
let candidate: entity::candidate::Model = session.into();
|
||||||
let password = password_form.password.clone();
|
|
||||||
|
|
||||||
// let handle = tokio::spawn(async move {
|
// let handle = tokio::spawn(async move {
|
||||||
let details = ApplicationService::decrypt_all_details(db, candidate.application, password)
|
let details = ApplicationService::decrypt_all_details(private_key,
|
||||||
|
db,
|
||||||
|
candidate.application
|
||||||
|
)
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Custom(
|
Custom(
|
||||||
|
|
|
||||||
|
|
@ -60,32 +60,17 @@ impl ApplicationService {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn decrypt_all_details(
|
pub async fn decrypt_all_details(
|
||||||
|
private_key: String,
|
||||||
db: &DbConn,
|
db: &DbConn,
|
||||||
application_id: i32,
|
application_id: i32,
|
||||||
password: String,
|
|
||||||
) -> Result<ApplicationDetails, ServiceError> {
|
) -> Result<ApplicationDetails, ServiceError> {
|
||||||
let candidate = match Query::find_candidate_by_id(db, application_id).await {
|
let candidate = Query::find_candidate_by_id(db, application_id).await?
|
||||||
Ok(candidate) => candidate.unwrap(),
|
.ok_or(ServiceError::CandidateNotFound)?;
|
||||||
Err(e) => return Err(ServiceError::DbError(e)), // TODO: logging
|
let parent = Query::find_parent_by_id(db, application_id).await?
|
||||||
};
|
.ok_or(ServiceError::ParentNotFound)?;
|
||||||
let parent = Query::find_parent_by_id(db, application_id).await?.unwrap();
|
|
||||||
|
|
||||||
match crypto::verify_password((&password).to_string(), candidate.code.clone()).await {
|
|
||||||
Ok(valid) => {
|
|
||||||
if !valid {
|
|
||||||
return Err(ServiceError::InvalidCredentials);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(_) => return Err(ServiceError::InvalidCredentials),
|
|
||||||
}
|
|
||||||
|
|
||||||
let dec_priv_key = crypto::decrypt_password(candidate.private_key.clone(), password)
|
|
||||||
.await
|
|
||||||
.ok()
|
|
||||||
.unwrap();
|
|
||||||
let enc_details = EncryptedApplicationDetails::try_from((candidate, parent))?;
|
let enc_details = EncryptedApplicationDetails::try_from((candidate, parent))?;
|
||||||
|
|
||||||
enc_details.decrypt(dec_priv_key).await
|
enc_details.decrypt(private_key).await
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in a new issue