use axum::{
extract::{Path, State},
http::StatusCode,
routing::get,
Router,
};
use role_system::{RoleSystem, Role, Permission, Subject, Resource};
use std::sync::Arc;
#[derive(Clone)]
struct AppState {
role_system: Arc<RoleSystem>,
}
async fn check_access(
State(state): State<AppState>,
Path((user_id, resource_id)): Path<(String, String)>,
) -> Result<&'static str, StatusCode> {
let subject = Subject::new(&user_id);
let resource = Resource::new(&resource_id, "documents");
match state.role_system.check_permission(&subject, "read", &resource) {
Ok(true) => Ok("Access granted"),
Ok(false) => Err(StatusCode::FORBIDDEN),
Err(_) => Err(StatusCode::INTERNAL_SERVER_ERROR),
}
}
#[tokio::main]
async fn main() {
let mut role_system = RoleSystem::new();
let reader = Role::new("reader")
.add_permission(Permission::new("read", "documents"));
role_system.register_role(reader).unwrap();
let state = AppState {
role_system: Arc::new(role_system),
};
let app = Router::new()
.route("/access/:user_id/:resource_id", get(check_access))
.with_state(state);
axum::Server::bind(&"127.0.0.1:8080".parse().unwrap())
.serve(app.into_make_service())
.await
.unwrap();
}