eric / rustwarden

Bolierplate rust pour web app "framework de developpement"

README.md

Rustwarden

Framework Rust pour la gestion d'utilisateurs et l'authentification securisee. Permet de creer rapidement des applications web avec authentification JWT, RBAC granulaire, gestion d'emails, et panneau d'administration.

Fonctionnalites

  • Authentification JWT avec refresh tokens et blacklist automatique
  • RBAC granulaire (roles + permissions par ressource)
  • Panneau d'administration complet (CRUD users, roles, permissions, settings)
  • Validation d'email avec token
  • Reset de mot de passe par email (confirmation double-etape)
  • File d'attente d'emails avec retry automatique
  • Detection de bounces IMAP
  • Protection CSRF
  • Rate limiting configurable
  • Internationalisation (fr, en, de, es)
  • Middleware d'authentification et d'autorisation
  • Mode headless (API-only) cle en main : routeur d'auth JSON canonique rustwarden_core::auth::auth_api_routes() monte en une ligne, comportement d'echec d'auth configurable (redirection vers login_path ou 401 JSON)
  • Outil screen-select : genere le plan des ecrans UI a coder selon les fonctionnalites activees (docs/plans/ui-screens.md) puis recoche le realise par analyse statique (-- --check) — pour les UIs custom/headless
  • Conformite ANSSI (complexite des mots de passe, HttpOnly cookies, etc.)
  • OAuth2 / OpenID Connect (Google, GitHub, Discord, Microsoft) avec architecture extensible
  • Federation ActivityPub optionnelle (RFC 0001+) : WebFinger, NodeInfo, login AP-native, invitations d'equipe cross-instance, modele de confiance allowlist/blocklist — fournie par le crate rustwarden-fediverse
  • Variable APP_NAME pour personnaliser le branding partout dans l'UI

Architecture

rustwarden/
├── crates/
│   ├── rustwarden-core/            # Library : auth, RBAC, services, middleware, i18n, hooks
│   ├── rustwarden-ui/              # UI optionnelle : templates HTML, admin panel, handlers
│   ├── rustwarden-fediverse/       # Federation ActivityPub optionnelle (RFC 0001+)
│   ├── rustwarden-fediverse-ui/    # UI HTML de reference pour la federation
│   └── rustwarden-fediverse-guard/ # Detection d'abus et bans pour la federation (RFC 0028+)
├── app/                    # Application de reference (12 lignes de main.rs)
├── tools/
│   └── rustwarden-cli/     # Wizard interactif pour creer ou updater de nouveaux projets
├── locales/                # Fichiers de traduction (YAML)
├── static/                 # Fichiers statiques (CSS, JS, images)
├── database/               # Docker Compose pour PostgreSQL
└── docs/                   # Documentation complementaire
└── .env                    # Variable d'environnement

Crates

CrateDescription
rustwarden-coreAuthentification JWT, modeles SeaORM, services (users, roles, permissions, email), middleware (auth, admin, CSRF, rate-limit), i18n, background tasks, hooks
rustwarden-uiInterface HTML par defaut (login, profil, admin panel) avec Askama, DaisyUI, HTMX
rustwarden-fediverseFederation ActivityPub (WebFinger, NodeInfo, actor, inbox, signatures HTTP, auth AP-native, invitations cross-instance, worker outbound, modele de confiance allowlist/blocklist) — optionnel via feature Cargo fediverse
rustwarden-fediverse-uiUI HTML de reference pour la federation : handlers admin/login/consent/invite, templates Askama, carte dashboard injectable
rustwarden-fediverse-guardDetection d'abus temps reel et gestion de bans pour la couche federation (RFC 0028+) — optionnel
rustwarden-appBinaire de reference utilisant le builder
rustwarden-cliWizard CLI interactif pour scaffolder des applications autonomes

Stack technique

  • Backend : Rust, Axum 0.8, SeaORM 2.0, Tokio
  • Auth : JWT (HS256), bcrypt, sessions en memoire ou SeaORM
  • Database : PostgreSQL
  • Frontend (UI) : Askama, Tailwind CSS, DaisyUI, HTMX, Alpine.js
  • Email : Lettre (SMTP), IMAP bounce detection

Demarrage rapide

Option 1 : Wizard CLI (recommande)

Le wizard interactif genere un projet autonome avec toute la configuration deja remplie.

# Compiler le wizard
cargo build -p rustwarden-cli

