feat: conditionally render login or homepage
							parent
							
								
									902de85131
								
							
						
					
					
						commit
						48b3191117
					
				|  | @ -13,37 +13,41 @@ 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()); | ||||
|     match logged_in_user(&ctx.pool, req.headers()) { | ||||
|         Ok(Some(user)) => { | ||||
|             req.extensions_mut().insert(user); | ||||
| 
 | ||||
|     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) { | ||||
|             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(), | ||||
|             next.run(req).await | ||||
|         } | ||||
|     } else { | ||||
|         StatusCode::UNAUTHORIZED.into_response() | ||||
|         Ok(None) => StatusCode::UNAUTHORIZED.into_response(), | ||||
|         Err(err) => AppError::Db(err).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) | ||||
|  |  | |||
|  | @ -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) | ||||
|     } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue