mirror of
https://github.com/danbulant/Portfolio
synced 2026-06-17 13:31:12 +00:00
feat: initial work on file upload
This commit is contained in:
parent
9f47bff2fa
commit
78d77cd735
2 changed files with 120 additions and 33 deletions
|
|
@ -8,6 +8,8 @@ use rocket::serde::json::Json;
|
|||
|
||||
use sea_orm_rocket::Connection;
|
||||
|
||||
use crate::guards::data::letter::Letter;
|
||||
use crate::guards::data::portfolio::Portfolio;
|
||||
use crate::{guards::request::auth::CandidateAuth, pool::Db, requests};
|
||||
|
||||
#[post("/login", data = "<login_form>")]
|
||||
|
|
@ -47,7 +49,7 @@ pub async fn whoami(session: CandidateAuth) -> Result<String, Custom<String>> {
|
|||
Ok(candidate.application.to_string())
|
||||
}
|
||||
|
||||
#[put("/details", data = "<details>")]
|
||||
#[post("/details", data = "<details>")]
|
||||
pub async fn fill_details(
|
||||
conn: Connection<'_, Db>,
|
||||
details: Json<UserDetails>,
|
||||
|
|
@ -70,3 +72,66 @@ pub async fn fill_details(
|
|||
|
||||
Ok("Details added".to_string())
|
||||
}
|
||||
|
||||
#[post("/coverletter", data = "<letter>")]
|
||||
pub async fn upload_cover_letter(
|
||||
session: CandidateAuth,
|
||||
letter: Letter,
|
||||
) -> Result<String, Custom<String>> {
|
||||
let candidate: entity::candidate::Model = session.into();
|
||||
|
||||
let candidate = CandidateService::add_cover_letter(candidate.application, letter.into()).await;
|
||||
|
||||
if candidate.is_err() {
|
||||
// TODO cleanup
|
||||
let e = candidate.err().unwrap();
|
||||
return Err(Custom(
|
||||
Status::from_code(e.code()).unwrap_or_default(),
|
||||
e.message(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok("Letter added".to_string())
|
||||
}
|
||||
|
||||
#[post("/portfolioletter", data = "<letter>")]
|
||||
pub async fn upload_portfolio_letter(
|
||||
session: CandidateAuth,
|
||||
letter: Letter,
|
||||
) -> Result<String, Custom<String>> {
|
||||
let candidate: entity::candidate::Model = session.into();
|
||||
|
||||
let candidate = CandidateService::add_portfolio_letter(candidate.application, letter.into()).await;
|
||||
|
||||
if candidate.is_err() {
|
||||
// TODO cleanup
|
||||
let e = candidate.err().unwrap();
|
||||
return Err(Custom(
|
||||
Status::from_code(e.code()).unwrap_or_default(),
|
||||
e.message(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok("Letter added".to_string())
|
||||
}
|
||||
|
||||
#[post("/portfolio", data = "<portfolio>")]
|
||||
pub async fn upload_portfolio_zip(
|
||||
session: CandidateAuth,
|
||||
portfolio: Portfolio,
|
||||
) -> Result<String, Custom<String>> {
|
||||
let candidate: entity::candidate::Model = session.into();
|
||||
|
||||
let candidate = CandidateService::add_portfolio_zip(candidate.application, portfolio.into()).await;
|
||||
|
||||
if candidate.is_err() {
|
||||
// TODO cleanup
|
||||
let e = candidate.err().unwrap();
|
||||
return Err(Custom(
|
||||
Status::from_code(e.code()).unwrap_or_default(),
|
||||
e.message(),
|
||||
));
|
||||
}
|
||||
|
||||
Ok("Letter added".to_string())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,7 +67,9 @@ impl EncryptedUserDetails {
|
|||
}
|
||||
}
|
||||
|
||||
fn extract_enc_candidate_details(candidate: candidate::Model) -> Result<UserDetails, ServiceError> {
|
||||
fn extract_enc_candidate_details(
|
||||
candidate: candidate::Model,
|
||||
) -> Result<UserDetails, ServiceError> {
|
||||
let ( // TODO: simplify??
|
||||
Some(name),
|
||||
Some(surname),
|
||||
|
|
@ -152,20 +154,18 @@ impl EncryptedUserDetails {
|
|||
panic!("Failed to encrypt user details"); // TODO
|
||||
};
|
||||
|
||||
Ok(
|
||||
UserDetails {
|
||||
name,
|
||||
surname,
|
||||
birthplace,
|
||||
// birthdate: NaiveDate::from_ymd(2000, 1, 1),
|
||||
address,
|
||||
telephone,
|
||||
citizenship,
|
||||
email,
|
||||
sex,
|
||||
study,
|
||||
}
|
||||
)
|
||||
Ok(UserDetails {
|
||||
name,
|
||||
surname,
|
||||
birthplace,
|
||||
// birthdate: NaiveDate::from_ymd(2000, 1, 1),
|
||||
address,
|
||||
telephone,
|
||||
citizenship,
|
||||
email,
|
||||
sex,
|
||||
study,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -183,7 +183,6 @@ pub struct UserDetails {
|
|||
pub study: String,
|
||||
}
|
||||
|
||||
|
||||
pub struct CandidateService;
|
||||
|
||||
impl CandidateService {
|
||||
|
|
@ -259,13 +258,9 @@ impl CandidateService {
|
|||
|
||||
let enc_details = EncryptedUserDetails::encrypt_form(form, recipients).await;
|
||||
|
||||
Mutation::add_candidate_details(
|
||||
db,
|
||||
user,
|
||||
enc_details,
|
||||
)
|
||||
.await
|
||||
.map_err(|_| ServiceError::DbError)
|
||||
Mutation::add_candidate_details(db, user, enc_details)
|
||||
.await
|
||||
.map_err(|_| ServiceError::DbError)
|
||||
}
|
||||
|
||||
pub async fn decrypt_details(
|
||||
|
|
@ -282,18 +277,36 @@ impl CandidateService {
|
|||
match crypto::verify_password((&password).to_string(), candidate.code.clone()).await {
|
||||
Ok(valid) => {
|
||||
if !valid {
|
||||
return Err(ServiceError::InvalidCredentials)
|
||||
return Err(ServiceError::InvalidCredentials);
|
||||
}
|
||||
},
|
||||
Err(_) => {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 dec_priv_key = crypto::decrypt_password(candidate.private_key.clone(), password)
|
||||
.await
|
||||
.ok()
|
||||
.unwrap();
|
||||
let enc_details = EncryptedUserDetails::from_model(candidate)?;
|
||||
|
||||
enc_details.decrypt(dec_priv_key).await
|
||||
}
|
||||
|
||||
pub async fn add_cover_letter(candidate_id: i32, letter: Vec<u8>) -> Result<(), ServiceError> {
|
||||
// TODO
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_portfolio_letter(candidate_id: i32, letter: Vec<u8>) -> Result<(), ServiceError> {
|
||||
// TODO
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn add_portfolio_zip(candidate_id: i32, zip: Vec<u8>) -> Result<(), ServiceError> {
|
||||
// TODO
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn login(
|
||||
db: &DbConn,
|
||||
user_id: i32,
|
||||
|
|
@ -326,10 +339,13 @@ impl CandidateService {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use sea_orm::{Database, DbConn};
|
||||
use entity::candidate::Model;
|
||||
use sea_orm::{Database, DbConn};
|
||||
|
||||
use crate::{crypto, services::candidate_service::{CandidateService, UserDetails}};
|
||||
use crate::{
|
||||
crypto,
|
||||
services::candidate_service::{CandidateService, UserDetails},
|
||||
};
|
||||
|
||||
use super::EncryptedUserDetails;
|
||||
|
||||
|
|
@ -398,7 +414,6 @@ mod tests {
|
|||
assert_eq!(secret_message, decrypted_message);
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
async fn put_user_data(db: &DbConn) -> Model {
|
||||
let plain_text_password = "test".to_string();
|
||||
|
|
@ -419,7 +434,10 @@ mod tests {
|
|||
sex: "test".to_string(),
|
||||
study: "test".to_string(),
|
||||
};
|
||||
CandidateService::add_user_details(&db, candidate, form).await.ok().unwrap()
|
||||
CandidateService::add_user_details(&db, candidate, form)
|
||||
.await
|
||||
.ok()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
|
|
@ -438,7 +456,11 @@ mod tests {
|
|||
let dec_priv_key = crypto::decrypt_password(enc_candidate.private_key.clone(), password)
|
||||
.await
|
||||
.unwrap();
|
||||
let dec_candidate = EncryptedUserDetails::from_model(enc_candidate).unwrap().decrypt(dec_priv_key).await.unwrap();
|
||||
let dec_candidate = EncryptedUserDetails::from_model(enc_candidate)
|
||||
.unwrap()
|
||||
.decrypt(dec_priv_key)
|
||||
.await
|
||||
.unwrap();
|
||||
|
||||
assert_eq!(dec_candidate.name, "test");
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue