Casbin-style authorization engine in MoonBit: model-driven policy configuration, matcher and effect evaluation, RBAC role hierarchy, and an in-memory policy store.
Dependencies
Project/module: xiguaAp6y3/moonbit-casbin Repository: https://github.com/xiguaAp6y3/moonbit-casbin Version: 0.1.0 License: Apache-2.0
| 功能 | 状态 |
|---|---|
| 模型配置解析(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..keyMatch5、keyGet / keyGet2 / keyGet3 | 已实现并测试 |
| 内置函数 regexMatch、globMatch、ipMatch(IPv4/IPv6 + CIDR) | 已实现并测试 |
| 结构化错误(六类错误 + 行号或偏移) | 已实现并测试 |
| 角色名模式匹配(AddMatchingFunc / 域匹配函数) | 计划中 |
| CLI 工具 | 计划中 |
git clone https://github.com/xiguaAp6y3/moonbit-casbin.git
cd moonbit-casbin
moon testmoon fmt --check
moon check --target all --deny-warn
moon build --target all
moon test --target all --deny-warnlet 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() == ["_", "_"]match Config::parse("r = sub, obj, act") {
Err(error) => {
// error.kind() == ConfigSyntax
// error.line() == 1
// error.message() == "entry outside of any section"
}
Ok(_) => ()
}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)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())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├── .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.mdpub(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
}fn Enforcer::add_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::add_named_policy(self : Enforcer, key : String, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::add_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]fn Enforcer::delete_permissions_for_user(self : Enforcer, user : String) -> Result[Bool, CasbinError]fn Enforcer::delete_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]fn Enforcer::delete_roles_for_user(self : Enforcer, user : String, domain? : String) -> Result[Bool, CasbinError]fn Enforcer::get_implicit_permissions_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[Array[String]], CasbinError]fn Enforcer::get_permissions_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[Array[String]], CasbinError]fn Enforcer::get_roles_for_user(self : Enforcer, user : String, domain? : String) -> Result[Array[String], CasbinError]fn Enforcer::get_users_for_role(self : Enforcer, role : String, domain? : String) -> Result[Array[String], CasbinError]fn Enforcer::has_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::has_role_for_user(self : Enforcer, user : String, role : String, domain? : String) -> Result[Bool, CasbinError]fn Enforcer::remove_filtered_grouping_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::remove_filtered_policy(self : Enforcer, field_index : Int, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::remove_grouping_policy(self : Enforcer, values : Array[String]) -> Result[Bool, CasbinError]fn Enforcer::remove_named_policy(self : Enforcer, key : String, values : Array[String]) -> Result[Bool, CasbinError]fn Expr::eval(self : Expr, lookup : (String) -> Value?, functions : FunctionRegistry) -> Result[Value, CasbinError]pub(all) struct FunctionRegistry {
entries : Array[(String, (Array[Value]) -> Value raise CasbinError)]
}fn FunctionRegistry::add(self : FunctionRegistry, name : String, function : (Array[Value]) -> Value raise CasbinError) -> Unitfn FunctionRegistry::get(self : FunctionRegistry, name : String) -> (Array[Value]) -> Value raise CasbinError?fn RoleManager::add_link(self : RoleManager, user : String, role : String, domain? : String) -> Unitfn RoleManager::delete_link(self : RoleManager, user : String, role : String, domain? : String) -> Boolfn RoleManager::get_implicit_roles(self : RoleManager, name : String, domain? : String) -> Array[String]fn RoleManager::get_implicit_users(self : RoleManager, name : String, domain? : String) -> Array[String]fn RoleManager::has_link(self : RoleManager, name1 : String, name2 : String, domain? : String) -> Boollet default_max_hierarchy_level : Intfn escape_assertion(text : String) -> Stringfn merge_effects(expression : EffectExpression, effects : Array[Effect], matches : Array[Bool], policy_index : Int, policy_length : Int) -> (Effect, Int)fn preprocess_expression(text : String) -> Stringfn remove_comments(text : String) -> StringInstall
Download zipCasbin-style authorization engine in MoonBit: model-driven policy configuration, matcher and effect evaluation, RBAC role hierarchy, and an in-memory policy store.
Dependencies