use actix_web::{App, HttpResponse, HttpServer, post}; use actix_web::web::{Data, Json, JsonConfig}; use diesel::{PgConnection}; use diesel::r2d2::ConnectionManager; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; use log::{error, info, Level}; use r2d2::Pool; use serde::{Serialize, Deserialize}; use crate::config::CONFIG; use crate::error::{APIError, APIErrorResponse}; pub mod config; pub mod error; pub mod models; pub mod schema; pub mod routes; pub mod util; pub mod tokens; pub const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); pub type PgPool = Pool>; #[actix_web::main] async fn main() -> std::io::Result<()> { simple_logger::init_with_level(Level::Debug).unwrap(); info!("Connecting to database at {}...", CONFIG.db_uri); let manager = ConnectionManager::new(&CONFIG.db_uri); let pool: PgPool = match Pool::builder().build(manager) { Ok(c) => c, Err(e) => { error!("Error connecting to database: {}", e); std::process::exit(1); } }; let mut conn = match pool.get() { Ok(c) => c, Err(e) => { error!("Error fetching connection: {}", e); std::process::exit(1); } }; let data = Data::new(pool); info!("Running migrations..."); match conn.run_pending_migrations(MIGRATIONS) { Ok(_) => (), Err(e) => { error!("Error running database migrations: {}", e); std::process::exit(1); } }; HttpServer::new(move || { App::new() .app_data(data.clone()) .app_data(JsonConfig::default().error_handler(|err, _req| { let err2: APIError = (&err).into(); actix_web::error::InternalError::from_response( err, HttpResponse::BadRequest().json(APIErrorResponse { errors: vec![ err2 ], }) ).into() })) .service(routes::v1::code_3fa::get_3fa_code) .service(routes::v1::user_add::add_user_request) .service(routes::v1::user_get::get_user_request) }) .bind(("127.0.0.1", 8080))? .run() .await }