casbin / Casbin.NET

An authorization library that supports access control models like ACL, RBAC, ABAC in .NET (C#)
https://casbin.org
Apache License 2.0
1.16k stars 111 forks source link

Trying to use multiple matcher #216

Closed thoraj closed 2 years ago

thoraj commented 2 years ago

I am having trouble trying to use multiple matchers in a model.

I have tried adding a second matcher to the model file, and I have also tried adding the second matcher in code.


        [Fact]
        public void CanHaveModelWithMultipleMatchers()
        {
            var m = Model.CreateDefault();
            m.AddDef("r", "r", "sub, obj, act");
            m.AddDef("p", "p", "sub, obj, act");
            m.AddDef("e", "e", "some(where (p.eft == allow))");
            m.AddDef("m", "m", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)");
            m.AddDef("m", "m2", "r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)");

            var fullPolicyPath = Path.Combine(AppContext.BaseDirectory, "Casbin","test-policy-multiple-matcher.csv");
            IAdapter a = new DefaultFileAdapter(fullPolicyPath);

            var e = new Enforcer(m, a);

            e.Enforce("company_admin", "company_A", "manage").Should().BeTrue();                        // OK 
            e.EnforceWithMatcher("m2","company_admin", "company_A", "manage").Should().BeTrue();        // Throws

        }

The standard Enforce() call works OK, but the second throws and exception:

DynamicExpresso.Exceptions.UnknownIdentifierException
Unknown identifier 'm2' (at index 0).
   at DynamicExpresso.Parsing.Parser.ParseIdentifier()
   at DynamicExpresso.Parsing.Parser.ParsePrimaryStart()
   at DynamicExpresso.Parsing.Parser.ParsePrimary()
   at DynamicExpresso.Parsing.Parser.ParseUnary()
   at DynamicExpresso.Parsing.Parser.ParseMultiplicative()
   at DynamicExpresso.Parsing.Parser.ParseAdditive()
   at DynamicExpresso.Parsing.Parser.ParseTypeTesting()
   at DynamicExpresso.Parsing.Parser.ParseComparison()
   at DynamicExpresso.Parsing.Parser.ParseLogicalAnd()
   at DynamicExpresso.Parsing.Parser.ParseLogicalXor()
   at DynamicExpresso.Parsing.Parser.ParseLogicalOr()
   at DynamicExpresso.Parsing.Parser.ParseConditionalAnd()
   at DynamicExpresso.Parsing.Parser.ParseConditionalOr()
   at DynamicExpresso.Parsing.Parser.ParseConditional()
   at DynamicExpresso.Parsing.Parser.ParseAssignment()
   at DynamicExpresso.Parsing.Parser.ParseExpressionSegment()
   at DynamicExpresso.Parsing.Parser.ParseExpressionSegment(Type returnType)
   at DynamicExpresso.Parsing.Parser.Parse()
   at DynamicExpresso.Interpreter.ParseAsLambda(String expressionText, Type expressionType, Parameter[] parameters)
   at DynamicExpresso.Interpreter.Parse(String expressionText, Type expressionType, Parameter[] parameters)
   at DynamicExpresso.Interpreter.Parse(String expressionText, Parameter[] parameters)
   at NetCasbin.Evaluation.ExpressionHandler.CreateExpression(String expressionString)
   at NetCasbin.Evaluation.ExpressionHandler.GetFunc[TFunc](String expressionString)
   at NetCasbin.Evaluation.ExpressionHandler.InvokeOnlyString(String expressionString)
   at NetCasbin.Evaluation.ExpressionHandler.Invoke(String expressionString)
   at NetCasbin.CoreEnforcer.InternalEnforceWithChainEffector(EnforceContext context, IChainEffector chainEffector, IReadOnlyList`1 requestValues, ICollection`1 explains)
   at NetCasbin.CoreEnforcer.InternalEnforce(IReadOnlyList`1 requestValues, String matcher, ICollection`1 explains)
   at NetCasbin.CoreEnforcer.EnforceWithMatcher(String matcher, Object[] requestValues)
   at Rosberg.Common.Test.TestOrganization.CanHaveModelWithMultipleMatchers() in C:\dev\src\RosbergCommon\Rosberg.Common.Test\TestOrganization.cs:line 286

I have verified that the 'm' collection in the model in fact has two entries ('m' and 'm2').

Not sure what I'm doing wrong, or if multiple matchers is supposed to work in v1.11?

casbin-bot commented 2 years ago

@sagilio @xcaptain @huazhikui

sagilio commented 2 years ago

@thoraj The first param of the EnforceWithMatcher method is the context of matcher, not the type.

e.EnforceWithMatcher("r.sub == p.sub && keyMatch(r.obj, p.obj) && regexMatch(r.act, p.act)","company_admin", "company_A", "manage").Should().BeTrue();  
thoraj commented 2 years ago

Thanks. I was able to sort out the issues.