diff --git a/packages/fullstack/examples/axum-auth/Cargo.toml b/packages/fullstack/examples/axum-auth/Cargo.toml index 8e8389084..94a0c6357 100644 --- a/packages/fullstack/examples/axum-auth/Cargo.toml +++ b/packages/fullstack/examples/axum-auth/Cargo.toml @@ -28,6 +28,7 @@ sqlx = { version = "0.7.0", features = [ ], optional = true } anyhow = "1.0.71" http = { version = "0.2.9", optional = true } +tower = { version = "0.4.13", optional = true } [dependencies.axum_session] version = "0.3.0" @@ -41,7 +42,7 @@ optional = true [features] default = [] -ssr = ["axum", "tokio", "dioxus-fullstack/axum", "tower-http", "simple_logger", "async-trait", "sqlx", "axum_session", "axum_session_auth", "http"] +ssr = ["axum", "tokio", "dioxus-fullstack/axum", "tower-http", "simple_logger", "async-trait", "sqlx", "axum_session", "axum_session_auth", "http", "tower"] web = ["dioxus-web"] [profile.release] diff --git a/packages/fullstack/examples/axum-auth/src/auth.rs b/packages/fullstack/examples/axum-auth/src/auth.rs index 9056c0c1a..56eddbd8e 100644 --- a/packages/fullstack/examples/axum-auth/src/auth.rs +++ b/packages/fullstack/examples/axum-auth/src/auth.rs @@ -1,9 +1,18 @@ use async_trait::async_trait; -use axum::{http::Method, routing::get, Router, response::{Response, IntoResponse}}; +use axum::{ + http::Method, + response::{IntoResponse, Response}, + routing::get, + Router, +}; use axum_session::{SessionConfig, SessionLayer, SessionSqlitePool, SessionStore}; use axum_session_auth::*; +use core::pin::Pin; +use dioxus_fullstack::prelude::*; use serde::{Deserialize, Serialize}; use sqlx::sqlite::{SqliteConnectOptions, SqlitePool, SqlitePoolOptions}; +use std::error::Error; +use std::future::Future; use std::{collections::HashSet, net::SocketAddr, str::FromStr}; #[derive(Debug, Clone, Serialize, Deserialize)] @@ -183,17 +192,29 @@ pub async fn connect_to_database() -> SqlitePool { .unwrap() } -pub struct Session(pub axum_session_auth::AuthSession); +pub struct Session( + pub axum_session_auth::AuthSession< + crate::auth::User, + i64, + axum_session_auth::SessionSqlitePool, + sqlx::SqlitePool, + >, +); -impl std::ops::Deref for Session { - type Target = axum_session_auth::AuthSession; +impl std::ops::Deref for Session { + type Target = axum_session_auth::AuthSession< + crate::auth::User, + i64, + axum_session_auth::SessionSqlitePool, + sqlx::SqlitePool, + >; fn deref(&self) -> &Self::Target { &self.0 } } -impl std::ops::DerefMut for Session { +impl std::ops::DerefMut for Session { fn deref_mut(&mut self) -> &mut Self::Target { &mut self.0 } @@ -211,19 +232,31 @@ impl std::fmt::Display for AuthSessionLayerNotFound { impl std::error::Error for AuthSessionLayerNotFound {} impl IntoResponse for AuthSessionLayerNotFound { - fn into_response(self) -> Response { - (http::status::StatusCode::INTERNAL_SERVER_ERROR, "AuthSessionLayer was not found").into_response() - } + fn into_response(self) -> Response { + ( + http::status::StatusCode::INTERNAL_SERVER_ERROR, + "AuthSessionLayer was not found", + ) + .into_response() } +} #[async_trait] impl axum::extract::FromRequestParts for Session { type Rejection = AuthSessionLayerNotFound; - async fn from_request_parts(parts: &mut http::request::Parts, state: &S) -> Result { - axum_session_auth::AuthSession::::from_request_parts(parts, state) - .await - .map(Session) - .map_err(|_| AuthSessionLayerNotFound) + async fn from_request_parts( + parts: &mut http::request::Parts, + state: &S, + ) -> Result { + axum_session_auth::AuthSession::< + crate::auth::User, + i64, + axum_session_auth::SessionSqlitePool, + sqlx::SqlitePool, + >::from_request_parts(parts, state) + .await + .map(Session) + .map_err(|_| AuthSessionLayerNotFound) } } diff --git a/packages/fullstack/examples/axum-auth/src/main.rs b/packages/fullstack/examples/axum-auth/src/main.rs index 1822f861c..0288f4d82 100644 --- a/packages/fullstack/examples/axum-auth/src/main.rs +++ b/packages/fullstack/examples/axum-auth/src/main.rs @@ -61,8 +61,7 @@ fn main() { >::new(Some(pool)) .with_config(auth_config), ) - .layer(axum_session::SessionLayer::new(session_store)) - ; + .layer(axum_session::SessionLayer::new(session_store)); // run it let addr = std::net::SocketAddr::from(([127, 0, 0, 1], 3000)); @@ -123,39 +122,35 @@ fn app(cx: Scope) -> Element { #[server(GetUserName)] pub async fn get_user_name( - #[extract] - session : crate::auth::Session + #[extract] session: crate::auth::Session, ) -> Result { - Ok(session.0.current_user.unwrap().username - .to_string()) + Ok(session.0.current_user.unwrap().username.to_string()) } #[server(Login)] -pub async fn login( - #[extract] - auth: crate::auth::Session -) -> Result<(), ServerFnError> { +pub async fn login(#[extract] auth: crate::auth::Session) -> Result<(), ServerFnError> { auth.login_user(2); Ok(()) } #[server(Permissions)] pub async fn get_permissions( - #[extract] - method: axum::http::Method, - #[extract] - auth: crate::auth::Session, + #[extract] method: axum::http::Method, + #[extract] auth: crate::auth::Session, ) -> Result { let current_user = auth.current_user.clone().unwrap_or_default(); // lets check permissions only and not worry about if they are anon or not - if !axum_session_auth::Auth::::build([axum::http::Method::POST], false) - .requires(axum_session_auth::Rights::any([ - axum_session_auth::Rights::permission("Category::View"), - axum_session_auth::Rights::permission("Admin::View"), - ])) - .validate(¤t_user, &method, None) - .await + if !axum_session_auth::Auth::::build( + [axum::http::Method::POST], + false, + ) + .requires(axum_session_auth::Rights::any([ + axum_session_auth::Rights::permission("Category::View"), + axum_session_auth::Rights::permission("Admin::View"), + ])) + .validate(¤t_user, &method, None) + .await { return Ok(format!( "User {}, Does not have permissions needed to view this page please login",