#[macro_use] extern crate rocket; #[macro_use] extern crate diesel_migrations; use figment::{ providers::{Env, Format, Yaml}, Figment, }; use rb::{auth::JwtConf, errors::RbError}; use rb_gw::db; use rocket::{ fairing::AdHoc, http::Status, serde::json::{json, Value}, Build, Request, Rocket, }; use rocket_sync_db_pools::database; use serde::{Deserialize, Serialize}; use proxy::ProxyServer; pub mod v1; mod proxy; #[database("postgres_rb")] pub struct RbDbConn(diesel::PgConnection); #[catch(default)] fn default_catcher(status: Status, _: &Request) -> Value { json!({"status": status.code, "message": ""}) } embed_migrations!(); async fn run_db_migrations(rocket: Rocket) -> Result, Rocket> { 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 } async fn create_admin_user(rocket: Rocket) -> Result, Rocket> { let admin = rocket.state::().expect("admin config"); let conn = RbDbConn::get_one(&rocket) .await .expect("database connection"); let new_user = db::NewUser { username: admin.username.clone(), password: admin.password.clone(), admin: true, }; match conn .run(move |c| db::users::create_or_update(c, new_user)) .await { Ok(_) => Ok(rocket), Err(RbError::UMDuplicateUser) => Ok(rocket), Err(_) => Err(rocket), } } #[derive(Debug, Deserialize, Serialize)] pub struct AdminConfig { username: String, password: String, } #[derive(Debug, Deserialize, Serialize)] pub struct RbConfig { admin: AdminConfig, jwt: JwtConf, } #[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, )) // .attach(AdHoc::try_on_ignite("Create admin user", create_admin_user)) .attach(AdHoc::config::()) .register("/", catchers![default_catcher]) .mount( "/v1/auth", routes![ v1::auth::already_logged_in, v1::auth::login, v1::auth::refresh_token, ], ).mount("/v1/posts", ProxyServer::from("http://localhost:8000/v1/posts")); // This let's the guards properly access the JWT credentials when needed let new_figment = rocket.figment(); let jwt_conf: JwtConf = new_figment.extract_inner("jwt").expect("jwt config"); // We do the same thing here so we can access the admin credentials for initially creating the // admin user let admin_conf: AdminConfig = new_figment.extract_inner("admin").expect("admin config"); rocket .manage(jwt_conf) .manage(admin_conf) .attach(AdHoc::try_on_ignite("Create admin user", create_admin_user)) }