moonbit-casbin

    Casbin-style authorization engine in MoonBit: model-driven policy configuration, matcher and effect evaluation, RBAC role hierarchy, and an in-memory policy store.

    casbin
    authorization
    access-control
    rbac
    abac
    policy
    security
    moonbit
    Download zip
    Version
    0.1.0
    License
    Apache-2.0
    Last updated
    4 hours ago
    Downloads
    1

    Dependencies

    #moonbit-casbin

    Casbin-style authorization engine in MoonBit: model-driven policy configuration, matcher and effect evaluation, RBAC role hierarchy, and an in-memory policy store.

    Project/module: xiguaAp6y3/moonbit-casbin Repository: https://github.com/xiguaAp6y3/moonbit-casbin Version: 0.1.0 License: Apache-2.0

    #中文项目介绍

    moonbit-casbin 是使用 MoonBit 实现的 Casbin 风格授权引擎。它按照与 Casbin 相同的模型配置格式([request_definition][policy_definition] [role_definition][policy_effect][matchers])加载授权模型,并自带 matcher 表达式求值引擎;后续将提供访问决策 API(enforce)、策略存储与 管理接口。

    当前已实现:

    • 配置解析:完整解析 Casbin 模型文件的小型 INI 方言,支持 # / ; 注释、空行、重复节合并、重复键按声明顺序保留、CRLF 换行;
    • 模型加载:把配置装载为请求定义、策略定义、角色定义、策略 effect 与 matcher 断言,校验必需的节和取值(定义键前缀、token 标识符、effect 唯一性);
    • Matcher 表达式引擎:自研词法器、Pratt 解析器与树遍历求值器,支持 比较、&& / ||(短路)、in 列表、字段访问、算术与字符串拼接; 函数注册表可通过 FunctionRegistry::add 扩展;语法错误携带字符偏移;
    • 判定链路r.subr_sub 等预处理、内存策略存储(保序 + 去重)、 CSV 策略解析(RFC 4180 引号子集)、5 种 effect 聚合 (allow-override / deny-override / allow-and-deny / priority / subjectPriority)、Enforcer::enforce 逐行匹配与提前终止;
    • RBAC:角色层级(BFS 可达性 + maxHierarchyLevel 限制)、角色域隔离 g = _, _, _)、g / g2 函数自动注入、分组策略变更后角色链接自动 重建(可关闭);
    • 管理 API:策略与角色增删查(含空串通配的过滤查询)、隐式角色与隐式 权限查询、delete_user / delete_role 级联删除;
    • 内置函数keyMatch / keyMatch2..keyMatch5keyGet / keyGet2 / keyGet3regexMatchglobMatchipMatch(IPv4/IPv6 + CIDR),用例表对齐 Casbin 官方测试;
    • 结构化错误:配置/模型/策略/匹配表达式/判定六类错误分类 ConfigSyntaxModelValidationPolicySyntaxMatcherSyntax MatcherEvalEnforcement),语法错误携带行号或字符偏移;
    • 依赖精简:仅依赖 MoonBit 标准库与官方 moonbitlang/regexp (Apache-2.0),wasm / wasm-gc / js / native 四目标通过检查、 构建与测试;
    • 持续集成:GitHub Actions 严格流水线(格式检查、--deny-warn 检查、 四目标构建与测试、打包清单)。

    #English Summary

    moonbit-casbin is a Casbin-style authorization engine implemented in MoonBit. It loads the Casbin model configuration format (request, policy, and role definitions, policy effect, matchers), ships its own matcher expression engine (lexer, Pratt parser, tree-walking evaluator with short-circuit logic, in lists, field access, and an extensible function registry), enforces requests end to end (accessor preprocessing, an in-memory policy store, a CSV policy adapter, the five Casbin policy effects, and Enforcer::enforce with per-row matching and early termination), implements RBAC (role hierarchy with a configurable depth limit, role domains, g / g2 function injection, management APIs for policies, roles, implicit roles, implicit permissions, and cascading deletes), and provides the full built-in operator set: keyMatch / keyMatch2..keyMatch5, keyGet / keyGet2 / keyGet3, regexMatch, globMatch, and ipMatch for IPv4/IPv6 with CIDR. It is not a port of the Casbin Go source code; the model format and semantics are reimplemented from the public documentation. The library depends only on the MoonBit standard library and the official moonbitlang/regexp package, and passes check, build, and test on wasm, wasm-gc, js, and native.

    #Casbin 简介

    Casbin 是一个广泛使用的授权库,把访问控制策略从业务代码中抽离为模型 (model)与策略(policy)两部分:

    • 模型描述"如何判断":请求参数(r = sub, obj, act)、策略参数 p = sub, obj, act)、角色定义(g = _, _)、匹配表达式 m = g(r.sub, p.sub) && r.obj == p.obj && r.act == p.act)以及 聚合方式(e = some(where (p.eft == allow)));
    • 策略描述"判断什么":一行行具体规则,例如 p, alice, data1, readg, alice, admin

    同一个模型可以支撑 ACL、RBAC、ABAC 等不同授权风格,切换风格通常只需换 模型文件,不改业务代码。参考实现见 casbin/casbin

    #项目价值

    • 为 MoonBit 补齐模型驱动的授权基础件:Web 框架、服务框架与工具类项目 可以复用同一套模型与策略语义,避免各自造轮子;
    • 与 Casbin 生态格式兼容:现有模型文件和策略文件的组织方式可以直接沿用, 迁移成本低;
    • 结构化错误与显式校验:配置错误在加载期暴露,并给出可定位的行号;
    • 多后端可用:核心库不依赖宿主能力,可编译到 wasm / wasm-gc / js / native,适合服务端与边缘场景。

    #功能支持矩阵

    功能状态
    模型配置解析(INI 方言、注释、重复节、CRLF)已实现并测试
    模型加载与校验(r / p / g / e / m已实现并测试
    Matcher 表达式求值(词法 / Pratt 语法 / 短路求值 / 函数注册表)已实现并测试
    判定链路(预处理 / 策略校验 / 逐行匹配 / 提前终止)已实现并测试
    策略 effect(allow-override / deny-override / allow-and-deny / priority / subjectPriority)已实现并测试
    RBAC 角色层级与角色域(g / g2、domain、层级上限)已实现并测试
    策略与角色管理 API(增删查、通配过滤、隐式角色与权限、级联删除)已实现并测试
    内存策略存储(保序、去重)与 CSV 策略解析已实现并测试
    内置函数 keyMatch / keyMatch2..keyMatch5keyGet / keyGet2 / keyGet3已实现并测试
    内置函数 regexMatchglobMatchipMatch(IPv4/IPv6 + CIDR)已实现并测试
    结构化错误(六类错误 + 行号或偏移)已实现并测试
    角色名模式匹配(AddMatchingFunc / 域匹配函数)计划中
    CLI 工具计划中

    #不支持内容

    当前代码(v0.4)不包含

    • 角色名模式匹配(Casbin 的 AddMatchingFunc / AddDomainMatchingFunc): has_link 按名字精确比较;
    • eval() 内置函数、条件角色(temporal roles)与 EnforceContext
    • 持久化适配器(数据库、Redis 等)与 Watcher(策略只驻留内存,由调用方 提供文本或逐条添加);
    • 分布式部署、过滤器策略加载与自适应策略;
    • 策略管理 HTTP 接口、Dashboard 与 CLI 工具。

    上表"计划中"的能力按 Roadmap 逐步实现;在实现之前,README 与发布说明 不会声称支持。

    #本地使用方式

    环境要求:MoonBit 工具链(含 wasm / wasm-gc / js / native 目标)。

    git clone https://github.com/xiguaAp6y3/moonbit-casbin.git cd moonbit-casbin moon test

    四目标严格验证(与 CI 相同):

    moon fmt --check moon check --target all --deny-warn moon build --target all moon test --target all --deny-warn

    #快速开始

    加载一个 RBAC 模型(rbac_model.conf 的内容与 Casbin 官方示例一致):

    let text =
    #|[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

    let model = Model::from_config(Config::parse(text).unwrap()).unwrap()
    let request = model.request_definition("r").unwrap()
    // request.tokens() == ["sub", "obj", "act"]
    let role = model.role_definition("g").unwrap()
    // role.tokens() == ["_", "_"]

    错误处理:Config::parse 只返回 ConfigSyntaxModel::from_config 只返回 ModelValidation,错误携带可读描述与行号(如适用)。

    match Config::parse("r = sub, obj, act") {
    Err(error) => {
    // error.kind() == ConfigSyntax
    // error.line() == 1
    // error.message() == "entry outside of any section"
    }
    Ok(_) => ()
    }

    Matcher 表达式引擎可以独立使用。标识符是 Casbin 预处理后的名字 r.sub 写作 r_sub),求值时的取值方式由调用方提供:

    let value = parse_matcher("keyMatch(r_obj, p_obj) && !denied")
    .unwrap()
    .eval(
    (name) =>
    match name {
    "r_obj" => Some(Value::String("/foo/bar"))
    "p_obj" => Some(Value::String("/foo/*"))
    "denied" => Some(Value::Bool(false))
    _ => None
    },
    builtin_functions(),
    )
    .unwrap()
    // value == Value::Bool(true)

    端到端判定:模型 + 策略文本 → enforce

    let model_text =
    #|[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

    let model = Model::from_config(Config::parse(model_text).unwrap()).unwrap()
    let enforcer = Enforcer::new(model).unwrap()
    let policy =
    #|p, alice, data1, read
    #|p, bob, data2, write
    enforcer.load_policy_from_text(policy).unwrap()
    assert_true(enforcer.enforce(["alice", "data1", "read"]).unwrap())
    assert_true(!enforcer.enforce(["alice", "data1", "write"]).unwrap())

    RBAC:g 规则定义角色,判定期自动解析角色层级,管理 API 可在线增删。

    let rbac_model_text =
    #|[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

    let model = Model::from_config(Config::parse(rbac_model_text).unwrap()).unwrap()
    let enforcer = Enforcer::new(model).unwrap()
    let policy =
    #|p, alice, data1, read
    #|p, data2_admin, data2, read
    #|g, alice, data2_admin
    enforcer.load_policy_from_text(policy).unwrap()
    assert_true(enforcer.enforce(["alice", "data2", "read"]).unwrap()) // 通过角色
    assert_true(enforcer.add_role_for_user("bob", "data2_admin").unwrap())
    assert_true(enforcer.get_implicit_roles_for_user("bob") == ["data2_admin"])
    assert_true(enforcer.enforce(["bob", "data2", "read"]).unwrap())
    assert_true(enforcer.delete_role_for_user("bob", "data2_admin").unwrap())
    assert_true(!enforcer.enforce(["bob", "data2", "read"]).unwrap())

    #开发与验证

    moon check --target all --deny-warn # 清零警告的严格检查 moon fmt # 格式化 moon test --target all --deny-warn # 四目标测试 moon package --list # 打包清单

    可运行示例:

    moon run examples/quickstart # ACL / RBAC / 管理 API moon run examples/matchers # keyMatch2 / regexMatch / ipMatch / globMatch

    #测试结果

    • 具名测试:97 个(配置解析 10、模型加载 8、词法 5、语法 6、求值 8、 内置函数 5、预处理 4、effect 5、策略存储 4、CSV 适配器 4、判定 12、 角色管理器 5、RBAC 端到端 7、扩展运算符 11、IP 3);
    • keyMatch / keyGetkeyMatch2..keyMatch5 / keyGet2 / keyGet3 / regexMatch / globMatch / ipMatch 用例表、EscapeAssertion / RemoveComments 用例表、RBAC 模型与角色 API 链路均移植自 Casbin 官方 测试与示例,逐项来源见 THIRD_PARTY_NOTICES.md
    • wasm / wasm-gc / js / native 四目标:check / build / test 均通过,0 errors,0 warnings。

    #目录结构

    ├── .github/workflows/ CI 与发布流水线 ├── examples/ 可运行示例(quickstart、matchers) ├── error.mbt 结构化错误类型 ├── config.mbt 模型配置解析 ├── model.mbt 模型加载与校验 ├── preprocess.mbt matcher/effect 文本预处理 ├── value.mbt 求值器的运行时值模型 ├── expr.mbt matcher 表达式 AST ├── lexer.mbt matcher 词法器 ├── parser.mbt matcher Pratt 解析器 ├── eval.mbt matcher 求值器 ├── functions.mbt 函数注册表与内置函数入口 ├── builtin_operators.mbt 正则/glob 类内置运算符 ├── ip.mbt IPv4/IPv6 与 CIDR 匹配 ├── effect.mbt policy effect 与效果聚合 ├── policy.mbt 内存策略存储 ├── adapter_csv.mbt CSV 策略解析 ├── enforcer.mbt 判定核心与角色链接 ├── role_manager.mbt 角色图与角色管理器 ├── management_api.mbt 策略与角色管理 API ├── *_test.mbt 黑盒测试(含 lexer_wbtest.mbt 白盒测试) ├── moon.mod / moon.pkg 模块清单 └── LICENSE / README.md

    #Roadmap

    • v0.1:配置解析、模型加载、结构化错误、CI。
    • v0.2:matcher 表达式引擎、判定链路(预处理、策略存储、CSV 适配器、 effect 聚合、enforce)。
    • v0.3:RBAC 角色层级与角色域、g / g2 注入、策略与角色管理 API、 隐式角色与权限、级联删除。
    • v0.4(当前):内置匹配函数补齐(keyMatch2..keyMatch5keyGet2 / keyGet3regexMatchglobMatchipMatch)与两个可运行示例。

    后续计划(尚未开始):CLI 工具、持久化适配器、角色名模式匹配、eval() EnforceContext

    #移植说明

    • 参考项目名称:Casbin(casbin/casbin);
    • 原项目链接:https://github.com/casbin/casbin ;
    • 原项目许可证:Apache-2.0;
    • 本项目许可证:Apache-2.0;
    • 参考范围:模型配置格式与判定语义按 Casbin 公开文档重新实现,不复制 Go 源码;keyMatch / keyGet 的用例表已移植自 Casbin 官方测试 util/builtin_operators_test.go),逐项来源与范围见 THIRD_PARTY_NOTICES.md

    #发布状态

    截至项目立项时对 MoonBit 生态的公开检索(GitHub language:moonbit 仓库与 mooncakes.io 注册表),未发现 Casbin 风格授权引擎的完整实现。这不是绝对 保证,仅代表立项时检索到的公开信息。

    #License

    Apache-2.0,见 LICENSE

    CasbinError

    pub(all) suberror CasbinError {
    CasbinError(CasbinErrorKind, String, Int, Int)
    }

    A structured error returned by every public API and raised internally.

    CasbinError::kind

    The error category.

    CasbinError::line

    fn CasbinError::line(self : CasbinError) -> Int

    The 1-based configuration line, or 0 when not meaningful.

    CasbinError::message

    fn CasbinError::message(self : CasbinError) -> String

    A short, caller-visible description.

    CasbinError::offset

    fn CasbinError::offset(self : CasbinError) -> Int

    The 0-based character offset in an expression, or 0 when not meaningful.

    Assertion

    pub(all) struct Assertion {
    key : String
    value : String
    tokens : Array[String]
    } derive(Eq,
    Debug
    )

    One assertion in the model: a definition (r, p, g) or an expression (e, m).

    Assertion::key

    fn Assertion::key(self : Assertion) -> String

    The assertion key, for example r, p, g, e, or m.

    Assertion::tokens

    fn Assertion::tokens(self : Assertion) -> Array[String]

    The comma-separated tokens of a definition assertion, trimmed and in declaration order; empty for expression assertions.

    Assertion::value

    fn Assertion::value(self : Assertion) -> String

    The raw value as written in the configuration.

    BinaryOp

    pub(all) enum BinaryOp {
    Or
    And
    Eq
    NotEq
    In
    Less
    LessEq
    Greater
    GreaterEq
    Add
    Sub
    Mul
    Div
    Mod
    } derive(Eq,
    Debug
    )

    Binary operators, lowest precedence first.

    CasbinErrorKind

    pub(all) enum CasbinErrorKind {
    ConfigSyntax
    ModelValidation
    PolicySyntax
    MatcherSyntax
    MatcherEval
    Enforcement
    } derive(Eq,
    Debug
    )

    The broad category of a CasbinError.

    Config

    pub(all) struct Config {
    sections : Array[ConfigSection]
    } derive(
    Debug
    )

    Parsed Casbin configuration (INI-style model file).

    Config::entries

    fn Config::entries(self : Config, section : String) -> Array[ConfigEntry]

    The entries of section in declaration order; empty when the section is absent.

    Config::get

    fn Config::get(self : Config, section : String, key : String) -> String?

    The value of key in section, or None when either is absent. When a key appears several times the first occurrence wins.

    Config::parse

    fn Config::parse(text : String) -> Result[Config, CasbinError]

    Parses Casbin model configuration text.

    Returns Err(CasbinErrorKind::ConfigSyntax) for malformed text; the error carries the 1-based line number.

    Config::section_names

    fn Config::section_names(self : Config) -> Array[String]

    The names of all declared sections in declaration order.

    ConfigEntry

    pub(all) struct ConfigEntry {
    key : String
    value : String
    } derive(
    Debug
    )

    One key = value entry inside a configuration section.

    ConfigEntry::key

    fn ConfigEntry::key(self : ConfigEntry) -> String

    The entry key.

    ConfigEntry::value

    fn ConfigEntry::value(self : ConfigEntry) -> String

    The entry value with surrounding whitespace removed.

    ConfigSection

    pub(all) struct ConfigSection {
    name : String
    entries : Array[ConfigEntry]
    } derive(
    Debug
    )

    A named configuration section with its entries in declaration order.

    Effect

    pub(all) enum Effect {
    Allow
    Indeterminate
    Deny
    } derive(Eq,
    Debug
    )

    The decision contributed by one policy row, or by the single-evaluation branch when the matcher does not reference the policy.

    EffectExpression

    pub(all) enum EffectExpression {
    AllowOverride
    DenyOverride
    AllowAndDeny
    Priority
    SubjectPriority
    } derive(Eq,
    Debug
    )

    The five policy effect expressions Casbin supports.

    EffectExpression::parse

    fn EffectExpression::parse(text : String) -> EffectExpression?

    Parses the canonical effect strings; the text must already be preprocessed (p.eft escaped to p_eft).

    Enforcer

    pub(all) struct Enforcer {
    model : Model
    store : PolicyStore
    effect : EffectExpression
    functions : FunctionRegistry
    matcher : Expr
    uses_policy : Bool
    request_tokens : Array[String]
    policy_type : String
    policy_tokens : Array[String]
    eft_index : Int?
    role_managers : Array[(String, RoleManager)]
    auto_build_role_links : Bool
    }

    An enforcer bound to one model and one in-memory policy store.

    Enforcer::add_function

    fn Enforcer::add_function(self : Enforcer, name : String, function : (Array[Value]) -> Value raise CasbinError) -> Unit

    Registers a custom matcher function, replacing an existing one.

    Enforcer::add_grouping_policy

    fn Enforcer::add_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Adds a grouping row to the g section. Returns false when the row already exists.

    Enforcer::add_named_policy

    fn Enforcer::add_named_policy(self : Enforcer, key : String, values : Array[String]) -> Result[Bool, CasbinError]

    Adds a policy row to the section key.

    Enforcer::add_policy

    fn Enforcer::add_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Adds a policy row to the p section. Returns false when the row already exists.

    Enforcer::add_role_for_user

    fn Enforcer::add_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]

    Adds role to user, optionally within domain.
    fn Enforcer::build_role_links(self : Enforcer) -> Result[Unit, CasbinError]

    Rebuilds every role graph from the grouping policy, mirroring Casbin's BuildRoleLinks. Called automatically after policy loads and grouping policy changes unless automatic rebuilding is disabled.

    Enforcer::delete_permissions_for_user

    fn Enforcer::delete_permissions_for_user(self : Enforcer, user : String) -> Result[Bool, CasbinError]

    Removes every policy row whose subject is user.

    Enforcer::delete_role

    fn Enforcer::delete_role(self : Enforcer, role : String) -> Result[Bool, CasbinError]

    Removes the role: grouping rows that reference it in either position and policy rows that use it as subject.

    Enforcer::delete_role_for_user

    fn Enforcer::delete_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]

    Removes role from user.

    Enforcer::delete_roles_for_user

    fn Enforcer::delete_roles_for_user(self : Enforcer, user : String, domain? : String) -> Result[Bool, CasbinError]

    Removes all roles of user, optionally within domain.

    Enforcer::delete_user

    fn Enforcer::delete_user(self : Enforcer, user : String) -> Result[Bool, CasbinError]

    Removes the user: every grouping row with the user as first field and every policy row with the user as subject.
    fn Enforcer::enable_auto_build_role_links(self : Enforcer, enabled : Bool) -> Unit

    Enables or disables automatic role-link rebuilding. Enabled by default, like Casbin.

    Enforcer::enforce

    fn Enforcer::enforce(self : Enforcer, request : Array[String]) -> Result[Bool, CasbinError]

    Decides whether request is allowed.

    The request must provide one value per request definition token.

    Enforcer::get_filtered_grouping_policy

    fn Enforcer::get_filtered_grouping_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Array[Array[String]]

    The g rows matched by values (empty string matches any field).

    Enforcer::get_filtered_policy

    fn Enforcer::get_filtered_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Array[Array[String]]

    The p rows whose fields from field_index on match values; an empty string in values matches any field.

    Enforcer::get_grouping_policy

    fn Enforcer::get_grouping_policy(self : Enforcer) -> Array[Array[String]]

    The rows of the g section, in insertion order.

    Enforcer::get_implicit_permissions_for_user

    fn Enforcer::get_implicit_permissions_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[Array[String]], CasbinError]

    The policy rows whose subject is user or one of the user's implicit roles. With a domain, only rows for that domain are returned.

    Enforcer::get_implicit_roles_for_user

    fn Enforcer::get_implicit_roles_for_user(self : Enforcer, user : String, domain? : String) -> Array[String]

    Every role user has, direct and indirect, across all role managers.

    Enforcer::get_implicit_users_for_role

    fn Enforcer::get_implicit_users_for_role(self : Enforcer, role : String, domain? : String) -> Array[String]

    Every user of role, direct and indirect, across all role managers.

    Enforcer::get_permissions_for_user

    fn Enforcer::get_permissions_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[Array[String]], CasbinError]

    The policy rows whose subject is user (and whose domain field is domain, when given).

    Enforcer::get_policy

    fn Enforcer::get_policy(self : Enforcer) -> Array[Array[String]]

    The rows of the p section, in insertion order.

    Enforcer::get_roles_for_user

    fn Enforcer::get_roles_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[String], CasbinError]

    The roles user has, directly.

    Enforcer::get_users_for_role

    fn Enforcer::get_users_for_role(self : Enforcer, role : String, domain? : String) -> Result[Array[String], CasbinError]

    The users of role, directly.

    Enforcer::has_grouping_policy

    fn Enforcer::has_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Whether the g section contains the row.

    Enforcer::has_policy

    fn Enforcer::has_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Whether the p section contains the row.

    Enforcer::has_role_for_user

    fn Enforcer::has_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]

    Whether user has the role role, directly.
    fn Enforcer::is_auto_build_role_links(self : Enforcer) -> Bool

    Whether automatic role-link rebuilding is enabled.

    Enforcer::load_policy_from_text

    fn Enforcer::load_policy_from_text(self : Enforcer, text : String) -> Result[Unit, CasbinError]

    Loads policy lines from text, validating each against the model.

    p sections require every row to have exactly the token count of the policy definition; g sections require at least the token count. Duplicate rows are skipped. Returns Err(ModelValidation) for a policy type the model does not define, and Err(Enforcement) for a row of the wrong size.

    Enforcer::model

    fn Enforcer::model(self : Enforcer) -> Model

    The model this enforcer was built from.

    Enforcer::new

    fn Enforcer::new(model : Model) -> Result[Enforcer, CasbinError]

    Builds an enforcer from a loaded model.

    Returns Err(ModelValidation) for an unsupported policy effect or a missing matcher, and Err(MatcherSyntax) when the matcher does not parse.

    Enforcer::policy

    fn Enforcer::policy(self : Enforcer) -> PolicyStore

    The in-memory policy store.

    Enforcer::remove_filtered_grouping_policy

    fn Enforcer::remove_filtered_grouping_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Result[Bool, CasbinError]

    Removes every g row matched by values. Returns whether any row was removed.

    Enforcer::remove_filtered_policy

    fn Enforcer::remove_filtered_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Result[Bool, CasbinError]

    Removes every p row matched by values. Returns whether any row was removed.

    Enforcer::remove_grouping_policy

    fn Enforcer::remove_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Removes a grouping row from the g section.

    Enforcer::remove_named_policy

    fn Enforcer::remove_named_policy(self : Enforcer, key : String, values : Array[String]) -> Result[Bool, CasbinError]

    Removes a policy row from the section key.

    Enforcer::remove_policy

    fn Enforcer::remove_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]

    Removes a policy row from the p section.

    Expr

    pub(all) enum Expr {
    Literal(Value)
    Ident(String)
    List(Array[Expr])
    Member(Expr, String)
    Unary(UnaryOp, Expr)
    Binary(BinaryOp, Expr, Expr)
    Call(String, Array[Expr])
    } derive(Eq,
    Debug
    )

    A matcher expression node.

    Expr::eval

    fn Expr::eval(self : Expr, lookup : (String) -> Value?, functions : FunctionRegistry) -> Result[Value, CasbinError]

    Evaluates a matcher expression.

    lookup resolves identifiers such as r_sub or p_obj and returns None for unknown names; functions resolves calls.

    FunctionRegistry

    pub(all) struct FunctionRegistry {
    entries : Array[(String, (Array[Value]) -> Value raise CasbinError)]
    }

    A registry of matcher functions keyed by name.

    FunctionRegistry::add

    fn FunctionRegistry::add(self : FunctionRegistry, name : String, function : (Array[Value]) -> Value raise CasbinError) -> Unit

    Registers function under name, replacing an existing entry.

    FunctionRegistry::get

    fn FunctionRegistry::get(self : FunctionRegistry, name : String) -> (Array[Value]) -> Value raise CasbinError?

    The function registered under name, if any.

    FunctionRegistry::new

    Creates an empty registry.

    Model

    pub(all) struct Model {
    request : Array[Assertion]
    policy : Array[Assertion]
    role : Array[Assertion]
    effect : Assertion?
    matcher : Array[Assertion]
    } derive(
    Debug
    )

    Loaded Casbin model: request, policy, and role definitions, the policy effect, and matcher expressions.

    Model::from_config

    fn Model::from_config(config : Config) -> Result[Model, CasbinError]

    Builds a model from parsed configuration.

    Returns Err(CasbinErrorKind::ModelValidation) for a semantically invalid model.

    Model::matcher

    fn Model::matcher(self : Model, key : String) -> Assertion?

    The matcher with the given key, for example m or m2.

    Model::policy_definition

    fn Model::policy_definition(self : Model, key : String) -> Assertion?

    The policy definition with the given key, for example p or p2.

    Model::policy_effect

    fn Model::policy_effect(self : Model) -> Assertion?

    The policy effect assertion.

    Model::request_definition

    fn Model::request_definition(self : Model, key : String) -> Assertion?

    The request definition with the given key, for example r.

    Model::role_definition

    fn Model::role_definition(self : Model, key : String) -> Assertion?

    The role definition with the given key, for example g or g2.

    PolicyLine

    pub(all) struct PolicyLine {
    key : String
    values : Array[String]
    } derive(Eq,
    Debug
    )

    One parsed policy line: the policy type plus the rule values.

    PolicyLine::key

    fn PolicyLine::key(self : PolicyLine) -> String

    The policy type, for example p or g.

    PolicyLine::values

    fn PolicyLine::values(self : PolicyLine) -> Array[String]

    The rule values, without the policy type.

    PolicySection

    pub(all) struct PolicySection {
    key : String
    rows : Array[Array[String]]
    index :
    HashMap
    [String, Int]
    }

    One policy type section: its rows plus a duplicate-detection index.

    PolicySection::key

    fn PolicySection::key(self : PolicySection) -> String

    The policy type, for example p, p2, g, or g2.

    PolicySection::rows

    fn PolicySection::rows(self : PolicySection) -> Array[Array[String]]

    The rows of this section in insertion order.

    PolicyStore

    pub(all) struct PolicyStore {
    sections : Array[PolicySection]
    }

    An in-memory policy store.

    PolicyStore::add

    fn PolicyStore::add(self : PolicyStore, key : String, row : Array[String]) -> Bool

    Adds row to the section key, creating the section when needed. Returns false when the row is already present.

    PolicyStore::clear

    fn PolicyStore::clear(self : PolicyStore) -> Unit

    Removes every row of every section.

    PolicyStore::has

    fn PolicyStore::has(self : PolicyStore, key : String, row : Array[String]) -> Bool

    Whether row is present in the section key.

    PolicyStore::new

    Creates an empty store.

    PolicyStore::remove

    fn PolicyStore::remove(self : PolicyStore, key : String, row : Array[String]) -> Bool

    Removes row from the section key, keeping the order of the remaining rows. Returns false when the row is not present.

    PolicyStore::rows

    fn PolicyStore::rows(self : PolicyStore, key : String) -> Array[Array[String]]

    The rows of the section key in insertion order; empty when the section does not exist.

    RoleGraph

    pub(all) struct RoleGraph {
    nodes : Array[RoleNode]
    }

    The role graph of one domain.

    RoleManager

    pub(all) struct RoleManager {
    graphs : Array[(String, RoleGraph)]
    max_hierarchy_level : Int
    }

    A role manager holding one graph per domain.
    fn RoleManager::add_link(self : RoleManager, user : String, role : String, domain? : String) -> Unit

    Records that user inherits role in domain (the default domain when omitted).

    RoleManager::clear

    fn RoleManager::clear(self : RoleManager) -> Unit

    Removes every link of every domain.
    fn RoleManager::delete_link(self : RoleManager, user : String, role : String, domain? : String) -> Bool

    Removes the link user -> role. Returns false when the link does not exist.

    RoleManager::get_implicit_roles

    fn RoleManager::get_implicit_roles(self : RoleManager, name : String, domain? : String) -> Array[String]

    Every role name inherits, direct and indirect, deduplicated and in breadth-first order; name itself is never included.

    RoleManager::get_implicit_users

    fn RoleManager::get_implicit_users(self : RoleManager, name : String, domain? : String) -> Array[String]

    Every node that inherits name, direct and indirect, deduplicated and in breadth-first order; name itself is never included.

    RoleManager::get_roles

    fn RoleManager::get_roles(self : RoleManager, name : String, domain? : String) -> Array[String]

    The roles name directly inherits, in insertion order.

    RoleManager::get_users

    fn RoleManager::get_users(self : RoleManager, name : String, domain? : String) -> Array[String]

    The nodes directly inheriting name, in insertion order.
    fn RoleManager::has_link(self : RoleManager, name1 : String, name2 : String, domain? : String) -> Bool

    Whether name1 inherits name2, directly or transitively.

    RoleManager::max_hierarchy_level

    fn RoleManager::max_hierarchy_level(self : RoleManager) -> Int

    The configured maximum hierarchy level.

    RoleManager::new

    fn RoleManager::new(max_hierarchy_level? : Int) -> RoleManager

    Creates an empty role manager.

    RoleNode

    pub(all) struct RoleNode {
    name : String
    parents : Array[String]
    users : Array[String]
    }

    One node of a role graph: direct parents (roles inherited) and direct users (nodes that inherit this one).

    UnaryOp

    pub(all) enum UnaryOp {
    Not
    Neg
    } derive(Eq,
    Debug
    )

    Unary operators.

    Value

    pub(all) enum Value {
    Null
    Bool(Bool)
    Int(Int)
    Double(Double)
    String(String)
    Array(Array[Value])
    Object(Array[(String, Value)])
    } derive(Eq,
    Debug
    )

    A runtime value produced or consumed by the matcher evaluator.

    Value::equals

    fn Value::equals(self : Value, other : Value) -> Bool

    Casbin-style equality: numbers compare across int and double, values of different types are never equal, arrays compare element-wise, and records compare field-wise in order.

    Value::type_name

    fn Value::type_name(self : Value) -> String

    A human-readable type name used in error messages.

    builtin_functions

    fn builtin_functions() -> FunctionRegistry

    A registry containing the built-in functions.

    casbin_error

    fn casbin_error(kind : CasbinErrorKind, message : String) -> CasbinError

    Constructs a CasbinError not tied to a position.

    casbin_error_at

    fn casbin_error_at(kind : CasbinErrorKind, line : Int, message : String) -> CasbinError

    Constructs a CasbinError carrying the 1-based configuration line.

    casbin_error_at_offset

    fn casbin_error_at_offset(kind : CasbinErrorKind, offset : Int, message : String) -> CasbinError

    Constructs a CasbinError carrying a 0-based character offset in an expression.

    default_max_hierarchy_level

    let default_max_hierarchy_level : Int

    The maximum hierarchy level used by Casbin's default role managers.

    escape_assertion

    fn escape_assertion(text : String) -> String

    Rewrites the first dot of r.attr style accessors to _, mirroring Casbin's EscapeAssertion.

    ip_match

    fn ip_match(ip1 : String, ip2 : String) -> Bool raise CasbinError

    Whether ip1 is covered by ip2, where ip2 is either a CIDR (192.168.2.0/24) or a plain address.

    Raises MatcherEval when either argument does not parse, mirroring the errors Casbin's ipMatch raises.

    merge_effects

    fn merge_effects(expression : EffectExpression, effects : Array[Effect], matches : Array[Bool], policy_index : Int, policy_length : Int) -> (Effect, Int)

    Merges the effects collected so far for the row at policy_index, mirroring DefaultEffector.MergeEffects.

    matches[i] records whether row i satisfied the matcher; effects[i] is that row's effect. Both arrays have one entry per policy row.

    parse_matcher

    fn parse_matcher(text : String) -> Result[Expr, CasbinError]

    Parses a matcher expression into an AST.

    The text is expected to be preprocessed the way Casbin preprocesses model files: r.sub has already become r_sub, so identifiers are plain names.

    parse_policy_text

    fn parse_policy_text(text : String) -> Result[Array[PolicyLine], CasbinError]

    Parses policy text into lines. Empty lines and # comments are skipped; a line whose first field is empty raises PolicySyntax.

    preprocess_expression

    fn preprocess_expression(text : String) -> String

    The full Casbin preprocessing for expression values: escape accessors, then strip comments.

    remove_comments

    fn remove_comments(text : String) -> String

    Strips a # comment; the kept prefix is trimmed. Mirrors Casbin's RemoveComments (including returning the text unchanged when there is no #).