codify "platform" into resolution logic, server-fn/fullstack overhaul (#4596)

overhaul dioxus fullstack using a new implementation of server_fn

This PR is a complete rewrite of dioxus fullstack designed to improve compatibility with axum and to fix a number of compilation errors based on feature flag unification plumbing through macros.
This commit is contained in:
Jonathan Kelley authored and GitHub committed 2025-10-03 18:26:19 -07:00
1 parent 8421c3aef0
commit f2b1c6d97f
424 files changed
+17284 -6624

No files matched your search

+144
View File
@@ -0,0 +1,144 @@
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<User, i64, SessionSqlitePool, sqlx::SqlitePool>;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub(crate) struct User {
pub id: i32,
pub anonymous: bool,
pub username: String,
pub permissions: HashSet<String>,
}
#[derive(sqlx::FromRow, Clone)]
pub(crate) struct SqlPermissionTokens {
pub token: String,
}
#[async_trait]
impl Authentication<User, i64, SqlitePool> for User {
async fn load_user(userid: i64, pool: Option<&SqlitePool>) -> Result<User, anyhow::Error> {
let pool = pool.unwrap();
User::get_user(userid, pool)
.await
.ok_or_else(|| anyhow::anyhow!("Could not load user"))
}
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<SqlitePool> for User {
async fn has(&self, perm: &str, _pool: &Option<&SqlitePool>) -> bool {
self.permissions.contains(perm)
}
}
impl User {
pub async fn get_user(id: i64, pool: &SqlitePool) -> Option<Self> {
#[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(id)
.fetch_one(pool)
.await
.ok()?;
//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(id)
.fetch_all(pool)
.await
.ok()?;
Some(User {
id: sqluser.id,
anonymous: sqluser.anonymous,
username: sqluser.username,
permissions: sql_user_perms.into_iter().map(|x| x.token).collect(),
})
}
pub async fn create_user_tables(pool: &SqlitePool) -> Result<(), sqlx::Error> {
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS users (
"id" INTEGER PRIMARY KEY,
"anonymous" BOOLEAN NOT NULL,
"username" VARCHAR(256) NOT NULL
)
"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
CREATE TABLE IF NOT EXISTS user_permissions (
"user_id" INTEGER NOT NULL,
"token" VARCHAR(256) NOT NULL
)"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
INSERT INTO users
(id, anonymous, username) SELECT 1, true, 'Guest'
ON CONFLICT(id) DO UPDATE SET
anonymous = EXCLUDED.anonymous,
username = EXCLUDED.username
"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
INSERT INTO users
(id, anonymous, username) SELECT 2, false, 'Test'
ON CONFLICT(id) DO UPDATE SET
anonymous = EXCLUDED.anonymous,
username = EXCLUDED.username
"#,
)
.execute(pool)
.await?;
sqlx::query(
r#"
INSERT INTO user_permissions
(user_id, token) SELECT 2, 'Category::View'
"#,
)
.execute(pool)
.await?;
Ok(())
}
}