Casbin.NET
Casbin.NET copied to clipboard
Breaking change in expression parsing between versions 1.5.0 and 2.5.3
I followed the migration guide but there are no documented details regarding the changes in expression parsing logic. The code that used to work on version 1.5.0 - doesn't work anymore on 2.5.3
Exception:
DynamicExpresso.Exceptions.ParseException: No property or field 'rule' exists in type 'ListRequestValues`1' (at index 2).
2024-05-09 19:43:58
at Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.<Invoke>g__Awaited|6_0(ExceptionHandlerMiddleware middleware, HttpContext context, Task task)
2024-05-09 19:43:58
...
at Casbin.EnforcerExtension.Enforce[T](IEnforcer enforcer, T[] value)
2024-05-09 19:43:58
at Casbin.Enforcer.Enforce[TRequest](EnforceContext context, TRequest requestValues)
2024-05-09 19:43:58
at Casbin.Enforcer.InternalEnforce[TRequest](EnforceContext& context, TRequest& requestValues)
2024-05-09 19:43:58
at Casbin.Enforcer.InternalEnforce[TRequest,TPolicy](EnforceContext& context, TRequest& requestValues)
2024-05-09 19:43:58
at Casbin.Evaluation.ExpressionHandler.Invoke[TRequest,TPolicy](EnforceContext& context, String expressionString, TRequest& request, TPolicy& policy)
2024-05-09 19:43:58
at DynamicExpresso.Interpreter.ParseAsDelegate[TDelegate](String expressionText, String[] parametersNames)
2024-05-09 19:43:58
at DynamicExpresso.Interpreter.ParseAsLambda(String expressionText, Type expressionType, Parameter[] parameters)
2024-05-09 19:43:58
at DynamicExpresso.Parsing.Parser.Parse()
...
Model:
[request_definition]
r = rule, sub, obj, act
[policy_definition]
p = sub_rule, sub, obj, act
[role_definition]
g = _, _
[policy_effect]
e = some(where (p.eft == allow)) && !some(where (p.eft == deny))
[matchers]
m = eval(p.sub_rule) && g(r.sub, p.sub) && keyMatch3(r.obj, p.obj) && (p.act == "*" || regexMatch(r.act, p.act))
Policies:
p, r.rule["CompanyData"]["CompanyIsActive"] == "True" && (r.rule["CompanyData"]["BusinessRole"] == "Role1" || r.rule["CompanyData"]["BusinessRole"] == "Role2"), WebApp, /api/transactions/getTransactions, POST
p, r.rule["CompanyData"]["CompanyIsActive"] == "False" && (r.rule["CompanyData"]["BusinessRole"] == "Role1" || r.rule["CompanyData"]["BusinessRole"] == "Role2"), Admin, /api/transactions/getTransactions, POST
How I'm enforcing on version 1.5.0:
var enforceRequestValues = new List<object>();
var authorizationAttributes = new Dictionary<string, Dictionary<string, string>>
{
["CompanyData"] = new Dictionary<string, string>
{
["CompanyIsActive"] = "True", ["BusinessRole"] = "Role1"
}
};
enforceRequestValues.Add(authorizationAttributes);
// role is Admin
enforceRequestValues.Add(role);
// path is /api/transactions/gettransactions
enforceRequestValues.Add(path);
// method is POST
enforceRequestValues.Add(method);
result = _enforcer.Enforce(enforceRequestValues.ToArray());
The same logic doesn't work on version 2.5.3
Can you suggest, please, what I am missing or what to change?
@sagilio @sociometry @AsakusaRinne
Here are two questions:
-
The current transformer processing for Matcher does not recognize index operators, and this needs to be fixed. https://github.com/casbin/Casbin.NET/blob/5a358a4328487b96a45b225a5f3d2af1c73c9702/Casbin/EnforceView.cs#L121-L122
-
The overload used for Enforce is incorrect. Enforce currently supports generic parameters, which helps to avoid the significant overhead caused by forced boxing. You can try to make a direct call, like this:
var authorizationAttributes = new Dictionary<string, Dictionary<string, string>>
{
["CompanyData"] = new Dictionary<string, string>
{
["CompanyIsActive"] = "True", ["BusinessRole"] = "Role1"
}
};
result = _enforcer.Enforce(authorizationAttributes, role, path, method);
Thanks, I will try to implement it
@vova-lantsov-dev Hi, I have tried to address this issue with pull request #355. It includes test cases for the scenarios you mentioned and the tests are now passing successfully. If you have time, could you please review the changes in the PR?
:tada: This issue has been resolved in version 2.7.1 :tada:
The release is available on GitHub release
Your semantic-release bot :package::rocket: