feat: conditionally render login or homepage

image-uploads
Jef Roosens 2025-01-11 21:53:46 +01:00
parent 902de85131
commit 48b3191117
No known key found for this signature in database
GPG Key ID: 21FD3D77D56BAF49
2 changed files with 43 additions and 33 deletions

View File

@ -13,22 +13,29 @@ use axum_extra::extract::{
use serde::Deserialize;
use tera::Context;
use crate::db::{Session, User};
use crate::db::{DbError, DbPool, Session, User};
use super::{error::AppError, render_view};
pub fn logged_in_user(pool: &DbPool, headers: &HeaderMap) -> Result<Option<User>, DbError> {
let jar = CookieJar::from_headers(headers);
if let Some(session_id) = jar
.get("session_id")
.and_then(|c| c.value().parse::<u64>().ok())
{
Session::user_from_id(pool, session_id)
} else {
Ok(None)
}
}
pub async fn auth_middleware(
State(ctx): State<crate::Context>,
mut req: Request,
next: Next,
) -> Response {
let jar = CookieJar::from_headers(req.headers());
if let Some(session_id) = jar
.get("session_id")
.and_then(|c| c.value().parse::<u64>().ok())
{
match Session::user_from_id(&ctx.pool, session_id) {
match logged_in_user(&ctx.pool, req.headers()) {
Ok(Some(user)) => {
req.extensions_mut().insert(user);
@ -37,13 +44,10 @@ pub async fn auth_middleware(
Ok(None) => StatusCode::UNAUTHORIZED.into_response(),
Err(err) => AppError::Db(err).into_response(),
}
} else {
StatusCode::UNAUTHORIZED.into_response()
}
}
pub fn app() -> Router<crate::Context> {
Router::new().route("/login", get(get_login).post(post_login))
Router::new().route("/login", post(post_login))
}
#[derive(Deserialize)]
@ -52,23 +56,10 @@ struct Login {
password: String,
}
async fn get_login(
State(ctx): State<crate::Context>,
headers: HeaderMap,
) -> Result<Html<String>, AppError> {
let context = Context::new();
Ok(Html(render_view(
&ctx.tera,
"views/login.html",
&context,
&headers,
)?))
}
async fn post_login(
State(ctx): State<crate::Context>,
jar: CookieJar,
headers: HeaderMap,
Form(login): Form<Login>,
) -> Result<(CookieJar, Html<String>), AppError> {
if let Some(user) = User::by_username(&ctx.pool, &login.username)? {
@ -84,7 +75,7 @@ async fn post_login(
.same_site(SameSite::Lax)
.build(),
),
Html(String::new()),
super::render_home(ctx, &headers).await?,
))
} else {
Err(AppError::Unauthorized)

View File

@ -74,7 +74,7 @@ pub fn app(ctx: crate::Context, static_dir: &str) -> axum::Router {
))
}
async fn get_index(State(ctx): State<crate::Context>, headers: HeaderMap) -> Result<Html<String>> {
pub async fn render_home(ctx: crate::Context, headers: &HeaderMap) -> Result<Html<String>> {
let plants = tokio::task::spawn_blocking(move || Plant::all(&ctx.pool))
.await
.unwrap()?;
@ -85,6 +85,25 @@ async fn get_index(State(ctx): State<crate::Context>, headers: HeaderMap) -> Res
&ctx.tera,
"views/index.html",
&context,
headers,
)?))
}
pub fn render_login(ctx: crate::Context, headers: &HeaderMap) -> Result<Html<String>> {
let context = Context::new();
Ok(Html(render_view(
&ctx.tera,
"views/login.html",
&context,
&headers,
)?))
}
async fn get_index(State(ctx): State<crate::Context>, headers: HeaderMap) -> Result<Html<String>> {
if auth::logged_in_user(&ctx.pool, &headers)?.is_some() {
render_home(ctx, &headers).await
} else {
render_login(ctx, &headers)
}
}