68 lines
2.4 KiB
Rust
68 lines
2.4 KiB
Rust
|
use std::str::FromStr;
|
||
|
|
||
|
use anyhow::Result;
|
||
|
use axum::{routing::{get, post}, Router};
|
||
|
use axum_login::AuthManagerLayerBuilder;
|
||
|
use clap::Parser;
|
||
|
use sea_orm::Database;
|
||
|
use tower_http::{services::ServeDir, trace::{DefaultOnRequest, DefaultOnResponse, TraceLayer}};
|
||
|
use tower_sessions::SessionManagerLayer;
|
||
|
use tower_sessions_sqlx_store::{sqlx::SqlitePool, SqliteStore};
|
||
|
use tracing::Level;
|
||
|
|
||
|
use crate::{config::CommandLineOptions, context::Context, handler::{home::home_page, login::logout, login_page, login_submit}, logging::setup_logging, templates::make_template_loader};
|
||
|
|
||
|
pub async fn run() -> Result<()> {
|
||
|
dotenvy::dotenv()?;
|
||
|
setup_logging();
|
||
|
|
||
|
let opts = CommandLineOptions::parse();
|
||
|
|
||
|
let template_loader = make_template_loader(opts.reload_templates);
|
||
|
|
||
|
let db_url = dotenvy::var("DATABASE_URL")?;
|
||
|
let db = Database::connect(db_url).await?;
|
||
|
|
||
|
let session_layer = create_session_manager_layer().await?;
|
||
|
|
||
|
let context = Context::new(db, template_loader);
|
||
|
|
||
|
let auth_backend = context.clone();
|
||
|
let auth_layer = AuthManagerLayerBuilder::new(auth_backend, session_layer.clone()).build();
|
||
|
|
||
|
let trace_layer = TraceLayer::new_for_http()
|
||
|
.on_request(DefaultOnRequest::new().level(Level::INFO))
|
||
|
.on_response(DefaultOnResponse::new().level(Level::INFO));
|
||
|
|
||
|
let app = Router::new()
|
||
|
.nest_service("/static", ServeDir::new("static"))
|
||
|
.route("/", get(home_page))
|
||
|
.route("/login", get(login_page))
|
||
|
.route("/login", post(login_submit))
|
||
|
.route("/logout", get(logout))
|
||
|
.layer(trace_layer)
|
||
|
.layer(session_layer)
|
||
|
.layer(auth_layer)
|
||
|
.with_state(context);
|
||
|
|
||
|
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
|
||
|
axum::serve(listener, app).await.unwrap();
|
||
|
|
||
|
Ok(())
|
||
|
}
|
||
|
|
||
|
pub async fn create_session_manager_layer() -> Result<SessionManagerLayer<SqliteStore>> {
|
||
|
let session_db_url =
|
||
|
dotenvy::var("SESSION_DB_URL").unwrap_or("sqlite:./sessions.db?mode=rwc".to_owned());
|
||
|
let pool = SqlitePool::connect(&session_db_url).await?;
|
||
|
let session_store = SqliteStore::new(pool);
|
||
|
session_store.migrate().await?;
|
||
|
|
||
|
let use_secure_sessions: bool =
|
||
|
FromStr::from_str(&dotenvy::var("SECURE_SESSIONS").unwrap_or("true".to_owned()))?;
|
||
|
|
||
|
let session_layer = SessionManagerLayer::new(session_store).with_secure(use_secure_sessions);
|
||
|
|
||
|
Ok(session_layer)
|
||
|
}
|