use axum::{Router, routing::get, Json, Extension};
use wacht::middleware::*;
use serde_json::{json, Value};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
wacht::init_from_env().await?;
let app = Router::new()
// Super admin routes - require all permissions
.nest("/admin", Router::new()
.route("/users", get(manage_users))
.route("/billing", get(manage_billing))
.route("/audit", get(view_audit_logs))
.layer(MultiplePermissionLayers::all(vec![
("admin:users", PermissionScope::Organization),
("admin:billing", PermissionScope::Organization),
("admin:audit", PermissionScope::Organization),
]))
)
// Content management - require any permission
.nest("/content", Router::new()
.route("/posts", get(list_posts))
.route("/media", get(list_media))
.layer(RequireAnyPermissionLayer::new(vec![
("content:read", PermissionScope::Workspace),
("content:write", PermissionScope::Workspace),
("content:admin", PermissionScope::Workspace),
]))
)
// Reports - specific permission
.route("/reports/financial", get(financial_reports))
.layer(PermissionLayer::organization("reports:financial"))
// Apply auth to all routes
.layer(AuthLayer::new());
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await?;
axum::serve(listener, app).await?;
Ok(())
}
async fn manage_users(Extension(auth): Extension<AuthContext>) -> Json<Value> {
Json(json!({
"message": "User management",
"user": auth.user_id
}))
}
async fn financial_reports(Extension(auth): Extension<AuthContext>) -> Json<Value> {
Json(json!({
"report": "Financial data",
"organization": auth.organization_id
}))
}