From 3f0fa576952bd967735fb99d35c42372c4058036 Mon Sep 17 00:00:00 2001 From: Daniel Flanagan Date: Tue, 21 Nov 2023 14:41:52 -0600 Subject: [PATCH] Session data to change views --- src/feather_icons.rs | 5 ++++- src/partials.rs | 31 ++++++++++++++++++++++--------- src/router.rs | 16 +++++++--------- src/views.rs | 37 +++++++++++++++++++++++-------------- 4 files changed, 56 insertions(+), 33 deletions(-) diff --git a/src/feather_icons.rs b/src/feather_icons.rs index 7d60ca8..de31277 100644 --- a/src/feather_icons.rs +++ b/src/feather_icons.rs @@ -2,7 +2,10 @@ // feather icons pub const FEATHER_ICON_USER_PLUS: &str = r#""#; -#[allow(dead_code)] pub const FEATHER_ICON_LAYOUT: &str = r#""#; pub const FEATHER_ICON_LOGIN: &str = r#""#; + +pub const FEATHER_ICON_USER: &str = r#""#; + +// pub const FEATHER_ICON_: &str = r#""#; diff --git a/src/partials.rs b/src/partials.rs index c92f36a..e3b6743 100644 --- a/src/partials.rs +++ b/src/partials.rs @@ -1,8 +1,10 @@ +use axum_login::AuthSession; use maud::{html, Markup, PreEscaped, DOCTYPE}; -use crate::feather_icons; +use crate::{feather_icons, state}; -pub fn header() -> Markup { +pub fn header(sess: &AuthSession) -> Markup { + let is_logged_in = sess.user.is_some(); html! { (DOCTYPE) head { @@ -27,13 +29,24 @@ pub fn header() -> Markup { // (PreEscaped(FEATHER_ICON_LAYOUT)) // "Dashboard" // } - a href="/register" preload="" { - (PreEscaped(feather_icons::FEATHER_ICON_USER_PLUS)) - "Register" - } - a href="/login" preload="" { - (PreEscaped(feather_icons::FEATHER_ICON_LOGIN)) - "Login" + @if is_logged_in { + a href="/account" preload="" { + (PreEscaped(feather_icons::FEATHER_ICON_USER)) + "Account" + } + a href="/app" preload="" { + (PreEscaped(feather_icons::FEATHER_ICON_LAYOUT)) + "Dashboard" + } + } @else { + a href="/register" preload="" { + (PreEscaped(feather_icons::FEATHER_ICON_USER_PLUS)) + "Register" + } + a href="/login" preload="" { + (PreEscaped(feather_icons::FEATHER_ICON_LOGIN)) + "Login" + } } } } diff --git a/src/router.rs b/src/router.rs index 558f9cd..18be87a 100644 --- a/src/router.rs +++ b/src/router.rs @@ -114,7 +114,7 @@ where { let password_bytes = password.as_ref().as_bytes(); let current = PasswordHash::new(current_digest.as_ref())?; - Ok(Argon2::default().verify_password(password_bytes, ¤t)?) + Argon2::default().verify_password(password_bytes, ¤t) } impl user::ActiveModel {} @@ -170,18 +170,16 @@ impl AuthnBackend for state::State { type Error = AppError; async fn authenticate(&self, l: Self::Credentials) -> Result, Self::Error> { - match User::find() + Ok(User::find() .filter(user::Column::Username.eq(l.username)) // TODO: will this have index problems since I'm searching over the password digest? .one(&self.db) .await? - { - Some(user) => match password_verify(&l.password, &user.password_digest) { - Ok(()) => Ok(Some(user)), - Err(e) => Err(e.into()), - }, - None => Ok(None), - } + .filter(|u| { + password_verify(&l.password, &u.password_digest) + .ok() + .is_some() + })) } async fn get_user(&self, user_id: &UserId) -> Result, Self::Error> { diff --git a/src/views.rs b/src/views.rs index 880311b..322a2c0 100644 --- a/src/views.rs +++ b/src/views.rs @@ -10,6 +10,7 @@ use axum::{ response::{Html, IntoResponse}, }; use axum_csrf::CsrfToken; +use axum_login::AuthSession; use maud::html; use sea_orm::EntityTrait; use tracing::instrument; @@ -24,11 +25,15 @@ where type AppRes = Result<(StatusCode, Html), AppError>; -#[instrument] -pub async fn index() -> Html { +pub async fn index(sess: AuthSession) -> Html { + let is_logged_in = sess.user.is_some(); + // let username = sess + // .user + // .map(|u| u.username) + // .unwrap_or_else(|| "N/A".to_owned()); Html( html! { - (header()) + (header(&sess)) main class="prose" { h1 { "Manage live lyrics and music displays" } p { "Stop struggling to share the same messy set of PowerPoint files or Google Presentations. Make editing and controlling your live lyrics and music displays easy and simple." } @@ -41,8 +46,12 @@ pub async fn index() -> Html { li { "Lightweight and fast" } } section class="flex gap" { - a href="/register" class="button bg-primary" { "Try now" } - a class="button" href="/login" { "Login" } + @if is_logged_in { + a href="/app" class="button bg-primary" { "Open app" } + } @else { + a href="/register" class="button bg-primary" { "Try now" } + a class="button" href="/login" { "Login" } + } } } (footer()) @@ -51,11 +60,11 @@ pub async fn index() -> Html { ) } -pub async fn register(t: CsrfToken) -> impl IntoResponse { - csrf(t, |token| { +pub async fn register(sess: AuthSession, t: CsrfToken) -> impl IntoResponse { + csrf(t, move |token| { Html( html! { - (header()) + (header(&sess)) main class="prose" { h1 { "Register an account" } form method="post" { @@ -79,11 +88,11 @@ pub async fn register(t: CsrfToken) -> impl IntoResponse { .await } -pub async fn login(t: CsrfToken) -> impl IntoResponse { - csrf(t, |token| { +pub async fn login(sess: AuthSession, t: CsrfToken) -> impl IntoResponse { + csrf(t, move |token| { Html( html! { - (header()) + (header(&sess)) main class="prose" { h1 { "Login" } form method="post" { @@ -107,20 +116,20 @@ pub async fn login(t: CsrfToken) -> impl IntoResponse { .await } -pub async fn all_users(State(s): State) -> AppRes { +pub async fn all_users(sess: AuthSession, State(s): State) -> AppRes { let users: Vec = User::find().all(&s.db).await?; Ok(( StatusCode::OK, Html( html! { - (header()) + (header(&sess)) main class="prose" { h1 { "Users" } ul { @if users.is_empty() { li { "It looks like there are no users yet!" } - } else { + } @else { @for u in users { li { (u.username)