Portfolio/api/src/lib.rs
2022-12-16 12:14:16 +01:00

184 lines
5.2 KiB
Rust

#[macro_use]
extern crate rocket;
use logging::Logging;
use rocket::fairing::{self, AdHoc, Fairing, Info, Kind};
use rocket::http::Header;
use rocket::{Build, Request, Response, Rocket};
use migration::MigratorTrait;
use sea_orm_rocket::Database;
mod guards;
mod pool;
mod requests;
mod routes;
mod logging;
pub mod test;
use pool::Db;
pub use entity::candidate;
pub use entity::candidate::Entity as Candidate;
struct CORS;
#[rocket::async_trait]
impl Fairing for CORS {
fn info(&self) -> Info {
Info {
name: "Add CORS headers to responses",
kind: Kind::Response,
}
}
#[cfg(debug_assertions)]
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new(
"Access-Control-Allow-Origin",
"http://localhost:5173",
));
response.set_header(Header::new(
"Access-Control-Allow-Methods",
"POST, GET, OPTIONS, DELETE",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "content-type"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
#[cfg(not(debug_assertions))]
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
response.set_header(Header::new(
"Access-Control-Allow-Origin",
"https://portfolio.ssps.cz", // TODO: UPRAVIT NA PRODUKČNÍ URL!!
));
response.set_header(Header::new(
"Access-Control-Allow-Methods",
"POST, GET, OPTIONS, DELETE",
));
response.set_header(Header::new("Access-Control-Allow-Headers", "content-type"));
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
}
}
#[options("/<_..>")]
fn all_options() {
/* Intentionally left empty */
}
#[get("/hello")]
async fn hello() -> &'static str {
"Hello, world!"
}
fn setup_logger() -> Result<(), fern::InitError> {
fern::Dispatch::new()
.format(|out, message, record| {
out.finish(format_args!(
"{}[{}][{}] {}",
chrono::Local::now().format("[%Y-%m-%d][%H:%M:%S]"),
record.target(),
record.level(),
message
))
})
.filter(|m| m.target() != "_" && m.target() != "rocket::server") // suppress rocket.rs messages
.level(::log::LevelFilter::Info)
.chain(std::io::stdout())
.chain(fern::log_file("output.log")?)
.apply()?;
Ok(())
}
async fn run_migrations(rocket: Rocket<Build>) -> fairing::Result {
let conn = &Db::fetch(&rocket).unwrap().conn;
let _ = migration::Migrator::up(conn, None).await;
Ok(rocket)
}
pub fn rocket() -> Rocket<Build> {
rocket::build()
.attach(Logging)
.attach(CORS)
.attach(Db::init())
.attach(AdHoc::try_on_ignite("Migrations", run_migrations))
.mount("/", routes![hello, all_options])
.mount(
"/candidate/",
routes![
routes::candidate::login,
routes::candidate::logout,
routes::candidate::whoami,
routes::candidate::get_details,
routes::candidate::post_details,
],
)
.mount(
"/candidate/add",
routes![
routes::candidate::upload_portfolio_letter,
routes::candidate::upload_portfolio_zip,
routes::candidate::upload_cover_letter,
],
)
.mount(
"/candidate/remove",
routes![
routes::candidate::delete_portfolio_letter,
routes::candidate::delete_portfolio_zip,
routes::candidate::delete_cover_letter,
],
)
.mount(
"/candidate/portfolio",
routes![
routes::candidate::submit_portfolio,
routes::candidate::submission_progress,
routes::candidate::download_portfolio,
routes::candidate::delete_portfolio,
],
)
.mount(
"/admin/",
routes![
routes::admin::login,
routes::admin::logout,
routes::admin::whoami,
routes::admin::hello,
routes::admin::create_candidate,
routes::admin::get_candidate,
routes::admin::reset_candidate_password,
routes::admin::get_candidate_portfolio,
routes::admin::delete_candidate,
],
)
.mount(
"/admin/list",
routes![
routes::admin::list_candidates,
routes::admin::list_candidates_csv,
]
)
.register("/", catchers![])
}
#[tokio::main]
async fn start() -> Result<(), rocket::Error> {
let result = setup_logger();
if let Some(err) = result.err() {
panic!("Error: {}", err);
}
rocket().launch().await.map(|_| ())
}
pub fn main() {
let result = start();
println!("Rocket: deorbit.");
if let Some(err) = result.err() {
println!("Error: {}", err);
}
}