#![allow(non_snake_case, unused)] #[cfg(feature = "server")] mod auth; use dioxus::prelude::*; use dioxus_fullstack::prelude::*; use serde::{Deserialize, Serialize}; fn main() { // Set the logger ahead of time since we don't use `dioxus::launch` on the server dioxus::logger::initialize_default(); #[cfg(feature = "web")] // Hydrate the application on the client LaunchBuilder::web().launch(app); #[cfg(feature = "server")] { use crate::auth::*; use axum::routing::*; use axum_session::SessionConfig; use axum_session::SessionStore; use axum_session_auth::AuthConfig; use axum_session_sqlx::SessionSqlitePool; tokio::runtime::Runtime::new() .unwrap() .block_on(async move { let pool = connect_to_database().await; //This Defaults as normal Cookies. //To enable Private cookies for integrity, and authenticity please check the next Example. let session_config = SessionConfig::default().with_table_name("test_table"); let auth_config = AuthConfig::::default().with_anonymous_user_id(Some(1)); let session_store = SessionStore::::new( Some(pool.clone().into()), session_config, ) .await .unwrap(); User::create_user_tables(&pool).await; // build our application with some routes let app = Router::new() // Server side render the application, serve static assets, and register server functions .serve_dioxus_application(ServeConfig::new().unwrap(), app) .layer( axum_session_auth::AuthSessionLayer::< crate::auth::User, i64, SessionSqlitePool, sqlx::SqlitePool, >::new(Some(pool)) .with_config(auth_config), ) .layer(axum_session::SessionLayer::new(session_store)); // serve the app using the address passed by the CLI let addr = dioxus::cli_config::fullstack_address_or_localhost(); let listener = tokio::net::TcpListener::bind(&addr).await.unwrap(); axum::serve(listener, app.into_make_service()) .await .unwrap(); }); } } // fn app() -> Element { let mut user_name = use_signal(|| "?".to_string()); let mut permissions = use_signal(|| "?".to_string()); rsx! { div { button { onclick: move |_| { async move { login().await?; Ok(()) } }, "Login Test User" } } div { button { onclick: move |_| async move { let data = get_user_name().await?; user_name.set(data); Ok(()) }, "Get User Name" } "User name: {user_name}" } div { button { onclick: move |_| async move { let data = get_permissions().await?; permissions.set(data); Ok(()) }, "Get Permissions" } "Permissions: {permissions}" } } } #[server] pub async fn get_user_name() -> ServerFnResult { let auth = auth::get_session().await?; Ok(auth.current_user.unwrap().username.to_string()) } #[server] pub async fn login() -> ServerFnResult { let auth = auth::get_session().await?; auth.login_user(2); Ok(()) } #[server] pub async fn get_permissions() -> ServerFnResult { let method: axum::http::Method = extract().await?; let auth = auth::get_session().await?; 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 { return Ok(format!( "User {}, Does not have permissions needed to view this page please login", current_user.username )); } Ok(format!( "User has Permissions needed. Here are the Users permissions: {:?}", current_user.permissions )) }