feat: conditionally render login or homepage
parent
902de85131
commit
48b3191117
|
@ -13,37 +13,41 @@ use axum_extra::extract::{
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use tera::Context;
|
use tera::Context;
|
||||||
|
|
||||||
use crate::db::{Session, User};
|
use crate::db::{DbError, DbPool, Session, User};
|
||||||
|
|
||||||
use super::{error::AppError, render_view};
|
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(
|
pub async fn auth_middleware(
|
||||||
State(ctx): State<crate::Context>,
|
State(ctx): State<crate::Context>,
|
||||||
mut req: Request,
|
mut req: Request,
|
||||||
next: Next,
|
next: Next,
|
||||||
) -> Response {
|
) -> Response {
|
||||||
let jar = CookieJar::from_headers(req.headers());
|
match logged_in_user(&ctx.pool, req.headers()) {
|
||||||
|
Ok(Some(user)) => {
|
||||||
|
req.extensions_mut().insert(user);
|
||||||
|
|
||||||
if let Some(session_id) = jar
|
next.run(req).await
|
||||||
.get("session_id")
|
|
||||||
.and_then(|c| c.value().parse::<u64>().ok())
|
|
||||||
{
|
|
||||||
match Session::user_from_id(&ctx.pool, session_id) {
|
|
||||||
Ok(Some(user)) => {
|
|
||||||
req.extensions_mut().insert(user);
|
|
||||||
|
|
||||||
next.run(req).await
|
|
||||||
}
|
|
||||||
Ok(None) => StatusCode::UNAUTHORIZED.into_response(),
|
|
||||||
Err(err) => AppError::Db(err).into_response(),
|
|
||||||
}
|
}
|
||||||
} else {
|
Ok(None) => StatusCode::UNAUTHORIZED.into_response(),
|
||||||
StatusCode::UNAUTHORIZED.into_response()
|
Err(err) => AppError::Db(err).into_response(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn app() -> Router<crate::Context> {
|
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)]
|
#[derive(Deserialize)]
|
||||||
|
@ -52,23 +56,10 @@ struct Login {
|
||||||
password: String,
|
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(
|
async fn post_login(
|
||||||
State(ctx): State<crate::Context>,
|
State(ctx): State<crate::Context>,
|
||||||
jar: CookieJar,
|
jar: CookieJar,
|
||||||
|
headers: HeaderMap,
|
||||||
Form(login): Form<Login>,
|
Form(login): Form<Login>,
|
||||||
) -> Result<(CookieJar, Html<String>), AppError> {
|
) -> Result<(CookieJar, Html<String>), AppError> {
|
||||||
if let Some(user) = User::by_username(&ctx.pool, &login.username)? {
|
if let Some(user) = User::by_username(&ctx.pool, &login.username)? {
|
||||||
|
@ -84,7 +75,7 @@ async fn post_login(
|
||||||
.same_site(SameSite::Lax)
|
.same_site(SameSite::Lax)
|
||||||
.build(),
|
.build(),
|
||||||
),
|
),
|
||||||
Html(String::new()),
|
super::render_home(ctx, &headers).await?,
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Err(AppError::Unauthorized)
|
Err(AppError::Unauthorized)
|
||||||
|
|
|
@ -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))
|
let plants = tokio::task::spawn_blocking(move || Plant::all(&ctx.pool))
|
||||||
.await
|
.await
|
||||||
.unwrap()?;
|
.unwrap()?;
|
||||||
|
@ -85,6 +85,25 @@ async fn get_index(State(ctx): State<crate::Context>, headers: HeaderMap) -> Res
|
||||||
&ctx.tera,
|
&ctx.tera,
|
||||||
"views/index.html",
|
"views/index.html",
|
||||||
&context,
|
&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,
|
&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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue