From 2965a788cfcf4a0386cb8832e0d96491bf54c1d3 Mon Sep 17 00:00:00 2001 From: Owen Jacobson Date: Wed, 4 Sep 2024 00:28:35 -0400 Subject: Display a different / page depending on whether the current identity is valid or not. This is mostly a proof of concept for the implementation of form login implemented in previous commits, but it _is_ useful as it controls whether the / page shows login, or shows logout. From here, chat is next! --- src/login/extract/login.rs | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) create mode 100644 src/login/extract/login.rs (limited to 'src/login/extract/login.rs') diff --git a/src/login/extract/login.rs b/src/login/extract/login.rs new file mode 100644 index 0000000..f49933a --- /dev/null +++ b/src/login/extract/login.rs @@ -0,0 +1,61 @@ +use axum::{ + extract::{FromRequestParts, State}, + http::{request::Parts, StatusCode}, + response::{IntoResponse, Response}, +}; +use sqlx::sqlite::SqlitePool; + +use crate::{ + error::InternalError, + login::{ + extract::IdentityToken, + repo::{logins::Login, tokens::Provider as _}, + }, +}; + +#[async_trait::async_trait] +impl FromRequestParts for Login { + type Rejection = LoginError; + + async fn from_request_parts( + parts: &mut Parts, + state: &SqlitePool, + ) -> Result { + let identity_token = IdentityToken::from_request_parts(parts, state).await?; + + let token = identity_token.token().ok_or(LoginError::Forbidden)?; + + let db = State::::from_request_parts(parts, state).await?; + let mut tx = db.begin().await?; + let login = tx.tokens().validate(token).await?; + tx.commit().await?; + + login.ok_or(LoginError::Forbidden) + } +} + +pub enum LoginError { + Failure(E), + Forbidden, +} + +impl IntoResponse for LoginError +where + E: IntoResponse, +{ + fn into_response(self) -> Response { + match self { + Self::Forbidden => (StatusCode::FORBIDDEN, "forbidden").into_response(), + Self::Failure(e) => e.into_response(), + } + } +} + +impl From for LoginError +where + E: Into, +{ + fn from(err: E) -> Self { + Self::Failure(err.into()) + } +} -- cgit v1.2.3