mirror of
https://github.com/danbulant/Portfolio
synced 2026-05-24 12:35:31 +00:00
Merge pull request #54 from EETagent/rework_api_tests
This commit is contained in:
commit
c4092c3d29
12 changed files with 340 additions and 48 deletions
2
Cargo.lock
generated
2
Cargo.lock
generated
|
|
@ -1981,9 +1981,11 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-stream",
|
"async-stream",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
|
"chrono",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"futures",
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
|
"once_cell",
|
||||||
"portfolio-core",
|
"portfolio-core",
|
||||||
"portfolio-entity",
|
"portfolio-entity",
|
||||||
"portfolio-migration",
|
"portfolio-migration",
|
||||||
|
|
|
||||||
|
|
@ -20,9 +20,15 @@ dotenv = "^0.15"
|
||||||
|
|
||||||
serde_json = { version = "^1.0" }
|
serde_json = { version = "^1.0" }
|
||||||
|
|
||||||
|
chrono = "^0.4"
|
||||||
|
|
||||||
portfolio-entity = { path = "../entity" }
|
portfolio-entity = { path = "../entity" }
|
||||||
portfolio-migration = { path = "../migration" }
|
portfolio-migration = { path = "../migration" }
|
||||||
portfolio-core = { path = "../core" }
|
portfolio-core = { path = "../core" }
|
||||||
|
|
||||||
[dependencies.sea-orm-rocket]
|
[dependencies.sea-orm-rocket]
|
||||||
version = "^0.5"
|
version = "^0.5"
|
||||||
|
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
once_cell = "1.9.0"
|
||||||
|
|
@ -12,6 +12,7 @@ mod guards;
|
||||||
mod pool;
|
mod pool;
|
||||||
mod requests;
|
mod requests;
|
||||||
mod routes;
|
mod routes;
|
||||||
|
pub mod test;
|
||||||
|
|
||||||
use pool::Db;
|
use pool::Db;
|
||||||
|
|
||||||
|
|
@ -29,8 +30,7 @@ async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {
|
||||||
Ok(rocket)
|
Ok(rocket)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::main]
|
pub fn rocket() -> Rocket<Build>{
|
||||||
async fn start() -> Result<(), rocket::Error> {
|
|
||||||
rocket::build()
|
rocket::build()
|
||||||
.attach(Db::init())
|
.attach(Db::init())
|
||||||
.attach(AdHoc::try_on_ignite("Migrations", run_migrations))
|
.attach(AdHoc::try_on_ignite("Migrations", run_migrations))
|
||||||
|
|
@ -81,6 +81,11 @@ async fn start() -> Result<(), rocket::Error> {
|
||||||
routes::admin::list_candidates,
|
routes::admin::list_candidates,
|
||||||
])
|
])
|
||||||
.register("/", catchers![])
|
.register("/", catchers![])
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn start() -> Result<(), rocket::Error> {
|
||||||
|
rocket()
|
||||||
.launch()
|
.launch()
|
||||||
.await
|
.await
|
||||||
.map(|_| ())
|
.map(|_| ())
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,9 @@
|
||||||
use portfolio_core::sea_orm;
|
use portfolio_core::{sea_orm::{self}};
|
||||||
|
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
|
#[cfg(not(test))]
|
||||||
use sea_orm::ConnectOptions;
|
use sea_orm::ConnectOptions;
|
||||||
use sea_orm_rocket::{rocket::figment::Figment, Database};
|
use sea_orm_rocket::{rocket::figment::Figment, Database};
|
||||||
|
#[cfg(not(test))]
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
#[derive(Database, Debug)]
|
#[derive(Database, Debug)]
|
||||||
|
|
@ -20,8 +21,17 @@ impl sea_orm_rocket::Pool for SeaOrmPool {
|
||||||
|
|
||||||
type Connection = sea_orm::DatabaseConnection;
|
type Connection = sea_orm::DatabaseConnection;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
async fn init(_figment: &Figment) -> Result<Self, Self::Error> {
|
||||||
|
let conn = portfolio_core::util::get_memory_sqlite_connection().await;
|
||||||
|
crate::test::tests::run_test_migrations(&conn).await;
|
||||||
|
return Ok(Self { conn });
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(not(test))]
|
||||||
async fn init(_figment: &Figment) -> Result<Self, Self::Error> {
|
async fn init(_figment: &Figment) -> Result<Self, Self::Error> {
|
||||||
dotenv::dotenv().ok();
|
dotenv::dotenv().ok();
|
||||||
|
|
||||||
let database_url = std::env::var("DATABASE_URL").unwrap();
|
let database_url = std::env::var("DATABASE_URL").unwrap();
|
||||||
let mut options: ConnectOptions = database_url.into();
|
let mut options: ConnectOptions = database_url.into();
|
||||||
options
|
options
|
||||||
|
|
@ -36,6 +46,7 @@ impl sea_orm_rocket::Pool for SeaOrmPool {
|
||||||
if let Some(idle_timeout) = config.idle_timeout {
|
if let Some(idle_timeout) = config.idle_timeout {
|
||||||
options.idle_timeout(Duration::from_secs(idle_timeout));
|
options.idle_timeout(Duration::from_secs(idle_timeout));
|
||||||
} */
|
} */
|
||||||
|
|
||||||
let conn = sea_orm::Database::connect(options).await?;
|
let conn = sea_orm::Database::connect(options).await?;
|
||||||
|
|
||||||
Ok(SeaOrmPool { conn })
|
Ok(SeaOrmPool { conn })
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::{SocketAddr, IpAddr, Ipv4Addr};
|
||||||
|
|
||||||
use portfolio_core::{
|
use portfolio_core::{
|
||||||
crypto::random_8_char_string,
|
crypto::random_8_char_string,
|
||||||
|
|
@ -17,9 +17,10 @@ use crate::{guards::request::auth::AdminAuth, pool::Db, requests};
|
||||||
pub async fn login(
|
pub async fn login(
|
||||||
conn: Connection<'_, Db>,
|
conn: Connection<'_, Db>,
|
||||||
login_form: Json<AdminLoginRequest>,
|
login_form: Json<AdminLoginRequest>,
|
||||||
ip_addr: SocketAddr,
|
// ip_addr: SocketAddr, // TODO uncomment in production
|
||||||
cookies: &CookieJar<'_>,
|
cookies: &CookieJar<'_>,
|
||||||
) -> Result<String, Custom<String>> {
|
) -> Result<String, Custom<String>> {
|
||||||
|
let ip_addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
|
||||||
let db = conn.into_inner();
|
let db = conn.into_inner();
|
||||||
let session_token_key = AdminService::login(
|
let session_token_key = AdminService::login(
|
||||||
db,
|
db,
|
||||||
|
|
@ -156,3 +157,62 @@ pub async fn get_candidate_portfolio(
|
||||||
|
|
||||||
Ok(portfolio)
|
Ok(portfolio)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use rocket::{local::blocking::Client, http::{Cookie, Status}};
|
||||||
|
|
||||||
|
use crate::test::tests::{test_client, ADMIN_PASSWORD, ADMIN_ID};
|
||||||
|
|
||||||
|
pub fn admin_login(client: &Client) -> (Cookie, Cookie) {
|
||||||
|
let response = client
|
||||||
|
.post("/admin/login")
|
||||||
|
.body(format!(
|
||||||
|
"{{
|
||||||
|
\"admin_id\": {},
|
||||||
|
\"password\": \"{}\"
|
||||||
|
}}",
|
||||||
|
ADMIN_ID, ADMIN_PASSWORD
|
||||||
|
))
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
println!("{:?}", response);
|
||||||
|
(
|
||||||
|
response.cookies().get("id").unwrap().to_owned(),
|
||||||
|
response.cookies().get("key").unwrap().to_owned(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_candidate(
|
||||||
|
client: &Client,
|
||||||
|
cookies: (Cookie, Cookie),
|
||||||
|
id: i32,
|
||||||
|
pid: String,
|
||||||
|
) -> String {
|
||||||
|
let response = client
|
||||||
|
.post("/admin/create")
|
||||||
|
.body(format!(
|
||||||
|
"{{
|
||||||
|
\"application_id\": {},
|
||||||
|
\"personal_id_number\": \"{}\"
|
||||||
|
}}",
|
||||||
|
id, pid
|
||||||
|
))
|
||||||
|
.cookie(cookies.0)
|
||||||
|
.cookie(cookies.1)
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
||||||
|
response.into_string().unwrap()
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_create_candidate() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
let cookies = admin_login(&client);
|
||||||
|
let password = create_candidate(&client, cookies, 1031511, "0".to_string());
|
||||||
|
|
||||||
|
assert_eq!(password.len(), 8);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use std::net::SocketAddr;
|
use std::net::{IpAddr, Ipv4Addr, SocketAddr};
|
||||||
|
|
||||||
use portfolio_core::candidate_details::ApplicationDetails;
|
use portfolio_core::candidate_details::ApplicationDetails;
|
||||||
use portfolio_core::services::application_service::ApplicationService;
|
use portfolio_core::services::application_service::ApplicationService;
|
||||||
|
|
@ -19,9 +19,10 @@ use crate::{guards::request::auth::CandidateAuth, pool::Db, requests};
|
||||||
pub async fn login(
|
pub async fn login(
|
||||||
conn: Connection<'_, Db>,
|
conn: Connection<'_, Db>,
|
||||||
login_form: Json<LoginRequest>,
|
login_form: Json<LoginRequest>,
|
||||||
ip_addr: SocketAddr,
|
// ip_addr: SocketAddr, // TODO uncomment in production
|
||||||
cookies: &CookieJar<'_>,
|
cookies: &CookieJar<'_>,
|
||||||
) -> Result<String, Custom<String>> {
|
) -> Result<String, Custom<String>> {
|
||||||
|
let ip_addr: SocketAddr = SocketAddr::new(IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)), 0);
|
||||||
let db = conn.into_inner();
|
let db = conn.into_inner();
|
||||||
let session_token_key = CandidateService::login(
|
let session_token_key = CandidateService::login(
|
||||||
db,
|
db,
|
||||||
|
|
@ -84,18 +85,14 @@ pub async fn add_details(
|
||||||
#[post("/get_details")]
|
#[post("/get_details")]
|
||||||
pub async fn get_details(
|
pub async fn get_details(
|
||||||
conn: Connection<'_, Db>,
|
conn: Connection<'_, Db>,
|
||||||
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 private_key = session.get_private_key();
|
||||||
let candidate: entity::candidate::Model = session.into();
|
let candidate: entity::candidate::Model = session.into();
|
||||||
|
|
||||||
|
|
||||||
// let handle = tokio::spawn(async move {
|
// let handle = tokio::spawn(async move {
|
||||||
let details = ApplicationService::decrypt_all_details(private_key,
|
let details = ApplicationService::decrypt_all_details(private_key, db, candidate.application)
|
||||||
db,
|
|
||||||
candidate.application
|
|
||||||
)
|
|
||||||
.await
|
.await
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
Custom(
|
Custom(
|
||||||
|
|
@ -303,3 +300,157 @@ pub async fn download_portfolio(session: CandidateAuth) -> Result<Vec<u8>, Custo
|
||||||
|
|
||||||
Ok(file.unwrap())
|
Ok(file.unwrap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use portfolio_core::{candidate_details::ApplicationDetails, crypto, sea_orm::prelude::Uuid};
|
||||||
|
use rocket::{
|
||||||
|
http::{Cookie, Status},
|
||||||
|
local::blocking::Client,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::{test::tests::{test_client, APPLICATION_ID, CANDIDATE_PASSWORD}, routes::admin::tests::admin_login};
|
||||||
|
|
||||||
|
fn candidate_login(client: &Client) -> (Cookie, Cookie) {
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/login")
|
||||||
|
.body(format!(
|
||||||
|
"{{
|
||||||
|
\"application_id\": {},
|
||||||
|
\"password\": \"{}\"
|
||||||
|
}}",
|
||||||
|
APPLICATION_ID, CANDIDATE_PASSWORD
|
||||||
|
))
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
(
|
||||||
|
response.cookies().get("id").unwrap().to_owned(),
|
||||||
|
response.cookies().get("key").unwrap().to_owned(),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const CANDIDATE_DETAILS: &'static str = "{
|
||||||
|
\"name\": \"idk\",
|
||||||
|
\"surname\": \"idk\",
|
||||||
|
\"birthplace\": \"Praha 1\",
|
||||||
|
\"birthdate\": \"2015-09-18\",
|
||||||
|
\"address\": \"Stefanikova jidelna\",
|
||||||
|
\"telephone\": \"000111222333\",
|
||||||
|
\"citizenship\": \"Czech Republic\",
|
||||||
|
\"email\": \"magor@magor.cz\",
|
||||||
|
\"sex\": \"MALE\",
|
||||||
|
\"study\": \"KB\",
|
||||||
|
\"parent_name\": \"maminka\",
|
||||||
|
\"parent_surname\": \"chad\",
|
||||||
|
\"parent_telephone\": \"420111222333\",
|
||||||
|
\"parent_email\": \"maminka@centrum.cz\"
|
||||||
|
}";
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_login_valid_credentials() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
let _response = candidate_login(&client);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_auth_candidate() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
let cookies = candidate_login(&client);
|
||||||
|
let response = client
|
||||||
|
.get("/candidate/whoami")
|
||||||
|
.cookie(cookies.0)
|
||||||
|
.cookie(cookies.1)
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
assert_eq!(response.into_string().unwrap(), APPLICATION_ID.to_string());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_get_candidate_details() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
let cookies = candidate_login(&client);
|
||||||
|
|
||||||
|
let details_orig: ApplicationDetails = serde_json::from_str(CANDIDATE_DETAILS).unwrap();
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/add/details")
|
||||||
|
.cookie(cookies.0.clone())
|
||||||
|
.cookie(cookies.1.clone())
|
||||||
|
.body(CANDIDATE_DETAILS.to_string())
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/get_details")
|
||||||
|
.cookie(cookies.0)
|
||||||
|
.cookie(cookies.1)
|
||||||
|
.dispatch();
|
||||||
|
|
||||||
|
assert_eq!(response.status(), Status::Ok);
|
||||||
|
|
||||||
|
let details_resp: ApplicationDetails =
|
||||||
|
serde_json::from_str(&response.into_string().unwrap()).unwrap();
|
||||||
|
assert_eq!(details_orig, details_resp);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_invalid_token_every_secured_endpoint() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
|
||||||
|
let id = Cookie::new("id", Uuid::new_v4().to_string());
|
||||||
|
let (private_key, _) = crypto::create_identity();
|
||||||
|
let key = Cookie::new("key", private_key);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/add/details")
|
||||||
|
.cookie(id.clone())
|
||||||
|
.cookie(key.clone())
|
||||||
|
.body(CANDIDATE_DETAILS.to_string())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/get_details")
|
||||||
|
.cookie(id.clone())
|
||||||
|
.cookie(key.clone())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.get("/candidate/whoami")
|
||||||
|
.cookie(id.clone())
|
||||||
|
.cookie(key.clone())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_admin_token_on_secured_candidate_endpoints() {
|
||||||
|
let client = test_client().lock().unwrap();
|
||||||
|
let cookies = admin_login(&client);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/add/details")
|
||||||
|
.cookie(cookies.0.clone())
|
||||||
|
.cookie(cookies.1.clone())
|
||||||
|
.body(CANDIDATE_DETAILS.to_string())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.post("/candidate/get_details")
|
||||||
|
.cookie(cookies.0.clone())
|
||||||
|
.cookie(cookies.1.clone())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
|
||||||
|
let response = client
|
||||||
|
.get("/candidate/whoami")
|
||||||
|
.cookie(cookies.0.clone())
|
||||||
|
.cookie(cookies.1.clone())
|
||||||
|
.dispatch();
|
||||||
|
assert_eq!(response.status(), Status::Unauthorized);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
62
api/src/test.rs
Normal file
62
api/src/test.rs
Normal file
|
|
@ -0,0 +1,62 @@
|
||||||
|
#[cfg(test)]
|
||||||
|
pub mod tests {
|
||||||
|
use crate::rocket;
|
||||||
|
use entity::admin;
|
||||||
|
use once_cell::sync::OnceCell;
|
||||||
|
use portfolio_core::{
|
||||||
|
crypto,
|
||||||
|
sea_orm::{ActiveModelTrait, DbConn, Set},
|
||||||
|
services::application_service::ApplicationService,
|
||||||
|
};
|
||||||
|
use rocket::{
|
||||||
|
local::blocking::Client,
|
||||||
|
};
|
||||||
|
use std::sync::Mutex;
|
||||||
|
|
||||||
|
pub const ADMIN_ID: i32 = 1;
|
||||||
|
pub const ADMIN_PASSWORD: &'static str = "test";
|
||||||
|
|
||||||
|
pub const APPLICATION_ID: i32 = 103151;
|
||||||
|
pub const CANDIDATE_PASSWORD: &'static str = "test";
|
||||||
|
pub const PERSONAL_ID_NUMBER: &'static str = "0101010000";
|
||||||
|
|
||||||
|
pub async fn run_test_migrations(db: &DbConn) {
|
||||||
|
let (pubkey, priv_key) = crypto::create_identity();
|
||||||
|
let priv_key = crypto::encrypt_password(priv_key, ADMIN_PASSWORD.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
let password_hash = crypto::hash_password(ADMIN_PASSWORD.to_string())
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
admin::ActiveModel {
|
||||||
|
id: Set(ADMIN_ID),
|
||||||
|
name: Set("admin pepa".to_string()),
|
||||||
|
public_key: Set(pubkey),
|
||||||
|
private_key: Set(priv_key),
|
||||||
|
password: Set(password_hash),
|
||||||
|
created_at: Set(chrono::Utc::now().naive_utc()),
|
||||||
|
updated_at: Set(chrono::Utc::now().naive_utc()),
|
||||||
|
}
|
||||||
|
.insert(db)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
|
ApplicationService::create_candidate_with_parent(
|
||||||
|
db,
|
||||||
|
APPLICATION_ID,
|
||||||
|
&CANDIDATE_PASSWORD.to_string(),
|
||||||
|
PERSONAL_ID_NUMBER.to_string(),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn test_client() -> &'static Mutex<Client> {
|
||||||
|
static INSTANCE: OnceCell<Mutex<Client>> = OnceCell::new();
|
||||||
|
INSTANCE.get_or_init(|| {
|
||||||
|
let rocket = rocket();
|
||||||
|
Mutex::from(Client::tracked(rocket).expect("valid rocket instance"))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -185,7 +185,7 @@ impl TryFrom<(candidate::Model, parent::Model)> for EncryptedApplicationDetails
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug, Serialize, Deserialize)]
|
#[derive(Debug, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct ApplicationDetails {
|
pub struct ApplicationDetails {
|
||||||
// Candidate
|
// Candidate
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ pub enum ServiceError {
|
||||||
InvalidApplicationId,
|
InvalidApplicationId,
|
||||||
#[error("Invalid credentials")]
|
#[error("Invalid credentials")]
|
||||||
InvalidCredentials,
|
InvalidCredentials,
|
||||||
|
#[error("Unauthorized")]
|
||||||
|
Unauthorized,
|
||||||
#[error("Forbidden")]
|
#[error("Forbidden")]
|
||||||
Forbidden,
|
Forbidden,
|
||||||
#[error("Session expired, please login agai")]
|
#[error("Session expired, please login agai")]
|
||||||
|
|
@ -65,6 +67,7 @@ impl ServiceError {
|
||||||
match self {
|
match self {
|
||||||
ServiceError::InvalidApplicationId => 400,
|
ServiceError::InvalidApplicationId => 400,
|
||||||
ServiceError::InvalidCredentials => 401,
|
ServiceError::InvalidCredentials => 401,
|
||||||
|
ServiceError::Unauthorized => 401,
|
||||||
ServiceError::Forbidden => 403,
|
ServiceError::Forbidden => 403,
|
||||||
ServiceError::ExpiredSession => 401,
|
ServiceError::ExpiredSession => 401,
|
||||||
ServiceError::JwtError => 500,
|
ServiceError::JwtError => 500,
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ impl AdminService {
|
||||||
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),
|
||||||
AdminUser::Candidate(_) => unreachable!(),
|
AdminUser::Candidate(_) => Err(ServiceError::Unauthorized),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -215,7 +215,7 @@ impl CandidateService {
|
||||||
match SessionService::auth_user_session(db, session_uuid).await {
|
match SessionService::auth_user_session(db, session_uuid).await {
|
||||||
Ok(user) => match user {
|
Ok(user) => match user {
|
||||||
AdminUser::Candidate(candidate) => Ok(candidate),
|
AdminUser::Candidate(candidate) => Ok(candidate),
|
||||||
AdminUser::Admin(_) => unreachable!(),
|
AdminUser::Admin(_) => Err(ServiceError::Unauthorized),
|
||||||
},
|
},
|
||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,9 @@
|
||||||
#[cfg(test)]
|
|
||||||
pub async fn get_memory_sqlite_connection() -> sea_orm::DbConn {
|
|
||||||
use entity::{admin, candidate, parent, session};
|
use entity::{admin, candidate, parent, session};
|
||||||
use sea_orm::{Schema, Database, DbConn};
|
use sea_orm::{Schema, Database, DbConn};
|
||||||
use sea_orm::{sea_query::TableCreateStatement, ConnectionTrait, DbBackend};
|
use sea_orm::{sea_query::TableCreateStatement, ConnectionTrait, DbBackend};
|
||||||
|
|
||||||
|
|
||||||
|
pub async fn get_memory_sqlite_connection() -> sea_orm::DbConn {
|
||||||
let base_url = "sqlite::memory:";
|
let base_url = "sqlite::memory:";
|
||||||
let db: DbConn = Database::connect(base_url).await.unwrap();
|
let db: DbConn = Database::connect(base_url).await.unwrap();
|
||||||
|
|
||||||
|
|
@ -12,18 +12,10 @@ pub async fn get_memory_sqlite_connection() -> sea_orm::DbConn {
|
||||||
let stmt2: TableCreateStatement = schema.create_table_from_entity(admin::Entity);
|
let stmt2: TableCreateStatement = schema.create_table_from_entity(admin::Entity);
|
||||||
let stmt3: TableCreateStatement = schema.create_table_from_entity(session::Entity);
|
let stmt3: TableCreateStatement = schema.create_table_from_entity(session::Entity);
|
||||||
let stmt4: TableCreateStatement = schema.create_table_from_entity(parent::Entity);
|
let stmt4: TableCreateStatement = schema.create_table_from_entity(parent::Entity);
|
||||||
db.execute(db.get_database_backend().build(&stmt))
|
db.execute(db.get_database_backend().build(&stmt)).await.unwrap();
|
||||||
.await
|
db.execute(db.get_database_backend().build(&stmt2)).await.unwrap();
|
||||||
.unwrap();
|
db.execute(db.get_database_backend().build(&stmt3)).await.unwrap();
|
||||||
db.execute(db.get_database_backend().build(&stmt2))
|
db.execute(db.get_database_backend().build(&stmt4)).await.unwrap();
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
db.execute(db.get_database_backend().build(&stmt3))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
db.execute(db.get_database_backend().build(&stmt4))
|
|
||||||
.await
|
|
||||||
.unwrap();
|
|
||||||
db
|
db
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue