diff --git a/src/db.rs b/src/db.rs index 58aa1ff..ac97be5 100644 --- a/src/db.rs +++ b/src/db.rs @@ -1,5 +1,5 @@ use serde::de::DeserializeOwned; -use sled::{Db, IVec}; +use sled::{Db, IVec, Tree}; use thiserror::Error; #[derive(Clone)] @@ -67,4 +67,8 @@ impl Data { }) .into_iter()) } + + pub fn tree(&self, name: &str) -> Result { + Ok(self.db.open_tree(name)?) + } } diff --git a/src/router.rs b/src/router.rs index a2ed58a..23d4baa 100644 --- a/src/router.rs +++ b/src/router.rs @@ -14,17 +14,21 @@ use axum::{ routing::get, Router, }; -use axum_login::login_required; +use axum_login::{login_required, AuthManagerLayerBuilder}; use maud::html; use sled::IVec; use thiserror::Error; use tower_http::trace::TraceLayer; use tower_livereload::LiveReloadLayer; +use tower_sessions::SessionManagerLayer; #[derive(Error, Debug)] pub enum NewRouterError { #[error("watcher error: {0}")] Watcher(#[from] notify::Error), + + #[error("database error: {0}")] + Database(#[from] db::Error), } #[derive(Error, Debug)] @@ -77,15 +81,21 @@ pub async fn router( let (static_file_service, static_file_watcher) = static_files::router(orl())?; let auth_service = auth::router(state.clone()).unwrap(); + let session_store = tower_sessions_sled_store::SledStore::new(state.db.tree("session")?); + let session_layer = SessionManagerLayer::new(session_store); + + let auth_layer = AuthManagerLayerBuilder::new(state.clone(), session_layer).build(); + let mut result = Router::new() + .route("/dashboard", get(dashboard)) + .route_layer(login_required!(AppState, login_url = "/auth/login")) .route("/", get(index)) .route("/about", get(about)) .route("/users", get(users)) - .route("/dashboard", get(dashboard)) - .route_layer(login_required!(AppState, login_url = "/auth/login")) .nest_service("/auth", auth_service) .nest_service("/static", static_file_service) .layer(TraceLayer::new_for_http()) + .layer(auth_layer) .with_state(state.clone()); if let Some(lr) = live_reload_layer { diff --git a/src/service/auth.rs b/src/service/auth.rs index f0caa26..424924a 100644 --- a/src/service/auth.rs +++ b/src/service/auth.rs @@ -6,8 +6,6 @@ use axum::http::StatusCode; use axum::response::{Html, IntoResponse, Redirect}; use axum::Form; use maud::html; -use redact::Secret; -use serde::Deserialize; use std::convert::Infallible; use axum::{ @@ -19,6 +17,7 @@ use crate::{prelude::*, user}; pub fn router(state: AppState) -> Result { Ok(Router::new() + .route("/logout", get(logout)) .route("/login", get(login)) .route("/login", post(authenticate)) .route("/register", get(register)) @@ -109,3 +108,10 @@ async fn create_user( .into_string(), )) } + +pub async fn logout(mut auth_session: AuthSession) -> impl IntoResponse { + match auth_session.logout().await { + Ok(_) => Redirect::to("/auth/login").into_response(), + Err(_) => StatusCode::INTERNAL_SERVER_ERROR.into_response(), + } +}