//! The code here is pulled from the `axum-session-auth` crate examples, requiring little to no //! modification to work with dioxus fullstack. use async_trait::async_trait; use axum_session_auth::*; use axum_session_sqlx::SessionSqlitePool; use serde::{Deserialize, Serialize}; use sqlx::sqlite::SqlitePool; use std::collections::HashSet; pub(crate) type Session = axum_session_auth::AuthSession; pub(crate) type AuthLayer = axum_session_auth::AuthSessionLayer; #[derive(Debug, Clone, Serialize, Deserialize)] pub(crate) struct User { pub id: i32, pub anonymous: bool, pub username: String, pub permissions: HashSet, } #[derive(sqlx::FromRow, Clone)] pub(crate) struct SqlPermissionTokens { pub token: String, } #[async_trait] impl Authentication for User { async fn load_user(userid: i64, pool: Option<&SqlitePool>) -> Result { let db = pool.unwrap(); #[derive(sqlx::FromRow, Clone)] struct SqlUser { id: i32, anonymous: bool, username: String, } let sqluser = sqlx::query_as::<_, SqlUser>("SELECT * FROM users WHERE id = $1") .bind(userid) .fetch_one(db) .await .unwrap(); //lets just get all the tokens the user can use, we will only use the full permissions if modifying them. let sql_user_perms = sqlx::query_as::<_, SqlPermissionTokens>( "SELECT token FROM user_permissions WHERE user_id = $1;", ) .bind(userid) .fetch_all(db) .await .unwrap(); Ok(User { id: sqluser.id, anonymous: sqluser.anonymous, username: sqluser.username, permissions: sql_user_perms.into_iter().map(|x| x.token).collect(), }) } fn is_authenticated(&self) -> bool { !self.anonymous } fn is_active(&self) -> bool { !self.anonymous } fn is_anonymous(&self) -> bool { self.anonymous } } #[async_trait] impl HasPermission for User { async fn has(&self, perm: &str, _pool: &Option<&SqlitePool>) -> bool { self.permissions.contains(perm) } }