feat(rbac): implement complete RBAC middleware and route permissions
- Add rbac_middleware_fn for use in middleware layer chain
- Add RBAC middleware to request processing pipeline (after auth)
- Complete route permissions for ALL apps:
- Anonymous: health, i18n, product, auth/login, chat, websocket
- Authenticated users: drive, mail, calendar, tasks, docs, paper, sheet,
slides, meet, research, sources, canvas, video, player, workspaces,
projects, goals, settings, bots (read), designer, dashboards, crm,
contacts, billing, products, tickets, learn, social, llm, autotask
- Admin/SuperAdmin: users, groups, bot management, analytics, monitoring,
audit, security, admin panel, attendant
- SuperAdmin only: RBAC management
- Add all /api/ui/** HTMX routes with proper permissions
- Chat remains anonymous for customer support functionality
This commit is contained in:
parent
81b8fd8f2d
commit
b4647cd8d2
3 changed files with 398 additions and 33 deletions
12
src/main.rs
12
src/main.rs
|
|
@ -227,6 +227,8 @@ async fn run_axum_server(
|
||||||
let cors = create_cors_layer();
|
let cors = create_cors_layer();
|
||||||
|
|
||||||
// Create auth config for protected routes
|
// Create auth config for protected routes
|
||||||
|
// Session-based auth from Zitadel uses session tokens (not JWTs)
|
||||||
|
// The auth middleware in auth.rs handles both JWT and session token validation
|
||||||
let auth_config = Arc::new(AuthConfig::from_env()
|
let auth_config = Arc::new(AuthConfig::from_env()
|
||||||
.add_anonymous_path("/health")
|
.add_anonymous_path("/health")
|
||||||
.add_anonymous_path("/healthz")
|
.add_anonymous_path("/healthz")
|
||||||
|
|
@ -488,6 +490,9 @@ async fn run_axum_server(
|
||||||
base_router
|
base_router
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Clone rbac_manager for use in middleware
|
||||||
|
let rbac_manager_for_middleware = Arc::clone(&rbac_manager);
|
||||||
|
|
||||||
let app = app_with_ui
|
let app = app_with_ui
|
||||||
// Security middleware stack (order matters - first added is outermost)
|
// Security middleware stack (order matters - first added is outermost)
|
||||||
.layer(middleware::from_fn(security_headers_middleware))
|
.layer(middleware::from_fn(security_headers_middleware))
|
||||||
|
|
@ -495,6 +500,13 @@ async fn run_axum_server(
|
||||||
.layer(rate_limit_extension)
|
.layer(rate_limit_extension)
|
||||||
// Request ID tracking for all requests
|
// Request ID tracking for all requests
|
||||||
.layer(middleware::from_fn(request_id_middleware))
|
.layer(middleware::from_fn(request_id_middleware))
|
||||||
|
// RBAC middleware - checks permissions AFTER authentication
|
||||||
|
.layer(middleware::from_fn(move |req: axum::http::Request<axum::body::Body>, next: axum::middleware::Next| {
|
||||||
|
let rbac = Arc::clone(&rbac_manager_for_middleware);
|
||||||
|
async move {
|
||||||
|
botserver::security::rbac_middleware_fn(req, next, rbac).await
|
||||||
|
}
|
||||||
|
}))
|
||||||
// Authentication middleware using provider registry
|
// Authentication middleware using provider registry
|
||||||
.layer(middleware::from_fn(move |req: axum::http::Request<axum::body::Body>, next: axum::middleware::Next| {
|
.layer(middleware::from_fn(move |req: axum::http::Request<axum::body::Body>, next: axum::middleware::Next| {
|
||||||
let state = auth_middleware_state.clone();
|
let state = auth_middleware_state.clone();
|
||||||
|
|
|
||||||
|
|
@ -79,7 +79,7 @@ pub use rbac_middleware::{
|
||||||
AccessDecision, AccessDecisionResult, RbacConfig, RbacError, RbacManager, RbacMiddlewareState,
|
AccessDecision, AccessDecisionResult, RbacConfig, RbacError, RbacManager, RbacMiddlewareState,
|
||||||
RequirePermission, RequireResourceAccess, RequireRole, ResourceAcl, ResourcePermission,
|
RequirePermission, RequireResourceAccess, RequireRole, ResourceAcl, ResourcePermission,
|
||||||
RoutePermission, build_default_route_permissions, create_admin_layer, create_permission_layer,
|
RoutePermission, build_default_route_permissions, create_admin_layer, create_permission_layer,
|
||||||
create_role_layer, rbac_middleware, require_admin_middleware, require_super_admin_middleware,
|
create_role_layer, rbac_middleware, rbac_middleware_fn, require_admin_middleware, require_super_admin_middleware,
|
||||||
};
|
};
|
||||||
pub use session::{
|
pub use session::{
|
||||||
DeviceInfo, InMemorySessionStore, SameSite, Session, SessionConfig, SessionManager,
|
DeviceInfo, InMemorySessionStore, SameSite, Session, SessionConfig, SessionManager,
|
||||||
|
|
|
||||||
|
|
@ -619,6 +619,56 @@ impl RbacManager {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// RBAC middleware function for use with middleware::from_fn
|
||||||
|
/// This version takes the RbacManager as a parameter instead of State
|
||||||
|
pub async fn rbac_middleware_fn(
|
||||||
|
request: Request<Body>,
|
||||||
|
next: Next,
|
||||||
|
rbac: Arc<RbacManager>,
|
||||||
|
) -> Response {
|
||||||
|
let path = request.uri().path().to_string();
|
||||||
|
let method = request.method().to_string();
|
||||||
|
|
||||||
|
let user = request
|
||||||
|
.extensions()
|
||||||
|
.get::<AuthenticatedUser>()
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(AuthenticatedUser::anonymous);
|
||||||
|
|
||||||
|
let decision = rbac.check_route_access(&path, &method, &user).await;
|
||||||
|
|
||||||
|
if rbac.config.audit_all_decisions {
|
||||||
|
debug!(
|
||||||
|
"RBAC decision for {} {} by user {}: {:?} - {}",
|
||||||
|
method, path, user.user_id, decision.decision, decision.reason
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if !decision.is_allowed() {
|
||||||
|
if !user.is_authenticated() {
|
||||||
|
return (
|
||||||
|
StatusCode::UNAUTHORIZED,
|
||||||
|
Json(serde_json::json!({
|
||||||
|
"error": "unauthorized",
|
||||||
|
"message": "Authentication required"
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.into_response();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
StatusCode::FORBIDDEN,
|
||||||
|
Json(serde_json::json!({
|
||||||
|
"error": "forbidden",
|
||||||
|
"message": decision.reason
|
||||||
|
})),
|
||||||
|
)
|
||||||
|
.into_response();
|
||||||
|
}
|
||||||
|
|
||||||
|
next.run(request).await
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn rbac_middleware(
|
pub async fn rbac_middleware(
|
||||||
State(rbac): State<Arc<RbacManager>>,
|
State(rbac): State<Arc<RbacManager>>,
|
||||||
request: Request<Body>,
|
request: Request<Body>,
|
||||||
|
|
@ -877,57 +927,360 @@ pub fn create_admin_layer(rbac_manager: Arc<RbacManager>) -> RbacMiddlewareState
|
||||||
|
|
||||||
pub fn build_default_route_permissions() -> Vec<RoutePermission> {
|
pub fn build_default_route_permissions() -> Vec<RoutePermission> {
|
||||||
vec![
|
vec![
|
||||||
|
// =====================================================================
|
||||||
|
// PUBLIC / ANONYMOUS ROUTES (no auth required)
|
||||||
|
// =====================================================================
|
||||||
|
RoutePermission::new("/health", "GET", "").with_anonymous(true),
|
||||||
|
RoutePermission::new("/healthz", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/health", "GET", "").with_anonymous(true),
|
RoutePermission::new("/api/health", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/version", "GET", "").with_anonymous(true),
|
RoutePermission::new("/api/version", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/product", "GET", "").with_anonymous(true),
|
RoutePermission::new("/api/product", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/i18n/**", "GET", "").with_anonymous(true),
|
RoutePermission::new("/api/i18n/**", "GET", "").with_anonymous(true),
|
||||||
|
|
||||||
|
// Auth routes - login must be anonymous
|
||||||
RoutePermission::new("/api/auth", "GET", "").with_anonymous(true),
|
RoutePermission::new("/api/auth", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/auth/login", "POST", "").with_anonymous(true),
|
RoutePermission::new("/api/auth/login", "POST", "").with_anonymous(true),
|
||||||
|
RoutePermission::new("/api/auth/bootstrap", "POST", "").with_anonymous(true),
|
||||||
|
RoutePermission::new("/api/auth/refresh", "POST", "").with_anonymous(true),
|
||||||
|
RoutePermission::new("/api/auth/logout", "POST", ""),
|
||||||
RoutePermission::new("/api/auth/me", "GET", ""),
|
RoutePermission::new("/api/auth/me", "GET", ""),
|
||||||
RoutePermission::new("/api/users", "GET", "users.read")
|
RoutePermission::new("/api/auth/**", "GET", ""),
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
RoutePermission::new("/api/auth/**", "POST", ""),
|
||||||
RoutePermission::new("/api/users", "POST", "users.create")
|
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
// WebSocket - anonymous for chat support
|
||||||
RoutePermission::new("/api/users/:id", "GET", "users.read"),
|
RoutePermission::new("/ws", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/users/:id", "PUT", "users.update"),
|
RoutePermission::new("/ws/**", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/users/:id", "DELETE", "users.delete")
|
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
// Chat - ANONYMOUS for customer support
|
||||||
RoutePermission::new("/api/drive/**", "GET", "drive.read"),
|
RoutePermission::new("/api/chat/**", "GET", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/drive/upload", "POST", "drive.write"),
|
RoutePermission::new("/api/chat/**", "POST", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/drive/:id", "DELETE", "drive.delete"),
|
|
||||||
RoutePermission::new("/api/mail/**", "GET", "mail.read"),
|
// Sessions - anonymous can create sessions for chat
|
||||||
RoutePermission::new("/api/mail/send", "POST", "mail.send"),
|
RoutePermission::new("/api/sessions", "POST", "").with_anonymous(true),
|
||||||
RoutePermission::new("/api/calendar/**", "GET", "calendar.read"),
|
RoutePermission::new("/api/sessions", "GET", ""),
|
||||||
RoutePermission::new("/api/calendar/events", "POST", "calendar.write"),
|
RoutePermission::new("/api/sessions/**", "GET", ""),
|
||||||
RoutePermission::new("/api/tasks/**", "GET", "tasks.read"),
|
|
||||||
RoutePermission::new("/api/tasks", "POST", "tasks.write"),
|
// =====================================================================
|
||||||
RoutePermission::new("/api/analytics/**", "GET", "analytics.read")
|
// AUTHENTICATED USER ROUTES (any logged-in user)
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
// =====================================================================
|
||||||
RoutePermission::new("/api/audit/**", "GET", "audit.read")
|
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
// Drive / Files
|
||||||
RoutePermission::new("/api/rbac/**", "*", "roles.assign")
|
RoutePermission::new("/api/drive/**", "GET", ""),
|
||||||
.with_roles(vec!["SuperAdmin".into()]),
|
RoutePermission::new("/api/drive/**", "POST", ""),
|
||||||
RoutePermission::new("/api/monitoring/**", "GET", "monitoring.read")
|
RoutePermission::new("/api/drive/**", "PUT", ""),
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
RoutePermission::new("/api/drive/**", "DELETE", ""),
|
||||||
RoutePermission::new("/api/bots", "POST", "bots.create"),
|
RoutePermission::new("/api/files/**", "GET", ""),
|
||||||
RoutePermission::new("/api/bots/:id", "DELETE", "bots.delete"),
|
RoutePermission::new("/api/files/**", "POST", ""),
|
||||||
RoutePermission::new("/api/bots/:id/**", "GET", "bots.read"),
|
RoutePermission::new("/api/files/**", "PUT", ""),
|
||||||
RoutePermission::new("/api/bots/:id/**", "PUT", "bots.update"),
|
RoutePermission::new("/api/files/**", "DELETE", ""),
|
||||||
// UI routes (HTMX endpoints) - allow authenticated users
|
|
||||||
|
// Mail
|
||||||
|
RoutePermission::new("/api/mail/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/mail/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/mail/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/mail/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Calendar
|
||||||
|
RoutePermission::new("/api/calendar/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/calendar/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/calendar/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/calendar/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Tasks
|
||||||
|
RoutePermission::new("/api/tasks/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/tasks/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/tasks/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/tasks/**", "PATCH", ""),
|
||||||
|
RoutePermission::new("/api/tasks/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Docs / Paper
|
||||||
|
RoutePermission::new("/api/docs/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/docs/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/docs/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/docs/**", "DELETE", ""),
|
||||||
|
RoutePermission::new("/api/paper/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/paper/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/paper/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/paper/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Sheet
|
||||||
|
RoutePermission::new("/api/sheet/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/sheet/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/sheet/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/sheet/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Slides
|
||||||
|
RoutePermission::new("/api/slides/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/slides/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/slides/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/slides/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Meet
|
||||||
|
RoutePermission::new("/api/meet/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/meet/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/meet/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/meet/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Research
|
||||||
|
RoutePermission::new("/api/research/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/research/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/research/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/research/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Sources
|
||||||
|
RoutePermission::new("/api/sources/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/sources/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/sources/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/sources/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Canvas
|
||||||
|
RoutePermission::new("/api/canvas/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/canvas/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/canvas/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/canvas/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Video / Player
|
||||||
|
RoutePermission::new("/api/video/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/video/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/player/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/player/**", "POST", ""),
|
||||||
|
|
||||||
|
// Workspaces
|
||||||
|
RoutePermission::new("/api/workspaces/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/workspaces/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/workspaces/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/workspaces/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Projects
|
||||||
|
RoutePermission::new("/api/projects/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/projects/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/projects/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/projects/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Goals
|
||||||
|
RoutePermission::new("/api/goals/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/goals/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/goals/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/goals/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Settings (user's own settings)
|
||||||
|
RoutePermission::new("/api/settings/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/settings/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/settings/**", "PUT", ""),
|
||||||
|
|
||||||
|
// Bots (read for all authenticated users)
|
||||||
|
RoutePermission::new("/api/bots", "GET", ""),
|
||||||
|
RoutePermission::new("/api/bots/:id", "GET", ""),
|
||||||
|
RoutePermission::new("/api/bots/:id/**", "GET", ""),
|
||||||
|
|
||||||
|
// Autotask
|
||||||
|
RoutePermission::new("/api/autotask/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/autotask/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/autotask/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/autotask/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Designer
|
||||||
|
RoutePermission::new("/api/designer/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/designer/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/designer/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/designer/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Dashboards
|
||||||
|
RoutePermission::new("/api/dashboards/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/dashboards/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/dashboards/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/dashboards/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// DB/Table access
|
||||||
|
RoutePermission::new("/api/db/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/db/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/db/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/db/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// CRM / Contacts
|
||||||
|
RoutePermission::new("/api/crm/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/crm/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/crm/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/crm/**", "DELETE", ""),
|
||||||
|
RoutePermission::new("/api/contacts/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/contacts/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/contacts/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/contacts/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Billing / Products
|
||||||
|
RoutePermission::new("/api/billing/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/billing/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/products/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/products/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/products/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/products/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Tickets
|
||||||
|
RoutePermission::new("/api/tickets/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/tickets/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/tickets/**", "PUT", ""),
|
||||||
|
RoutePermission::new("/api/tickets/**", "DELETE", ""),
|
||||||
|
|
||||||
|
// Learn
|
||||||
|
RoutePermission::new("/api/learn/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/learn/**", "POST", ""),
|
||||||
|
|
||||||
|
// Social
|
||||||
|
RoutePermission::new("/api/social/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/social/**", "POST", ""),
|
||||||
|
|
||||||
|
// LLM
|
||||||
|
RoutePermission::new("/api/llm/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/llm/**", "POST", ""),
|
||||||
|
|
||||||
|
// =====================================================================
|
||||||
|
// UI ROUTES (HTMX endpoints) - authenticated users
|
||||||
|
// =====================================================================
|
||||||
RoutePermission::new("/api/ui/tasks/**", "GET", ""),
|
RoutePermission::new("/api/ui/tasks/**", "GET", ""),
|
||||||
RoutePermission::new("/api/ui/tasks/**", "POST", ""),
|
RoutePermission::new("/api/ui/tasks/**", "POST", ""),
|
||||||
RoutePermission::new("/api/ui/tasks/**", "PUT", ""),
|
RoutePermission::new("/api/ui/tasks/**", "PUT", ""),
|
||||||
RoutePermission::new("/api/ui/tasks/**", "PATCH", ""),
|
RoutePermission::new("/api/ui/tasks/**", "PATCH", ""),
|
||||||
RoutePermission::new("/api/ui/tasks/**", "DELETE", ""),
|
RoutePermission::new("/api/ui/tasks/**", "DELETE", ""),
|
||||||
RoutePermission::new("/api/ui/calendar/**", "GET", ""),
|
RoutePermission::new("/api/ui/calendar/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/calendar/**", "POST", ""),
|
||||||
RoutePermission::new("/api/ui/drive/**", "GET", ""),
|
RoutePermission::new("/api/ui/drive/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/drive/**", "POST", ""),
|
||||||
RoutePermission::new("/api/ui/mail/**", "GET", ""),
|
RoutePermission::new("/api/ui/mail/**", "GET", ""),
|
||||||
RoutePermission::new("/api/ui/monitoring/**", "GET", ""),
|
RoutePermission::new("/api/ui/mail/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/docs/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/docs/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/paper/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/paper/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/sheet/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/sheet/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/slides/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/slides/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/meet/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/meet/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/research/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/research/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/sources/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/sources/**", "POST", ""),
|
||||||
|
RoutePermission::new("/api/ui/canvas/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/video/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/player/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/workspaces/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/projects/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/goals/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/designer/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/dashboards/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/crm/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/billing/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/products/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/tickets/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/learn/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/social/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/settings/**", "GET", ""),
|
||||||
|
RoutePermission::new("/api/ui/autotask/**", "GET", ""),
|
||||||
|
|
||||||
|
// =====================================================================
|
||||||
|
// ADMIN ROUTES (requires Admin or SuperAdmin role)
|
||||||
|
// =====================================================================
|
||||||
|
RoutePermission::new("/api/users", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/:id", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/:id", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/:id", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/**", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/**", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/users/**", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Groups management
|
||||||
|
RoutePermission::new("/api/groups/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/groups/**", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/groups/**", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/groups/**", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Bot management (create/delete)
|
||||||
|
RoutePermission::new("/api/bots", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/bots/:id", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/bots/:id", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/bots/:id/**", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/bots/:id/**", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Analytics (admin view)
|
||||||
|
RoutePermission::new("/api/analytics/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
||||||
RoutePermission::new("/api/ui/analytics/**", "GET", "")
|
RoutePermission::new("/api/ui/analytics/**", "GET", "")
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
||||||
|
|
||||||
|
// Monitoring
|
||||||
|
RoutePermission::new("/api/monitoring/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/ui/monitoring/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Audit logs
|
||||||
|
RoutePermission::new("/api/audit/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/ui/audit/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Security settings
|
||||||
|
RoutePermission::new("/api/security/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/security/**", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/security/**", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/ui/security/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
|
||||||
|
// Admin panel
|
||||||
|
RoutePermission::new("/api/admin/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/admin/**", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/admin/**", "PUT", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/admin/**", "DELETE", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
RoutePermission::new("/api/ui/admin/**", "GET", "")
|
RoutePermission::new("/api/ui/admin/**", "GET", "")
|
||||||
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into()]),
|
||||||
RoutePermission::new("/api/ui/**", "GET", ""),
|
|
||||||
|
// Attendant (customer service)
|
||||||
|
RoutePermission::new("/api/attendant/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
||||||
|
RoutePermission::new("/api/attendant/**", "POST", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
||||||
|
RoutePermission::new("/api/ui/attendant/**", "GET", "")
|
||||||
|
.with_roles(vec!["Admin".into(), "SuperAdmin".into(), "Moderator".into()]),
|
||||||
|
|
||||||
|
// =====================================================================
|
||||||
|
// SUPER ADMIN ONLY ROUTES
|
||||||
|
// =====================================================================
|
||||||
|
RoutePermission::new("/api/rbac/**", "GET", "")
|
||||||
|
.with_roles(vec!["SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/rbac/**", "POST", "")
|
||||||
|
.with_roles(vec!["SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/rbac/**", "PUT", "")
|
||||||
|
.with_roles(vec!["SuperAdmin".into()]),
|
||||||
|
RoutePermission::new("/api/rbac/**", "DELETE", "")
|
||||||
|
.with_roles(vec!["SuperAdmin".into()]),
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue