Session data to change views
This commit is contained in:
parent
6579332013
commit
3f0fa57695
4 changed files with 56 additions and 33 deletions
|
@ -2,7 +2,10 @@
|
|||
// feather icons
|
||||
pub const FEATHER_ICON_USER_PLUS: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user-plus"><path d="M16 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path><circle cx="8.5" cy="7" r="4"></circle><line x1="20" y1="8" x2="20" y2="14"></line><line x1="23" y1="11" x2="17" y2="11"></line></svg>"#;
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub const FEATHER_ICON_LAYOUT: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-layout"><rect x="3" y="3" width="18" height="18" rx="2" ry="2"></rect><line x1="3" y1="9" x2="21" y2="9"></line><line x1="9" y1="21" x2="9" y2="9"></line></svg>"#;
|
||||
|
||||
pub const FEATHER_ICON_LOGIN: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-log-in"><path d="M15 3h4a2 2 0 0 1 2 2v14a2 2 0 0 1-2 2h-4"></path><polyline points="10 17 15 12 10 7"></polyline><line x1="15" y1="12" x2="3" y2="12"></line></svg>"#;
|
||||
|
||||
pub const FEATHER_ICON_USER: &str = r#"<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="feather feather-user"><path d="M20 21v-2a4 4 0 0 0-4-4H8a4 4 0 0 0-4 4v2"></path><circle cx="12" cy="7" r="4"></circle></svg>"#;
|
||||
|
||||
// pub const FEATHER_ICON_: &str = r#""#;
|
||||
|
|
|
@ -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<state::State>) -> Markup {
|
||||
let is_logged_in = sess.user.is_some();
|
||||
html! {
|
||||
(DOCTYPE)
|
||||
head {
|
||||
|
@ -27,6 +29,16 @@ pub fn header() -> Markup {
|
|||
// (PreEscaped(FEATHER_ICON_LAYOUT))
|
||||
// "Dashboard"
|
||||
// }
|
||||
@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"
|
||||
|
@ -41,6 +53,7 @@ pub fn header() -> Markup {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn footer() -> Markup {
|
||||
html! {
|
||||
|
|
|
@ -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<Option<Self::User>, 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<Self>) -> Result<Option<Self::User>, Self::Error> {
|
||||
|
|
33
src/views.rs
33
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<String>), AppError>;
|
||||
|
||||
#[instrument]
|
||||
pub async fn index() -> Html<String> {
|
||||
pub async fn index(sess: AuthSession<state::State>) -> Html<String> {
|
||||
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,21 +46,25 @@ pub async fn index() -> Html<String> {
|
|||
li { "Lightweight and fast" }
|
||||
}
|
||||
section class="flex gap" {
|
||||
@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())
|
||||
}
|
||||
.into_string(),
|
||||
)
|
||||
}
|
||||
|
||||
pub async fn register(t: CsrfToken) -> impl IntoResponse {
|
||||
csrf(t, |token| {
|
||||
pub async fn register(sess: AuthSession<state::State>, 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<state::State>, 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<state::State>) -> AppRes {
|
||||
pub async fn all_users(sess: AuthSession<state::State>, State(s): State<state::State>) -> AppRes {
|
||||
let users: Vec<user::Model> = 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)
|
||||
|
|
Loading…
Reference in a new issue