pique/src/server.rs

68 lines
2.4 KiB
Rust
Raw Normal View History

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)
}