# Lancer le wizard
cargo run -p rustwarden-cli -- start-project

Le wizard demande interactivement :

  1. Nom du projet (nom technique du crate)
  2. Nom affiche (APP_NAME dans l'interface)
  3. Description
  4. Dossier cible
  5. Mode (interface web ou API seule, federation optionnelle : aucune / headless / avec UI de reference)
  6. Migrations automatiques (oui/non)
  7. Port du serveur
  8. Base de donnees (nom, utilisateur, mot de passe)
  9. Administrateur (username, email, mot de passe)
  10. SMTP (optionnel : host, port, identifiants)

Il genere un projet autonome avec :

  • Les crates rustwarden-core et rustwarden-ui copies localement
  • .env configure avec vos identifiants
  • database/.env pour Docker PostgreSQL
  • Un README.md et un DEVELOPER.md detaille
  • Une page d'accueil personnalisee avec le nom de votre application
  • Les templates HTML rebrandes automatiquement
# Apres generation
cd mon-app
# PostgreSQL n'ecoute que 127.0.0.1:5432. Copier database/env.sample vers
# database/.env et definir POSTGRES_PASSWORD (obligatoire, pas de repli).
cp database/env.sample database/.env
cd database && docker compose up -d && cd ..
cargo run
# Ouvrir http://localhost:3000

Option 2 : Comme dependance dans un projet existant

[dependencies]
rustwarden-core = { path = "../rustwarden/crates/rustwarden-core" }
rustwarden-ui = { path = "../rustwarden/crates/rustwarden-ui" }  # optionnel
use rustwarden_core::prelude::*;

#[tokio::main]
async fn main() -> anyhow::Result<()> {
    RustwardenApp::builder()
        .from_env()
        .with_ui(rustwarden_ui::default_routes)
        .auto_migrate(true)
        .merge_routes(my_routes())
        .build()
        .await?
        .run()
        .await
}

Option 3 : Mode headless (API-only)

RustwardenApp::builder()
    .from_env()
    .headless()                                                    // API-only : echec d'auth = 401 JSON (au lieu d'une redirection)
    .merge_machine_routes(rustwarden_core::auth::auth_api_routes()) // API d'auth /api/v1/auth/* prete a l'emploi
    .merge_routes(my_api_routes())                                 // vos routes metier
    .build()
    .await?
    .run()
    .await

En mode headless, aucun prefixe protege n'est enregistre par defaut : declarez les votres via .register_protected_prefix("/…"). Le chemin de login (login_path) et le mode d'echec (auth_failure_mode) sont configurables — voir la section Configuration.

Pour planifier les ecrans d'une UI custom, le binaire screen-select (livre avec rustwarden-core) genere docs/plans/ui-screens.md — la liste des ecrans a coder selon les fonctionnalites activees — puis recoche le realise par analyse statique des routes :

cargo run -p rustwarden-core --bin screen-select              # wizard : selection des fonctionnalites → plan
cargo run -p rustwarden-core --bin screen-select -- --check   # controle de couverture (recoche le realise)

Catalogue des ecrans et limites de detection : docs/SERVICES_REFERENCE.md §22.


Builder API

RustwardenApp::builder()
    .from_env()                              // charge .env + init logging
    .database_url("postgres://...")          // ou .database(db_connection)
    .address("0.0.0.0:8080")                 // adresse du serveur
    .with_ui(rustwarden_ui::browser_routes)  // UI SSR (canal browser, CSRF)
    .merge_machine_routes(rustwarden_ui::api_routes()) // API JSON de l'UI (canal machine, sans CSRF)
    .headless()                              // OU mode API-only (pas d'UI) → echec d'auth = 401 JSON
    .login_path("/connexion")                // chemin de redirection de login (defaut "/login")
    .auth_failure_mode(AuthFailureMode::Json401) // Redirect (defaut UI) ou Json401 (defaut headless)
    .merge_browser_routes(custom_ui_router)  // pages SSR mutantes → CSRF applique
    .merge_machine_routes(custom_api_router) // API JSON / webhooks → sans CSRF
    .register_protected_prefix("/espace")    // auth requise sur ce prefixe
    .hooks(MyHooks)                          // lifecycle hooks personnalises
    .auto_migrate(true)                      // migrations auto au demarrage
    .without_email()                         // desactiver l'email
    .without_background_tasks()              // desactiver les taches de fond
    .locale_dir("my_locales")                // repertoire de traductions
    .supported_locales(vec!["fr", "en"])     // locales supportees
    .default_locale("fr")                    // locale par defaut
    .build().await?
    .run().await

with_ui/merge_browser_routes = canal browser (CSRF applique) ; merge_machine_routes = canal machine (API Bearer/JSON, sans CSRF). rustwarden_ui::default_routes est deprecie (remettrait /api/v1/* sous CSRF) → utiliser browser_routes() + api_routes().

Sequencement interne du builder

  1. Connexion a la base PostgreSQL
  2. Migrations automatiques (si active)
  3. Creation admin par defaut + initialisation app_settings
  4. Configuration auth (JWT, sessions)
  5. Demarrage des taches de fond (email queue, IMAP bounce, JWT cleanup)
  6. Chargement i18n
  7. Assemblage du router (UI + routes custom + middleware)
  8. Demarrage du serveur HTTP

Mise a jour du framework (projets generes)

Les projets generes par le wizard embarquent les crates du framework en local (vendored). Pour les resynchroniser sur une version plus recente :

# Depuis le depot Rustwarden (le wizard demande le dossier du projet cible)
cargo run -p rustwarden-cli -- update-project

La commande synchronise les crates presentes dans le projet (rustwarden-core, rustwarden-ui, rustwarden-fediverse* selon le cas — binaire screen-select inclus), preserve les templates personnalises, supprime les fichiers retires du framework, propose d'ajouter la federation si elle est absente, puis rappelle les actions post-update (cargo check, migrations, screen-select).

Procedure manuelle (fallback)
# Depuis le dossier du projet consommateur
rm -rf crates/rustwarden-core crates/rustwarden-ui
cp -r /chemin/vers/Rustwarden/crates/rustwarden-core crates/
cp -r /chemin/vers/Rustwarden/crates/rustwarden-ui crates/
# Fichiers partages (si modifies)
cp -r /chemin/vers/Rustwarden/locales ./
cp -r /chemin/vers/Rustwarden/static ./

Verifier ensuite les breaking changes :

  • exports du prelude (signatures de RustwardenApp, AuthUser, Claims, etc.)
  • migrations : core_migrations() dans src/migrations.rs a jour
  • contrat des templates (variables LayoutContext)
  • versions des dependances dans Cargo.toml (les versions recentes ont change : thiserror 2.0, askama 0.15, jsonwebtoken 10, rand 0.9, etc.)

Puis compiler :

cargo check
cargo clippy -- -D warnings

Routes disponibles

Routes publiques

MethodeCheminDescription
GET/Redirection vers /home ou /login
GET/loginPage de connexion / inscription
GET/resend-verificationRenvoi de l'email de verification
GET/reset-passwordPage de reinitialisation du mot de passe
GET/confirm-password-changeConfirmation de changement de mot de passe
GET/healthHealth check

API REST (authentification)

MethodeCheminDescription
POST/api/v1/auth/loginConnexion (retourne JWT + refresh token)
POST/api/v1/auth/registerInscription
POST/api/v1/auth/refreshRafraichir le JWT
POST/api/v1/auth/logoutDeconnexion (blacklist le JWT)
GET/api/v1/auth/meProfil de l'utilisateur connecte
POST/api/v1/auth/forgot-passwordDemander un reset de mot de passe
POST/api/v1/auth/reset-passwordExecuter le reset
GET/api/v1/auth/verify-email/{token}Verifier l'adresse email
POST/api/v1/auth/resend-verificationRenvoyer le mail de verification
POST/api/v1/auth/resend-verification/by-usernameIdem, par username
POST/api/v1/auth/2fa/verifyVerifier le code 2FA (challenge de login)

Cet ensemble est fourni cle en main par rustwarden_core::auth::auth_api_routes() (a monter via merge_machine_routes). En mode UI, rustwarden_ui::api_routes() monte exactement le meme jeu de routes.

API REST (OAuth) (feature oauth)

MethodeCheminDescription
GET/api/v1/auth/oauth/{provider}/redirectRedirige vers le provider OAuth
GET/api/v1/auth/oauth/{provider}/callbackCallback du provider OAuth
GET/api/v1/auth/oauth/providersListe les providers actifs (JSON)
GET/api/v1/auth/oauth/accountsListe les comptes OAuth de l'utilisateur
DELETE/api/v1/auth/oauth/accounts/{id}Delie un compte OAuth

API REST (utilisateurs)

MethodeCheminDescription
GET/api/v1/usersLister les utilisateurs
POST/api/v1/usersCreer un utilisateur

Pages UI (authentification requise)

MethodeCheminDescription
GET/homePage d'accueil
GET/profilePage profil
PUT/profileMettre a jour le profil
GET/settings/passwordPage changement de mot de passe
PUT/settings/passwordChanger le mot de passe
DELETE/settings/password/pendingAnnuler un changement en attente
GET/settings/sessionsPage des sessions actives
DELETE/settings/sessions/{id}Revoquer une session
GET/settings/preferencesPage des preferences
PUT/settings/preferencesMettre a jour les preferences

Pages admin (role admin requis)

MethodeCheminDescription
GET/adminDashboard d'administration
GET/admin/usersListe des utilisateurs
GET/admin/users/createFormulaire de creation
POST/admin/usersCreer un utilisateur
GET/admin/users/{id}Formulaire d'edition
PUT/admin/users/{id}Mettre a jour un utilisateur
DELETE/admin/users/{id}Supprimer un utilisateur
POST/admin/users/{id}/reset-passwordReinitialiser le mot de passe
POST/admin/users/{id}/reset-password-emailEnvoyer un email de reinitialisation
GET/admin/rolesListe des roles
GET/admin/roles/createFormulaire de creation de role
POST/admin/rolesCreer un role
GET/admin/roles/{id}Formulaire d'edition de role
PUT/admin/roles/{id}Mettre a jour un role
DELETE/admin/roles/{id}Supprimer un role
GET/admin/settingsParametres de l'application
PUT/admin/settingsMettre a jour les parametres
GET/admin/errorsPage de test d'erreurs

Pages admin federation (feature fediverse)

Quand le binaire est compile avec --features fediverse, le dashboard admin affiche une carte "Federation ActivityPub" qui pointe vers /admin/fediverse/settings. Depuis ce hub :

MethodeCheminDescription
GET/admin/fediverse/settingsToggle d'activation + selecteurs (mode de confiance, scope d'interop, authorized-fetch)
POST/admin/fediverse/settingsSauvegarder les reglages
GET/admin/fediverse/trust_listListe de confiance (allowlist ou blocklist selon le mode)
POST/admin/fediverse/trust_list/addAjouter un domaine
POST/admin/fediverse/trust_list/deleteRetirer un domaine
GET/admin/fediverse/queueDashboard de la file d'envoi outbound (RFC 0011)
GET/admin/fediverse/sessions_remoteSessions distantes actives
POST/admin/fediverse/sessions_remote/revokeRevoquer une session distante
POST/admin/fediverse/sessions_remote/kill_domainKill-switch par domaine
GET/admin/fediverse/nodeinfoStats NodeInfo humanisees
GET/admin/teams/{id}/invitesInvitations d'equipe cross-instance

Cote utilisateur final, le flow de connexion federee est expose sur /login/fediverse (et son SSE /login/fediverse/sse/{id}), l'ecran de consentement IdP sur /fediverse/consent/{id}, et la page d'acceptation d'invitation sur /fediverse/invite/{id}. Le profil utilisateur expose /profile/connected_apps pour lister les instances qu'il a autorisees.

Endpoints protocole (publics, hors UI) (feature fediverse)

MethodeCheminDescription
GET/.well-known/webfinger?resource=acct:user@domainResolution WebFinger RFC 7033
GET/.well-known/nodeinfoDiscovery NodeInfo
GET/nodeinfo/2.1Document NodeInfo 2.1
GET/users/{username}Person actor JSON (avec content negotiation)
POST/inboxInbox AP (Update / Delete / Revoke)
POST/fediverse/auth/inboxInbox AP-native pour AuthRequest / Accept / Reject

Hooks (extension)

Implementez RustwardenHooks pour ajouter de la logique metier aux evenements du framework :

use rustwarden_core::prelude::*;
use async_trait::async_trait;
use sea_orm::DatabaseConnection;
use uuid::Uuid;

struct MyHooks;

#[async_trait]
impl RustwardenHooks for MyHooks {
    async fn on_user_registered(&self, db: &DatabaseConnection, user_id: Uuid, username: &str) -> anyhow::Result<()> {
        // Creer un workspace par defaut pour le nouvel utilisateur
        Ok(())
    }

    async fn on_user_login(&self, db: &DatabaseConnection, user_id: Uuid, username: &str) -> anyhow::Result<()> {
        // Logger l'activite, envoyer une notification...
        Ok(())
    }
}

Activez les hooks dans le builder :

RustwardenApp::builder()
    .from_env()
    .hooks(MyHooks)
    .build()
    .await?
    .run()
    .await

Hooks disponibles

HookDeclencheur
on_user_registeredApres inscription d'un utilisateur
on_user_loginApres connexion reussie
on_user_logoutApres deconnexion
on_password_changedApres changement de mot de passe
on_email_verifiedApres verification de l'email
on_role_changedApres modification des roles
on_resource_sharedApres partage d'une ressource
on_resource_unsharedApres revocation d'un partage
on_oauth_loginApres login OAuth reussi (provider + is_new_user)

RBAC (Roles et Permissions)

Le systeme RBAC permet de definir des roles avec des permissions granulaires.

Modele

  • Role : nom unique (ex: admin, editor, viewer)
  • Permission : nom unique (ex: users.read, users.create, articles.publish)
  • Role-Permission : table de liaison many-to-many
  • User-Role : table de liaison many-to-many

Utilisation dans les handlers

use rustwarden_core::services::permission_service::PermissionService;
use rustwarden_core::services::role_service::RoleService;

// Verifier si un utilisateur a une permission specifique
let has_perm = PermissionService::user_has_permission(&db, user_id, "articles.publish").await?;

// Recuperer les roles d'un utilisateur
let roles = RoleService::get_user_roles(&db, user_id).await?;

Administration

Le panneau d'administration (/admin/roles) permet de :

  • Creer / modifier / supprimer des roles
  • Attribuer des permissions aux roles
  • Assigner des roles aux utilisateurs

Configuration (.env)

Application

VariableDescriptionDefaut
APP_NAMENom affiche dans l'interface et les emailsMy App
APP_THEMETheme de l'applicationlight
APP_DEBUGMode debugfalse
DEFAULT_LOCALELocale par defautfr

Base de donnees

VariableDescriptionDefaut
DATABASE_URLURL PostgreSQLrequis

Serveur

VariableDescriptionDefaut
SERVER_HOSTAdresse d'ecoute0.0.0.0
SERVER_PORTPort3000
RUST_LOGNiveau de loggingdebug

JWT

VariableDescriptionDefaut
JWT_SECRETCle secrete JWT (min 32 chars)requis
JWT_EXPIRATION_MINUTESDuree de vie du token15
JWT_ISSUERIssuer du JWTnom du projet
REFRESH_TOKEN_EXPIRATION_DAYSDuree de vie du refresh token7

Sessions

VariableDescriptionDefaut
SESSION_TIMEOUT_MINUTESDuree de la session30
SESSION_BACKENDBackend de session (memory, seaorm, redis)memory
REDIS_URLURL Redis (si SESSION_BACKEND=redis)—

Rate limiting

VariableDescriptionDefaut
RATE_LIMIT_LOGIN_PER_MINUTETentatives de login5
RATE_LIMIT_REFRESH_PER_MINUTERafraichissements JWT10
RATE_LIMIT_GENERAL_PER_MINUTERequetes generales100

Cookies

VariableDescriptionDefaut
COOKIE_SECURECookies securises (HTTPS only)false
COOKIE_SAME_SITEPolitique SameSiteLax

Comportement d'authentification

VariableDescriptionDefaut
LOGIN_PATHChemin de redirection de login emis par le middleware d'auth (decouple de l'UI)/login
AUTH_FAILURE_MODEReponse sur route protegee sans auth : redirect (302 vers LOGIN_PATH) ou json401 (401 JSON). .headless() bascule le defaut sur json401redirect

Admin initial

VariableDescriptionDefaut
ADMIN_USERNAMELogin admin par defautadmin
ADMIN_EMAILEmail adminrequis
ADMIN_PASSWORDMot de passe adminrequis

Email SMTP

VariableDescriptionDefaut
SMTP_HOSTServeur SMTP— (optionnel)
SMTP_PORTPort SMTP587
SMTP_USERUtilisateur SMTP—
SMTP_PASSWORDMot de passe SMTP—
SMTP_FROMAdresse expediteur—
SMTP_FROM_NAMENom expediteurvaleur de APP_NAME
SMTP_USE_TLSUtiliser TLStrue
SMTP_USE_STARTTLSUtiliser STARTTLStrue
SMTP_ACCEPT_INVALID_CERTSAccepter certificats invalidesfalse
EMAIL_BASE_URLURL de base pour les liens dans les emailshttp://localhost:3000

File d'attente email

VariableDescriptionDefaut
EMAIL_QUEUE_BATCH_SIZETaille du batch10
EMAIL_QUEUE_RETRY_ATTEMPTSNombre de tentatives5
EMAIL_QUEUE_RETRY_DELAY_SECONDSDelai entre tentatives300
EMAIL_VALIDATION_REQUIREDExiger la validation emailtrue
ALLOW_REGISTRATIONAutoriser l'inscription publiquefalse

IMAP (detection de bounces)

VariableDescriptionDefaut
IMAP_HOSTServeur IMAP— (optionnel)
IMAP_PORTPort IMAP993
IMAP_USERUtilisateur IMAP—
IMAP_PASSWORDMot de passe IMAP—
IMAP_USE_TLSUtiliser TLStrue
IMAP_USE_STARTTLSUtiliser STARTTLSfalse
IMAP_ACCEPT_INVALID_CERTSAccepter certificats invalidesfalse
IMAP_MAILBOXBoite mail a surveillerINBOX
IMAP_POLL_INTERVAL_SECONDSIntervalle de verification300

OAuth / SSO (feature oauth)

VariableDescriptionDefaut
OAUTH_ENCRYPTION_KEYCle AES-256-GCM (hex 64 chars) pour chiffrer les secrets en DB—
OAUTH_ENABLEDActive globalement OAuthfalse
OAUTH_REDIRECT_BASE_URLURL de base pour les callbackshttp://localhost:3000
OAUTH_GOOGLE_CLIENT_IDGoogle Client ID—
OAUTH_GOOGLE_CLIENT_SECRETGoogle Client Secret—
OAUTH_GOOGLE_ENABLEDActive Googlefalse
OAUTH_GITHUB_CLIENT_IDGitHub Client ID—
OAUTH_GITHUB_CLIENT_SECRETGitHub Client Secret—
OAUTH_GITHUB_ENABLEDActive GitHubfalse
OAUTH_DISCORD_CLIENT_IDDiscord Client ID—
OAUTH_DISCORD_CLIENT_SECRETDiscord Client Secret—
OAUTH_DISCORD_ENABLEDActive Discordfalse
OAUTH_MICROSOFT_CLIENT_IDMicrosoft Client ID—
OAUTH_MICROSOFT_CLIENT_SECRETMicrosoft Client Secret—
OAUTH_MICROSOFT_ENABLEDActive Microsoftfalse
OAUTH_MICROSOFT_TENANTAzure AD tenantcommon

Les credentials OAuth peuvent etre configures via l'interface Admin (/admin/settings) ou via ces variables d'environnement (fallback).

Federation ActivityPub (feature fediverse)

VariableDescriptionDefaut
FEDIVERSE_DOMAINDomaine federe expose, ex. example.org. Refuse les placeholders type example.com, your.tld, change-me.tld.requis
FEDIVERSE_DEBUG_LOCAL_FEDERATIONAutorise les base URLs http:// (tests locaux multi-instances). Ne jamais activer en production.false
FEDIVERSE_AUTHORIZED_FETCHMode "secure fetch" Mastodon : exige une signature HTTP pour resoudre un acteur. Activer apres audit.false
FEDIVERSE_OUTBOUND_WORKERSNombre de workers concurrents qui drainent la file de delivery.4
FEDIVERSE_OUTBOUND_MAX_ATTEMPTSTentatives maximum avant qu'un job soit marque dead.8
FEDIVERSE_OUTBOUND_REQUEST_TIMEOUT_SECSTimeout par requete outbound.30
FEDIVERSE_FETCH_ACTOR_CACHE_TTL_SECSTTL du cache des documents acteur distants.86400
FEDIVERSE_AUTH_CHALLENGE_TTL_SECSTTL des challenges d'auth AP-native (RFC 0006).300

La feature est opt-in a la compilation : ajouter --features fediverse au binaire. Le crate rustwarden-core ne tire aucune des deps lourdes (activitypub_federation, rsa, reqwest, ammonia) tant que le binaire n'active pas la feature. Cote runtime, deux flags supplementaires dans app_settings controlent l'experience admin : fediverse_enabled (toggle global, defaut false) et fediverse_trust_mode (allowlist / open_with_blocklist). Reglage via /admin/fediverse/settings ou directement en SQL.

Wiring minimal dans main.rs (extrait de app/src/main.rs) :

#[cfg(feature = "fediverse")]
let builder = {
    use std::sync::Arc;
    let db = sea_orm::Database::connect(&std::env::var("DATABASE_URL")?).await?;
    let config = rustwarden_fediverse::FediverseConfig::from_env()?;
    let router = rustwarden_fediverse::routes::router(config, db.clone());
    let checker: Arc<dyn rustwarden_core::middleware::revocation::RemoteIdentityRevocationChecker> =
        Arc::new(
            rustwarden_fediverse::services::revocation::SeaOrmRemoteIdentityRevocationChecker::new(
                db.clone(),
            ),
        );
    builder
        .database(db)
        .register_protected_prefix("/fediverse/consent")
        .register_protected_prefix("/fediverse/invite")
        .register_revocation_checker(checker)
        .merge_routes(router)
};

Pour un essai local multi-instances (3 noeuds federes via Docker Compose), voir tests/fediverse-testbed/README.md. Guide operateur complet : docs/fediverse-operations.md.


Migrations

Les migrations sont gerees avec SeaORM Migration :

# Manuellement
cargo run --bin migrate

# Automatiquement au demarrage (via le builder)
.auto_migrate(true)

Pour combiner avec vos propres migrations :

use rustwarden_core::migrations::core_migrations;

struct AppMigrator;

impl MigratorTrait for AppMigrator {
    fn migrations() -> Vec<Box<dyn MigrationTrait>> {
        let mut all = core_migrations();
        all.push(Box::new(MyCustomMigration));
        all
    }
}

Internationalisation (i18n)

Les traductions sont dans locales/ au format YAML. 4 langues incluses : fr, en, de, es.

# locales/fr.yml
products:
  title: "Produits"
  empty: "Aucun produit trouve"

Utilisation dans un handler :

use rustwarden_core::i18n::service::I18nService;
use rustwarden_core::i18n::extractor::Locale;
use std::sync::Arc;
use axum::extract::Extension;

async fn my_page(
    locale: Locale,
    Extension(i18n): Extension<Arc<I18nService>>,
) -> String {
    i18n.t(&locale.0, "products.title")
}

La locale est detectee automatiquement dans cet ordre :

  1. Cookie locale
  2. Header Accept-Language
  3. DEFAULT_LOCALE (env var)

Commandes utiles

CommandeDescription
cargo run -p rustwarden-appLancer l'application de reference
cargo run -p rustwarden-cli -- start-projectWizard de creation de projet
cargo run -p rustwarden-cli -- update-projectResynchroniser le framework vendored d'un projet genere
cargo run --bin migrateExecuter les migrations
cargo run --bin seedCreer/mettre a jour l'admin initial
cargo run --bin hash_passwordHasher un mot de passe bcrypt
cargo run --bin change_passwordChanger le mot de passe d'un utilisateur (ex. cargo run --bin change_password -- admin "Admin123!")
cargo run -p rustwarden-core --bin screen-selectGenerer le plan des ecrans UI a coder (depuis un projet consommateur)
cargo run -p rustwarden-core --bin screen-select -- --checkRecocher les ecrans realises par analyse statique
cargo testLancer les tests
cargo build --releaseBuild optimise pour la production

Documentation complementaire

DocumentDescription
DEVELOPER.mdGuide detaille pour les developpeurs (architecture, hooks, ajout de routes/modeles)
docs/SERVICES_REFERENCE.mdReference exhaustive des services et API pour projets consommateurs (§22 : binaire screen-select)
docs/ANSSI_COMPLIANCE_REPORT.mdRapport de conformite aux recommandations ANSSI
docs/CSS_STYLE_GUIDE.mdGuide de style CSS/DaisyUI
docs/configuration-flows.mdDiagrammes des flux de configuration
docs/fediverse-operations.mdGuide operateur de la federation ActivityPub (10 sections : activation, env vars, app_settings, trust/block list, incidents, observabilite, GC, promotion stable, URLs, limites)
docs/rfcs/25 RFCs documentant la conception de la couche federation (0001–0025)
tests/fediverse-testbed/README.mdBanc d'essai Docker tri-instance (alpha/beta/gamma) pour valider la federation Rustwarden↔Rustwarden
.env.sampleFichier de reference pour toutes les variables d'environnement