#[macro_use] extern crate rocket; #[macro_use] extern crate diesel_migrations; use figment::{ providers::{Env, Format, Yaml}, Figment, }; use rb::auth::JwtConf; use rocket::{ fairing::AdHoc, http::Status, serde::json::{json, Value}, Build, Request, Rocket, }; use rocket_sync_db_pools::database; use serde::{Deserialize, Serialize}; pub mod v1; /// This function just returns a pre-built rocket header containing a valid JWT for the secret /// "secret", valid until 2034 or something. It's easy for testing the API. #[cfg(test)] pub fn auth_header() -> rocket::http::Header<'static> { return rocket::http::Header::new("Authorization", "Bearer eyJhbGciOiJIUzI1NiJ9.eyJpZCI6IjVjMjM2OTI0NjY4ZDQzZWFiNGNmNDczYjk1YWZiNzgzIiwidXNlcm5hbWUiOiJKb2huIERvZSIsImFkbWluIjp0cnVlLCJleHAiOjE1MTYyMzkwMjIwfQ.if939L9le8LP-dtXnQs-mHPkb-VieRAvAfSu20755jY"); } /// Used by Rocket to store database connections. #[database("postgres_rb")] pub struct RbDbConn(diesel::PgConnection); /// Handles all error status codes. #[catch(default)] fn default_catcher(status: Status, _: &Request) -> Value { json!({"status": status.code, "message": ""}) } /// Rocket fairing that executes the necessary migrations in our database. async fn run_db_migrations(rocket: Rocket) -> Result, Rocket> { embed_migrations!(); let conn = RbDbConn::get_one(&rocket) .await .expect("database connection"); conn.run(|c| match embedded_migrations::run(c) { Ok(()) => Ok(rocket), Err(_) => Err(rocket), }) .await } /// Struct to deserialize from the config file. It contains any custom configuration our /// application might need besides the default Rocket variables. #[derive(Debug, Deserialize, Serialize)] pub struct RbConfig { jwt: JwtConf, } /// The main entrypoint of our program. It launches the Rocket instance. #[launch] fn rocket() -> _ { let figment = Figment::from(rocket::config::Config::default()) .merge(Yaml::file("Rb.yaml").nested()) .merge(Env::prefixed("RB_").global()); let rocket = rocket::custom(figment) .attach(RbDbConn::fairing()) .attach(AdHoc::try_on_ignite( "Run database migrations", run_db_migrations, )) .register("/", catchers![default_catcher]) .mount( "/v1/sections", routes![ v1::sections::get, v1::sections::create, v1::sections::find, v1::sections::patch, v1::sections::delete ], ) .mount( "/v1/posts", routes![ v1::posts::get, v1::posts::create, v1::posts::find, v1::posts::patch, v1::posts::delete ], ) .mount( "/v1/versions", routes![ v1::versions::get, v1::versions::get_for_post, v1::versions::create, v1::versions::find, v1::versions::patch, v1::versions::delete ], ); let new_figment = rocket.figment(); let jwt_conf: JwtConf = new_figment.extract_inner("jwt").expect("jwt config"); rocket.manage(jwt_conf) }