### Policy File Example (CSV) Source: https://context7.com/apache/casbin-rs/llms.txt Example of a policy file in CSV format. Defines permission rules ('p') and role assignments ('g'). ```csv # p lines define permission rules p, alice, data1, read p, bob, data2, write p, data2_admin, data2, read p, data2_admin, data2, write # g lines define role assignments g, alice, data2_admin # Domain-scoped role assignments (3-field g) # g, alice, admin, domain1 ``` -------------------------------- ### Preload Policy into Adapter Example Source: https://github.com/apache/casbin-rs/blob/master/README.md Example code demonstrating how to preload an existing policy into an adapter. This is useful for initializing the Casbin enforcer with a predefined policy. ```rust let mut enforcer = Enforcer::new("examples/rbac_model.conf", false).await.unwrap(); let mut reader = csv::Reader::from_path("examples/rbac_policy.csv").unwrap(); for result in reader.records() { let record = result.unwrap(); enforcer.add_policy(record.iter().map(|r| r.to_string()).collect()).await.unwrap(); } ``` -------------------------------- ### ACL Policy Example Source: https://github.com/apache/casbin-rs/blob/master/README.md An example policy file for the ACL model. Each line defines a permission rule specifying which subject can perform which action on which object. ```plaintext p, alice, data1, read p, bob, data2, write ``` -------------------------------- ### Install Casbin-RS with Tokio Source: https://context7.com/apache/casbin-rs/llms.txt Add Casbin-RS to your Cargo.toml with the Tokio runtime and optional features like logging and incremental role builds. ```toml [dependencies] casbin = { version = "2.18.1", features = ["runtime-tokio", "logging", "incremental"] } tokio = { version = "1", features = ["full"] } ``` -------------------------------- ### Install Casbin-RS with async-std Source: https://context7.com/apache/casbin-rs/llms.txt Add Casbin-RS to your Cargo.toml with the async-std runtime. Ensure to disable default features if not using them. ```toml [dependencies] casbin = { version = "2.18.1", default-features = false, features = ["runtime-async-std", "logging"] } ``` -------------------------------- ### Perform Access Enforcement Check in Rust Source: https://github.com/apache/casbin-rs/blob/master/README.md Integrate this code into your application logic to check if a user (subject) is authorized to perform an action on a resource. The example demonstrates how to handle both successful authorization and potential errors during the enforcement check. For multi-threaded environments, wrap the Enforcer instance in `Arc>`. ```rust let sub = "alice"; // the user that wants to access a resource. let obj = "data1"; // the resource that is going to be accessed. let act = "read"; // the operation that the user performs on the resource. if let Ok(authorized) = e.enforce((sub, obj, act)) { if authorized { // permit alice to read data1 } else { // deny the request } } else { // error occurs } ``` -------------------------------- ### Implement Multi-argument Custom Function for Range Check Source: https://github.com/apache/casbin-rs/blob/master/CUSTOM_FUNCTIONS.md Define a custom function that checks if a value falls within a specified minimum and maximum range. This example uses three `Dynamic` arguments and performs integer comparisons. ```rust e.add_function( "between", OperatorFunction::Arg3(|val: Dynamic, min: Dynamic, max: Dynamic| { let val_int = val.as_int().unwrap_or(0); let min_int = min.as_int().unwrap_or(0); let max_int = max.as_int().unwrap_or(0); (val_int >= min_int && val_int <= max_int).into() }), ); ``` -------------------------------- ### Configure Role Manager with Pattern Matching in Casbin-RS Source: https://context7.com/apache/casbin-rs/llms.txt Demonstrates setting a matching function for pattern-based role resolution and handling domain patterns. Also shows how to set a custom role manager. ```rust use casbin::prelude::*; use casbin::model::{key_match2, key_match}; #[tokio::main] async fn main() -> Result<()> { // Pattern matching: roles resolved by path pattern let e = Enforcer::new( "examples/rbac_with_pattern_model.conf", "examples/rbac_with_pattern_policy.csv", ).await?; // Set a matching function so /pen/1 is treated as a member of /pen/:id role e.get_role_manager().write().matching_fn(Some(key_match2), None); assert!(e.enforce(("alice", "/pen/1", "GET"))?); assert!(e.enforce(("alice", "/book/1", "GET"))?); assert!(!e.enforce(("bob", "/book/1", "GET"))?); // Domain pattern matching let e2 = Enforcer::new( "examples/rbac_with_pattern_domain_model.conf", "examples/rbac_with_pattern_domain_policy.csv", ).await?; e2.get_role_manager().write().matching_fn(None, Some(key_match)); assert!(e2.enforce(("alice", "domain1", "data1", "read"))?); // Custom role manager use casbin::DefaultRoleManager; use parking_lot::RwLock; use std::sync::Arc; let mut e3 = Enforcer::new( "examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv", ).await?; let new_rm = Arc::new(RwLock::new(DefaultRoleManager::new(10))); e3.set_role_manager(new_rm)?; assert!(e3.enforce(("alice", "domain1", "data1", "read"))?); Ok(()) } ``` -------------------------------- ### Casbin-rs Adapters for Policy Storage Source: https://context7.com/apache/casbin-rs/llms.txt Demonstrates various built-in adapters for policy persistence: FileAdapter for CSV files, MemoryAdapter for in-memory storage, NullAdapter for no-op, and StringAdapter for CSV strings. Also shows how to hot-swap adapters. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // FileAdapter — reads/writes CSV policy file let file_adapter = FileAdapter::new("examples/rbac_policy.csv"); let e1 = Enforcer::new("examples/rbac_model.conf", file_adapter).await?; // FileAdapter with filtered loading support let filtered_adapter = FileAdapter::new_filtered_adapter("examples/rbac_with_domains_policy.csv"); let mut e2 = Enforcer::new("examples/rbac_with_domains_model.conf", filtered_adapter).await?; e2.load_filtered_policy(Filter { p: vec!["", "domain1"], g: vec!["", "", "domain1"], }).await?; assert!(e2.enforce(("alice", "domain1", "data1", "read"))?); assert!(!e2.enforce(("bob", "domain2", "data2", "read"))?); // domain2 not loaded // MemoryAdapter — in-memory, policies added programmatically let mem_adapter = MemoryAdapter::default(); let mut e3 = Enforcer::new("examples/rbac_model.conf", mem_adapter).await?; e3.add_permission_for_user("alice", vec!["data1".into(), "read".into()]).await?; assert!(e3.enforce(("alice", "data1", "read"))?); // NullAdapter — no-op, useful for testing without persistence let null_adapter = NullAdapter::default(); let e4 = Enforcer::new("examples/basic_model.conf", null_adapter).await?; // StringAdapter — load policy from a CSV string let policy_str = "p, alice, data1, read\np, bob, data2, write\ng, alice, admin\n".to_owned(); let string_adapter = StringAdapter::new(policy_str); let e5 = Enforcer::new("examples/rbac_model.conf", string_adapter).await?; assert!(e5.enforce(("alice", "data1", "read"))?); // Hot-swap adapter at runtime let mut e6 = Enforcer::new("examples/basic_model.conf", FileAdapter::new("examples/basic_policy.csv")).await?; e6.set_adapter(MemoryAdapter::default()).await?; // reloads policy from new adapter Ok(()) } ``` -------------------------------- ### Build Casbin Models Programmatically with DefaultModel Source: https://context7.com/apache/casbin-rs/llms.txt Shows how to construct Casbin models using `DefaultModel` from a file, an inline string, or by programmatically adding definitions for request, policy, effect, and matchers. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // From file let m1 = DefaultModel::from_file("examples/rbac_model.conf").await?; // From inline string let m2 = DefaultModel::from_str(r#"[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act "#).await?; // Programmatic construction let mut m3 = DefaultModel::default(); m3.add_def("r", "r", "sub, obj, act"); m3.add_def("p", "p", "sub, obj, act"); m3.add_def("g", "g", "_, _"); m3.add_def("e", "e", "some(where (p.eft == allow))"); m3.add_def("m", "m", "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act"); let mut e = Enforcer::new(m3, MemoryAdapter::default()).await?; e.add_permission_for_user("alice", vec!["data1".into(), "read".into()]).await?; e.add_role_for_user("alice", "admin", None).await?; assert!(e.enforce(("alice", "data1", "read"))?); Ok(()) } ``` -------------------------------- ### Create Enforcer from Files or In-Memory Model Source: https://context7.com/apache/casbin-rs/llms.txt Use `Enforcer::new` to initialize an enforcer. It accepts file paths for model and policy, or in-memory `DefaultModel` and `MemoryAdapter`. Automatically loads policy from the adapter. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // From file paths (most common) let mut e = Enforcer::new( "examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv", ).await?; // From in-memory model + memory adapter let mut m = DefaultModel::default(); m.add_def("r", "r", "sub, obj, act"); m.add_def("p", "p", "sub, obj, act"); m.add_def("g", "g", "_, _"); m.add_def("e", "e", "some(where (p.eft == allow))"); m.add_def("m", "m", "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act"); let adapter = MemoryAdapter::default(); let mut e2 = Enforcer::new(m, adapter).await?; // From inline model string let m2 = DefaultModel::from_str(r#" [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act "#).await?; let e3 = Enforcer::new(m2, MemoryAdapter::default()).await?; Ok(()) } ``` -------------------------------- ### Configure Enforcer Lifecycle and Policy Management Source: https://context7.com/apache/casbin-rs/llms.txt Demonstrates enabling/disabling enforcement, logging, auto-save, and managing policy in memory. Use this for dynamic control over enforcement and policy persistence. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let mut e = Enforcer::new("examples/basic_model.conf", "examples/basic_policy.csv").await?; // Enable / disable enforcement (disabled always returns true) e.enable_enforce(false); assert!(e.enforce(("nobody", "anything", "any"))?); e.enable_enforce(true); // Logging (feature = "logging") #[cfg(feature = "logging")] e.enable_log(true); // Disable auto-save so in-memory mutations don't persist e.enable_auto_save(false); e.remove_policy(vec!["alice".into(), "data1".into(), "read".into()]).await?; e.load_policy().await?; assert!(e.enforce(("alice", "data1", "read"))?); e.enable_auto_save(true); // Save current in-memory policy back to adapter e.save_policy().await?; // Clear all policy e.clear_policy().await?; // Hot-swap model let new_model = DefaultModel::from_file("examples/basic_with_root_model.conf").await?; e.set_model(new_model).await?; assert!(e.enforce(("root", "data1", "read"))?); // Hot-swap adapter e.set_adapter(FileAdapter::new("examples/basic_inverse_policy.csv")).await?; assert!(!e.enforce(("alice", "data1", "read"))?); // Check flags assert!( e.has_auto_save_enabled()); assert!( e.has_auto_build_role_links_enabled()); assert!( e.is_enabled()); Ok(()) } ``` -------------------------------- ### Enforce with Matched Rule Explanation Source: https://context7.com/apache/casbin-rs/llms.txt The `enforce_ex` method, when the `explain` and `logging` features are enabled, returns the enforcement decision along with the specific policy rules that led to that decision. This is useful for debugging and understanding access control logic. ```rust // Cargo.toml: features = ["runtime-tokio", "logging", "explain"] use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let e = Enforcer::new("examples/rbac_model.conf", "examples/rbac_policy.csv").await?; // Returns (bool, Vec>) let (allowed, rules) = e.enforce_ex(("alice", "data1", "read"))?; assert!(allowed); assert_eq!(rules, vec![vec!["alice", "data1", "read"]]); // For role-inherited access let (allowed2, rules2) = e.enforce_ex(("alice", "data2", "read"))?; assert!(allowed2); // matched rule is from data2_admin role assert_eq!(rules2, vec![vec!["data2_admin", "data2", "read"]]); let (denied, no_rules) = e.enforce_ex(("alice", "data1", "write"))?; assert!(!denied); assert!(no_rules.is_empty()); Ok(()) } ``` -------------------------------- ### Use Custom Functions in Casbin Policy Matchers Source: https://github.com/apache/casbin-rs/blob/master/CUSTOM_FUNCTIONS.md Demonstrates how to integrate custom functions like `greaterThan` and `stringContains` directly within the Casbin policy matcher configuration (`.conf` file). ```conf [matchers] m = greaterThan(r.age, 18) && stringContains(r.path, p.path) ``` -------------------------------- ### Initialize Casbin Enforcer in Rust Source: https://github.com/apache/casbin-rs/blob/master/README.md Use this snippet to create a new Casbin enforcer instance by providing paths to the model configuration and policy files. The `enable_log(true)` call activates logging for enforcement decisions. Ensure the `tokio` runtime is set up for async operations. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let mut e = Enforcer::new("examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv").await?; e.enable_log(true); e.enforce(("alice", "domain1", "data1", "read"))?; Ok(()) } ``` -------------------------------- ### Enforcer::new Source: https://context7.com/apache/casbin-rs/llms.txt Creates a new Enforcer instance. It can load the model and policy from file paths, or from in-memory configurations. ```APIDOC ## `Enforcer::new` — Create an enforcer from files or in-memory model The primary constructor for `Enforcer`. Accepts any combination of file paths, `DefaultModel`, or `MemoryAdapter`; automatically loads policy from the adapter. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // From file paths (most common) let mut e = Enforcer::new( "examples/rbac_with_domains_model.conf", "examples/rbac_with_domains_policy.csv", ).await?; // From in-memory model + memory adapter let mut m = DefaultModel::default(); m.add_def("r", "r", "sub, obj, act"); m.add_def("p", "p", "sub, obj, act"); m.add_def("g", "g", "_, _"); m.add_def("e", "e", "some(where (p.eft == allow))"); m.add_def("m", "m", "g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act"); let adapter = MemoryAdapter::default(); let mut e2 = Enforcer::new(m, adapter).await?; // From inline model string let m2 = DefaultModel::from_str( r#"[request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [policy_effect] e = some(where (p.eft == allow)) [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act "#, ).await?; let e3 = Enforcer::new(m2, MemoryAdapter::default()).await?; Ok(()) } ``` ``` -------------------------------- ### Priority / Deny-override Model Configuration Source: https://context7.com/apache/casbin-rs/llms.txt Defines a model supporting priority-based effects and deny-overrides. The policy definition includes an 'eft' field. ```ini # examples/priority_model.conf [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act, eft [role_definition] g = _, _ [policy_effect] e = priority(p.eft) || deny [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act ``` -------------------------------- ### Casbin-RS Built-in Matcher Functions Source: https://context7.com/apache/casbin-rs/llms.txt Illustrates the usage of various built-in matcher functions like keyMatch, keyGet, keyMatch2, keyGet2, keyMatch3, keyGet3, keyMatch4, keyMatch5, regexMatch, ipMatch, and globMatch. ```rust use casbin::model::function_map::*; fn main() { // keyMatch: * wildcard, "/foo/bar" matches "/foo/*" assert!(key_match("/foo/bar", "/foo/*")); assert!(key_match("/foo/bar", "/fo*")); assert!(!key_match("/bar/foo", "/foo/*")); // keyGet: returns the * captured portion assert_eq!(key_get("/foo/bar", "/foo/*"), "bar"); // keyMatch2: :param style, "/resource1" matches "/:resource" assert!(key_match2("/foo/baz", "/foo/:bar")); assert!(key_match2("/foo/baz/foo", "/foo/:bar/foo")); // keyGet2: extract named parameter value assert_eq!(key_get2("/myid/using/myresid", "/:id/using/:resId", "id"), "myid"); // keyMatch3: {param} style assert!(key_match3("/foo/baz", "/foo/{bar}")); assert_eq!(key_get3("/resource1", "/{resource}", "resource"), "resource1"); // keyMatch4: {param} with repeated-token enforcement assert!(key_match4("/parent/123/child/123", "/parent/{id}/child/{id}")); assert!(!key_match4("/parent/123/child/456", "/parent/{id}/child/{id}")); // keyMatch5: ignores query strings assert!(key_match5("/foo/bar?status=1&type=2", "/foo/bar")); assert!(key_match5("/parent/child1?status=1", "/parent/*")); // regexMatch assert!(regex_match("foobar", "^foo.*")); // ipMatch (feature = "ip") #[cfg(feature = "ip")] assert!(ip_match("192.168.2.123", "192.168.2.0/24")); // globMatch (feature = "glob") #[cfg(feature = "glob")] { assert!(glob_match("/abc/123", "/abc/*")); assert!(!glob_match("/abc/123/456", "/abc/*")); assert!(glob_match("/abc/123/456", "/abc/**")); } } ``` -------------------------------- ### RBAC with Domains Model Configuration Source: https://context7.com/apache/casbin-rs/llms.txt Defines an RBAC model that supports domains (tenants). The role definition includes a domain field. ```ini # examples/rbac_with_domains_model.conf [request_definition] r = sub, dom, obj, act [policy_definition] p = sub, dom, obj, act [role_definition] g = _, _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub, r.dom) && r.dom == p.dom && r.obj == p.obj && r.act == p.act ``` -------------------------------- ### Manage Policy Rules with MgmtApi Source: https://context7.com/apache/casbin-rs/llms.txt Use MgmtApi for CRUD operations on policy rules. Supports single and batch add/remove, named policies, filtered removals, and grouping policies. Also includes methods for querying all rules, filtered rules, checking rule existence, and enumerating subjects, objects, actions, and roles. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let mut e = Enforcer::new("examples/rbac_model.conf", "examples/rbac_policy.csv").await?; // Add / remove single policy e.add_policy(vec!["eve".into(), "data3".into(), "read".into()]).await?; e.remove_policy(vec!["eve".into(), "data3".into(), "read".into()]).await?; // Batch add / remove e.add_policies(vec![ vec!["carol".into(), "data1".into(), "read".intoടെ], vec!["carol".into(), "data2".into(), "write".intoടെ], ]).await?; e.remove_policies(vec![ vec!["carol".into(), "data1".into(), "read".intoടെ], ]).await?; // Named policy type (p2, p3, ...) e.add_named_policy("p", vec!["frank".into(), "data1".into(), "write".into()]).await?; e.remove_named_policy("p", vec!["frank".into(), "data1".into(), "write".into()]).await?; // Remove by field filter: remove all rules where field[1] == "data2" e.remove_filtered_policy(1, vec!["data2".into()]).await?; // Add / remove role grouping e.add_grouping_policy(vec!["alice".into(), "data2_admin".into()]).await?; e.remove_grouping_policy(vec!["alice".into(), "data2_admin".into()]).await?; e.add_grouping_policies(vec![ vec!["bob".into(), "data1_admin".intoടെ], vec!["eve".into(), "data3_admin".intoടെ], ]).await?; e.remove_filtered_grouping_policy(0, vec!["bob".into()]).await?; // Query policies let all_rules = e.get_policy(); // Vec> let filtered = e.get_filtered_policy(0, vec!["alice".into()]); let has_rule = e.has_policy(vec!["alice".into(), "data1".into(), "read".into()]); // Enumerate entities let subjects = e.get_all_subjects(); // Vec let objects = e.get_all_objects(); let actions = e.get_all_actions(); let roles = e.get_all_roles(); println!("subjects: {:?}", subjects); println!("has alice->data1->read: {}", has_rule); Ok(()) } ``` -------------------------------- ### Load Filtered Policy Rules Source: https://context7.com/apache/casbin-rs/llms.txt Use `load_filtered_policy` with a `Filter` to load only specific policy rules, reducing memory usage for large, multi-tenant configurations. Ensure the adapter supports filtering. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // Use a filtered adapter so Enforcer::new doesn't auto-load full policy let adapter = FileAdapter::new_filtered_adapter("examples/rbac_with_domains_policy.csv"); let mut e = Enforcer::new("examples/rbac_with_domains_model.conf", adapter).await?; // Load only domain1 policies e.load_filtered_policy(Filter { p: vec!["", "domain1"], g: vec!["", "", "domain1"], }).await?; assert!( e.enforce(("alice", "domain1", "data1", "read"))?); assert!( e.enforce(("alice", "domain1", "data1", "write"))?); // domain2 rules were not loaded assert!(!e.enforce(("bob", "domain2", "data2", "read"))?); assert!( e.is_filtered()); Ok(()) } ``` -------------------------------- ### RBAC Model Configuration Source: https://context7.com/apache/casbin-rs/llms.txt Defines a Role-Based Access Control (RBAC) model for Casbin. Includes role definition for hierarchical roles. ```ini # examples/rbac_model.conf [request_definition] r = sub, obj, act [policy_definition] p = sub, obj, act [role_definition] g = _, _ [policy_effect] e = some(where (p.eft == allow)) [matchers] m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act ``` -------------------------------- ### enforce_ex Source: https://context7.com/apache/casbin-rs/llms.txt Enforces a request and returns the decision along with the specific policy rules that led to that decision. Requires the 'explain' and 'logging' features to be enabled. ```APIDOC ## `enforce_ex` — Enforce with matched rule explanation (feature: `explain` + `logging`) Returns the decision along with the matching policy rules that caused it. ```rust // Cargo.toml: features = ["runtime-tokio", "logging", "explain"] use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let e = Enforcer::new("examples/rbac_model.conf", "examples/rbac_policy.csv").await?; // Returns (bool, Vec>) let (allowed, rules) = e.enforce_ex(("alice", "data1", "read"))?; assert!(allowed); assert_eq!(rules, vec![vec!["alice", "data1", "read"]]); // For role-inherited access let (allowed2, rules2) = e.enforce_ex(("alice", "data2", "read"))?; assert!(allowed2); // matched rule is from data2_admin role assert_eq!(rules2, vec![vec!["data2_admin", "data2", "read"]]); let (denied, no_rules) = e.enforce_ex(("alice", "data1", "write"))?; assert!(!denied); assert!(no_rules.is_empty()); Ok(()) } ``` ``` -------------------------------- ### Add Casbin-RS to Cargo.toml Source: https://github.com/apache/casbin-rs/blob/master/README.md Add the casbin package to your project's Cargo.toml file. Ensure you use the correct version and feature flags for your project. Tokio is also listed as a dependency. ```toml [dependencies] casbin = { version = "2.8.0", default-features = false, features = ["runtime-async-std", "logging", "incremental"] } tokio = { version = "1.10.0", features = ["fs", "io-util"] } ``` -------------------------------- ### Multi-Model Enforcement with EnforceWithContext Source: https://context7.com/apache/casbin-rs/llms.txt Use `enforce_with_context` with an `EnforceContext` to evaluate requests against named sections in a multi-model configuration. This allows a single enforcer to manage different policy sets. ```rust use casbin::prelude::*; use casbin::EnforceContext; #[tokio::main] async fn main() -> Result<()> { // multi_section_model.conf defines r/p/m AND r2/p2/m2 let e = Enforcer::new( "examples/multi_section_model.conf", "examples/multi_section_policy.csv", ).await?; // Default section (r, p, m) assert!(e.enforce(("alice", "read", "project1"))?); // Named section 2 (r2, p2, m2) let ctx = EnforceContext::new("2"); assert!(e.enforce_with_context(ctx, ("james", "execute"))?); Ok(()) } ``` -------------------------------- ### load_filtered_policy - Partial policy loading Source: https://context7.com/apache/casbin-rs/llms.txt The `load_filtered_policy` method allows for partial loading of policy rules based on specified filters, which is useful for optimizing performance in large, multi-tenant environments. ```APIDOC ## `load_filtered_policy` — Partial policy loading Loads only the policy rules matching the given field filter, reducing memory usage in large multi-tenant deployments. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { // Use a filtered adapter so Enforcer::new doesn't auto-load full policy let adapter = FileAdapter::new_filtered_adapter("examples/rbac_with_domains_policy.csv"); let mut e = Enforcer::new("examples/rbac_with_domains_model.conf", adapter).await?; // Load only domain1 policies e.load_filtered_policy(Filter { p: vec!["", "domain1"], // filter p rules: field[1] == "domain1" g: vec!["", "", "domain1"], // filter g rules: field[2] == "domain1" }).await?; assert!( e.enforce(("alice", "domain1", "data1", "read"))?); assert!( e.enforce(("alice", "domain1", "data1", "write"))?); // domain2 rules were not loaded assert!(!e.enforce(("bob", "domain2", "data2", "read"))?); assert!( e.is_filtered()); // marks enforcer as filtered Ok(()) } ``` ``` -------------------------------- ### Manage Roles and Permissions with RbacApi Source: https://context7.com/apache/casbin-rs/llms.txt Utilize RbacApi for higher-level role and permission management. Supports assigning/revoking roles for users, domain-scoped assignments, and querying roles (direct and implicit). Also includes methods for managing user permissions, reverse lookups, and deleting users/roles. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let mut e = Enforcer::new("examples/rbac_model.conf", "examples/rbac_policy.csv").await?; // Assign / revoke roles e.add_role_for_user("alice", "data1_admin", None).await?; e.add_roles_for_user("bob", vec!["data1_admin".into(), "data2_admin".into()], None).await?; e.delete_role_for_user("alice", "data1_admin", None).await?; e.delete_roles_for_user("bob", None).await?; // Domain-scoped role assignment e.add_role_for_user("alice", "admin", Some("domain1")).await?; // Query roles let roles = e.get_roles_for_user("alice", None); // direct roles let implicit = e.get_implicit_roles_for_user("alice", None); // recursive hierarchy let users_in_role = e.get_users_for_role("data2_admin", None); let has_role = e.has_role_for_user("alice", "data2_admin", None); // Permissions e.add_permission_for_user("bob", vec!["data3".into(), "read".into()]).await?; e.add_permissions_for_user("eve", vec![ vec!["data1".into(), "read".intoടെ], vec!["data2".into(), "write".intoടെ], ]).await?; e.delete_permission_for_user("bob", vec!["data3".into(), "read".into()]).await?; e.delete_permissions_for_user("eve").await?; let perms = e.get_permissions_for_user("alice", None); let implicit_perms = e.get_implicit_permissions_for_user("alice", None); let has_perm = e.has_permission_for_user("alice", vec!["data1".into(), "read".into()]); // Reverse lookup: who can access data2/write? let users = e.get_implicit_users_for_permission(vec!["data2".into(), "write".into()]).await; println!("alice roles: {:?}", roles); println!("implicit roles: {:?}", implicit); println!("who can data2/write: {:?}", users); // Delete user and role entirely e.delete_user("alice").await?; e.delete_role("data2_admin").await?; Ok(()) } ``` -------------------------------- ### MgmtApi: Policy Management Source: https://context7.com/apache/casbin-rs/llms.txt Provides full CRUD access to policy rules. Users can add, remove, and query individual or batch policies, as well as manage named policies and perform filtered removals. ```APIDOC ## MgmtApi: Policy Management Provides full CRUD access to policy rules. Users can add, remove, and query individual or batch policies, as well as manage named policies and perform filtered removals. ### Add Policy - **Method**: `add_policy` - **Description**: Adds a single policy rule. - **Parameters**: `Vec` representing the rule fields. ### Remove Policy - **Method**: `remove_policy` - **Description**: Removes a single policy rule. - **Parameters**: `Vec` representing the rule fields. ### Add Policies - **Method**: `add_policies` - **Description**: Adds multiple policy rules in a batch. - **Parameters**: `Vec>` representing the rules. ### Remove Policies - **Method**: `remove_policies` - **Description**: Removes multiple policy rules in a batch. - **Parameters**: `Vec>` representing the rules. ### Add Named Policy - **Method**: `add_named_policy` - **Description**: Adds a single policy rule to a named policy type. - **Parameters**: `policy_type: String`, `rule: Vec`. ### Remove Named Policy - **Method**: `remove_named_policy` - **Description**: Removes a single policy rule from a named policy type. - **Parameters**: `policy_type: String`, `rule: Vec`. ### Remove Filtered Policy - **Method**: `remove_filtered_policy` - **Description**: Removes policy rules that match a field filter. - **Parameters**: `field_index: usize`, `field_values: Vec`. ### Get Policy - **Method**: `get_policy` - **Description**: Retrieves all policy rules. - **Returns**: `Vec>`. ### Get Filtered Policy - **Method**: `get_filtered_policy` - **Description**: Retrieves policy rules filtered by a specific field. - **Parameters**: `field_index: usize`, `field_values: Vec`. - **Returns**: `Vec>`. ### Has Policy - **Method**: `has_policy` - **Description**: Checks if a specific policy rule exists. - **Parameters**: `rule: Vec`. - **Returns**: `bool`. ### Get All Subjects - **Method**: `get_all_subjects` - **Description**: Retrieves all unique subjects from policies. - **Returns**: `Vec`. ### Get All Objects - **Method**: `get_all_objects` - **Description**: Retrieves all unique objects from policies. - **Returns**: `Vec`. ### Get All Actions - **Method**: `get_all_actions` - **Description**: Retrieves all unique actions from policies. - **Returns**: `Vec`. ### Get All Roles - **Method**: `get_all_roles` - **Description**: Retrieves all unique roles from policies. - **Returns**: `Vec`. ``` -------------------------------- ### Migrate Custom Function from ImmutableString to Dynamic Source: https://github.com/apache/casbin-rs/blob/master/CUSTOM_FUNCTIONS.md Update custom functions to use `Dynamic` instead of `ImmutableString` for arguments. Convert `Dynamic` arguments to strings using `.to_string()` before use. ```rust e.add_function( "myFunc", OperatorFunction::Arg2( |s1: ImmutableString, s2: ImmutableString| { // logic here true.into() } ), ); ``` ```rust e.add_function( "myFunc", OperatorFunction::Arg2(|s1: Dynamic, s2: Dynamic| { let str1 = s1.to_string(); let str2 = s2.to_string(); // logic here true.into() }), ); ``` -------------------------------- ### CoreApi - Enforcer Configuration and Lifecycle Source: https://context7.com/apache/casbin-rs/llms.txt The CoreApi trait provides essential functionalities for managing an Enforcer's lifecycle, including loading and saving policies, enabling/disabling enforcement, and hot-swapping models and adapters. ```APIDOC ## CoreApi — Enforcer configuration and lifecycle `CoreApi` is the base trait providing model/adapter swaps, policy load/save, and enable/disable controls. ```rust use casbin::prelude::*; #[tokio::main] async fn main() -> Result<()> { let mut e = Enforcer::new("examples/basic_model.conf", "examples/basic_policy.csv").await?; // Enable / disable enforcement (disabled always returns true) e.enable_enforce(false); assert!(e.enforce(("nobody", "anything", "any"))?); e.enable_enforce(true); // Logging (feature = "logging") #[cfg(feature = "logging")] e.enable_log(true); // Disable auto-save so in-memory mutations don't persist e.enable_auto_save(false); e.remove_policy(vec!["alice".into(), "data1".into(), "read".into()]).await?; e.load_policy().await?; // reload restores alice's rule assert!(e.enforce(("alice", "data1", "read"))?); e.enable_auto_save(true); // Save current in-memory policy back to adapter e.save_policy().await?; // Clear all policy e.clear_policy().await?; // Hot-swap model let new_model = DefaultModel::from_file("examples/basic_with_root_model.conf").await?; e.set_model(new_model).await?; assert!(e.enforce(("root", "data1", "read"))?); // root superuser now allowed // Hot-swap adapter e.set_adapter(FileAdapter::new("examples/basic_inverse_policy.csv")).await?; assert!(!e.enforce(("alice", "data1", "read"))?); // inverse policy // Check flags assert!( e.has_auto_save_enabled()); assert!( e.has_auto_build_role_links_enabled()); assert!( e.is_enabled()); Ok(()) } ``` ``` -------------------------------- ### Implement String Comparison Custom Function Source: https://github.com/apache/casbin-rs/blob/master/CUSTOM_FUNCTIONS.md Register a custom function for direct string comparison by converting `Dynamic` arguments to `String`. This function checks for equality between two string inputs. ```rust e.add_function( "stringMatch", OperatorFunction::Arg2(|s1: Dynamic, s2: Dynamic| { let str1 = s1.to_string(); let str2 = s2.to_string(); (str1 == str2).into() }), ); ``` -------------------------------- ### enforce_with_context Source: https://context7.com/apache/casbin-rs/llms.txt Performs enforcement using a named section suffix, allowing a single enforcer to manage multiple policy sets. ```APIDOC ## `enforce_with_context` — Multi-model enforcement Enforces using a named section suffix, enabling a single enforcer to run different policy sets (e.g., `r2`, `p2`, `m2`). ```rust use casbin::prelude::*; use casbin::EnforceContext; #[tokio::main] async fn main() -> Result<()> { // multi_section_model.conf defines r/p/m AND r2/p2/m2 let e = Enforcer::new( "examples/multi_section_model.conf", "examples/multi_section_policy.csv", ).await?; // Default section (r, p, m) assert!(e.enforce(("alice", "read", "project1"))?); // Named section 2 (r2, p2, m2) let ctx = EnforceContext::new("2"); assert!(e.enforce_with_context(ctx, ("james", "execute"))?); Ok(()) } ``` ``` -------------------------------- ### RbacApi: Permission Management Source: https://context7.com/apache/casbin-rs/llms.txt Manages user permissions, including adding, revoking, and querying permissions, both directly and implicitly. ```APIDOC ## RbacApi: Permission Management Manages user permissions, including adding, revoking, and querying permissions, both directly and implicitly. ### Add Permission for User - **Method**: `add_permission_for_user` - **Description**: Grants a specific permission to a user. - **Parameters**: `user: &str`, `permission: Vec<&str>`. ### Add Permissions for User - **Method**: `add_permissions_for_user` - **Description**: Grants multiple permissions to a user. - **Parameters**: `user: &str`, `permissions: Vec>`. ### Delete Permission for User - **Method**: `delete_permission_for_user` - **Description**: Revokes a specific permission from a user. - **Parameters**: `user: &str`, `permission: Vec<&str>`. ### Delete Permissions for User - **Method**: `delete_permissions_for_user` - **Description**: Revokes all permissions from a user. - **Parameters**: `user: &str`. ### Get Permissions for User - **Method**: `get_permissions_for_user` - **Description**: Retrieves the direct permissions granted to a user. - **Parameters**: `user: &str`, `domain: Option<&str>`. - **Returns**: `Vec>`. ### Get Implicit Permissions for User - **Method**: `get_implicit_permissions_for_user` - **Description**: Retrieves all permissions for a user, including those inherited through roles, optionally within a specific domain. - **Parameters**: `user: &str`, `domain: Option<&str>`. - **Returns**: `Vec>`. ### Has Permission for User - **Method**: `has_permission_for_user` - **Description**: Checks if a user has a specific permission. - **Parameters**: `user: &str`, `permission: Vec<&str>`. - **Returns**: `bool`. ### Get Implicit Users for Permission - **Method**: `get_implicit_users_for_permission` - **Description**: Retrieves all users who have a specific permission, considering role hierarchies. - **Parameters**: `permission: Vec<&str>`. - **Returns**: `Result>`. ``` -------------------------------- ### MgmtApi: Grouping Policy Management Source: https://context7.com/apache/casbin-rs/llms.txt Manages user-role assignments (grouping policies). Supports adding, removing, and filtering grouping policies. ```APIDOC ## MgmtApi: Grouping Policy Management Manages user-role assignments (grouping policies). Supports adding, removing, and filtering grouping policies. ### Add Grouping Policy - **Method**: `add_grouping_policy` - **Description**: Adds a single user-role assignment. - **Parameters**: `Vec` representing the assignment fields. ### Remove Grouping Policy - **Method**: `remove_grouping_policy` - **Description**: Removes a single user-role assignment. - **Parameters**: `Vec` representing the assignment fields. ### Add Grouping Policies - **Method**: `add_grouping_policies` - **Description**: Adds multiple user-role assignments in a batch. - **Parameters**: `Vec>` representing the assignments. ### Remove Filtered Grouping Policy - **Method**: `remove_filtered_grouping_policy` - **Description**: Removes grouping policies that match a field filter. - **Parameters**: `field_index: usize`, `field_values: Vec`. ``` -------------------------------- ### ACL Model Configuration Source: https://github.com/apache/casbin-rs/blob/master/README.md This is a basic Access Control List (ACL) model configuration for Casbin. It defines the request structure, policy structure, effect of policies, and the matching logic. ```ini # Request definition [request_definition] r = sub, obj, act # Policy definition [policy_definition] p = sub, obj, act # Policy effect [policy_effect] e = some(where (p.eft == allow)) # Matchers [matchers] m = r.sub == p.sub && r.obj == p.obj && r.act == p.act ``` -------------------------------- ### Add a Basic Custom Function in Casbin-RS Source: https://github.com/apache/casbin-rs/blob/master/CUSTOM_FUNCTIONS.md Register a custom function with the Enforcer using `add_function`. The function should accept `Dynamic` arguments and return a `Dynamic` value. Ensure necessary imports are included. ```rust use casbin::prelude::*; use rhai::Dynamic; // Create your enforcer let mut e = Enforcer::new("model.conf", "policy.csv").await?; // Add a custom function e.add_function( "myFunction", OperatorFunction::Arg2(|arg1: Dynamic, arg2: Dynamic| { // Your custom logic here true.into() // Return a Dynamic value }), ); ```