brass/web/src/main.rs

127 lines
3.5 KiB
Rust

use std::env;
use std::time::Duration;
use actix_identity::IdentityMiddleware;
use actix_session::SessionMiddleware;
use actix_web::body::MessageBody;
use actix_web::cookie::Key;
use actix_web::dev::{ServiceFactory, ServiceRequest, ServiceResponse};
use actix_web::{web, App, HttpServer};
use actix_web_static_files::ResourceFiles;
use brass_config::{get_env, load_config, Config};
use chrono::NaiveTime;
use mail::Mailer;
use sqlx::postgres::PgPool;
use sqlx::{Pool, Postgres};
use tracing::info;
use tracing_actix_web::TracingLogger;
use tracing_panic::panic_hook;
use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{fmt, EnvFilter};
use utils::Customization;
use crate::postgres_session_store::SqlxPostgresqlSessionStore;
use crate::utils::manage_commands::{handle_command, parse_args};
mod endpoints;
mod mail;
mod middleware;
mod models;
mod utils;
mod filters;
mod postgres_session_store;
include!(concat!(env!("OUT_DIR"), "/generated.rs"));
include!(concat!(env!("OUT_DIR"), "/built.rs"));
pub const START_OF_DAY: NaiveTime = NaiveTime::from_hms_opt(0, 0, 0).unwrap();
pub const END_OF_DAY: NaiveTime = NaiveTime::from_hms_opt(23, 59, 59).unwrap();
#[actix_web::main]
async fn main() -> anyhow::Result<()> {
let env = get_env()?;
let config: Config = load_config(&env)?;
init_tracing();
let args = parse_args()?;
let pool = PgPool::connect(&config.database_url).await?;
let mailer = Mailer::new(&config)?;
let customization = Customization {
webmaster_email: config.webmaster_email.clone(),
hostname: config.hostname.clone()
};
handle_command(args.command, &pool, &mailer).await?;
let address = config.server_address;
let port = config.server_port;
info!("Starting server on http://{address}:{port}.");
HttpServer::new(move || {
create_app(
config.clone(),
pool.clone(),
mailer.clone(),
customization.clone(),
)
})
.bind((address, port))?
.run()
.await?;
Ok(())
}
pub fn create_app(
config: Config,
pool: Pool<Postgres>,
mailer: Mailer,
customization: Customization,
) -> App<
impl ServiceFactory<
ServiceRequest,
Response = ServiceResponse<impl MessageBody>,
Config = (),
InitError = (),
Error = actix_web::error::Error,
>,
> {
let generated = generate();
let secret_key = Key::from(config.secret_key.as_bytes());
let store = SqlxPostgresqlSessionStore::from_pool(pool.clone().into());
App::new()
.app_data(web::Data::new(pool))
.app_data(web::Data::new(mailer))
.app_data(web::Data::new(customization))
.configure(endpoints::init)
.wrap(middleware::ErrorAppender)
.wrap(TracingLogger::default())
.wrap(middleware::RedirectToLogin)
.wrap(middleware::LoadCurrentUser)
.wrap(
IdentityMiddleware::builder()
.visit_deadline(Some(Duration::from_secs(300)))
.build(),
)
.wrap(SessionMiddleware::new(store.clone(), secret_key.clone()))
.service(ResourceFiles::new("/static", generated))
}
fn init_tracing() {
let filter = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info"))
.unwrap();
tracing_subscriber::registry()
.with(fmt::layer())
.with(filter)
.init();
std::panic::set_hook(Box::new(panic_hook));
}