#[macro_use] extern crate diesel; #[macro_use] extern crate diesel_migrations; use actix::prelude::*; use actix_web::middleware::{errhandlers::ErrorHandlers, Logger}; use actix_identity::{CookieIdentityPolicy, IdentityService}; use actix_web::{http, web, App, HttpServer}; use chrono::Duration; use diesel::mysql::MysqlConnection; use dotenv::dotenv; use r2d2_diesel::ConnectionManager; mod public; mod error; mod error_handlers; mod schema; mod model; use crate::model::DbExecutor; embed_migrations!(); pub struct Secret(String); #[actix_rt::main] async fn main() -> std::io::Result<()> { dotenv().ok(); std::env::set_var( "RUST_LOG", "rgit=debug,actix_web=trace,actix_server=debug", ); env_logger::init(); let bind_host: String = std::env::var("BIND_HOST").unwrap_or_else(|_| "127.0.0.1:8000".to_string()); let database_url = std::env::var("DATABASE_URL").expect("DATABASE_URL must be set"); let manager = ConnectionManager::::new(database_url); let pool = r2d2::Pool::builder() .build(manager) .expect("Can to build connection pool"); embedded_migrations::run(&*pool.get().expect("Can connect to mysql")) .expect("Can run migrations"); let db_addr: Addr = SyncArbiter::start(4, move || DbExecutor(pool.clone())); HttpServer::new(move || { let secret: String = std::env::var("SECRET_KEY").expect("SECRET_KEY env var should be set"); let domain: String = std::env::var("DOMAIN").unwrap_or_else(|_| "localhost".to_string()); let secure_cookies = &domain != "localhost"; let error_handlers = ErrorHandlers::new() .handler( http::StatusCode::INTERNAL_SERVER_ERROR, error_handlers::internal_server_error, ) .handler(http::StatusCode::BAD_REQUEST, error_handlers::bad_request) .handler(http::StatusCode::NOT_FOUND, error_handlers::not_found); App::new() .data(db_addr.clone()) .data(Secret(secret.clone())) .wrap(error_handlers) .wrap(IdentityService::new( CookieIdentityPolicy::new(secret.as_bytes()) .name("rgit-session") .domain(domain.as_str()) .max_age_time(Duration::days(30)) .secure(secure_cookies), // this has to reflect the usage of https )) .wrap(Logger::default()) .route("/", web::get().to(public::index)) .service(actix_files::Files::new("/static", "static/")) }) .bind(&bind_host)? .run() .await?; Ok(()) }