Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[bug]Adding a policy that contains double quotes will cause an exception in the eval function #440

Open
Wan95u opened this issue Nov 14, 2024 · 6 comments
Assignees
Labels

Comments

@Wan95u
Copy link

Wan95u commented Nov 14, 2024

jcasbin version
1.5.5

What happened
When adding a new policy, if the rule contains double quotes, the Assertion.policy will also contain double quotes, causing the eval function to fail. Restarting the program and calling Helper.loadPolicyLine() will split the double quotes. I would like to ask about the original intention behind the design of both.

@hsluoyz
Copy link
Member

hsluoyz commented Nov 14, 2024

@Wan95u

  1. Provide full example code, not natural language

  2. Test with Casbin online editor first: https://editor.casbin.org/

@hsluoyz hsluoyz self-assigned this Nov 14, 2024
@Wan95u
Copy link
Author

Wan95u commented Nov 15, 2024

model.conf:

[request_definition]
r = sub, obj, act

[policy_definition]
p =sub_rule,obj_rule,act

[policy_effect]
e = some(where (p.eft == allow))

[matchers]
m = r.act==p.act && eval(p.sub_rule) && eval(p.obj_rule)

policy:

{
    "sub": "",
    "obj": "\"let test=seq.set('n3','n4');include(test,r.sub.name)\"",
    "act": "read"
}

image

request:

{
    "sub": {
        "name": "n3",
        "age": 1
    },
    "obj": {
        "field": [
            "f1",
            "f2"
        ]
    },
    "act": "read"
}

call enforceEx result:
image

But when I reboot, I check the same request again:
image

@hsluoyz
Copy link
Member

hsluoyz commented Nov 15, 2024

@Wan95u plz provide full Java code (better in a test case format)

@Wan95u
Copy link
Author

Wan95u commented Nov 15, 2024

@hsluoyz main code
controller

package org.example.controller;


import com.googlecode.aviator.AviatorEvaluatorInstance;
import com.googlecode.aviator.Options;
import org.casbin.jcasbin.main.EnforceResult;
import org.casbin.jcasbin.main.ManagementEnforcer;
import org.example.model.Policy;
import org.example.model.Request;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;


@RestController
@RequestMapping({"/_api/casbin"})
public class JCasbin {

    @Autowired
    private ManagementEnforcer enforcer;
    
    @PostMapping("/verify")
    public Object findByProcName2(@RequestBody Request request) {
        AviatorEvaluatorInstance aviatorEval = enforcer.getAviatorEval();
        aviatorEval.setOption(Options.TRACE_EVAL, true);
        EnforceResult enforceResult = enforcer.enforceEx(request.getSub(), request.getObj(), request.getAct());
        System.out.println(enforceResult);
        return enforceResult;
    }

    @PostMapping("/policy")
    public void addPolicy(@RequestBody Policy policy) {
        boolean flag = enforcer.addPolicy(policy.rule());
        System.out.println("add policy:" + flag);
    }
}

Request

package org.example.model;

import lombok.Data;

import java.util.List;


@Data
public class Request {

    private Sub sub;

    private Obj obj;

    private String act;

    @Data
    class Sub {
        private String name;

        private int age;

        private String role;

        private String tenant;
    }

    @Data
    class Obj {

        private String name;

        private List<String> field;
    }
}

policy

package org.example.model;


import com.mysql.jdbc.StringUtils;
import lombok.Data;

import java.util.ArrayList;
import java.util.List;


@Data
public class Policy {

    private String sub;

    private String obj;

    private String act;

    public List<String> rule() {
        List<String> rule = new ArrayList<>();
        rule.add(StringUtils.isNullOrEmpty(sub) ? "true" : sub);
        rule.add(StringUtils.isNullOrEmpty(obj) ? "true" : obj);
        rule.add(StringUtils.isNullOrEmpty(act) ? "true" : act);
        return rule;
    }
}

@tx2002
Copy link
Contributor

tx2002 commented Nov 26, 2024

When adding a new policy, if the rule contains double quotes, the Assertion.policy will also contain double quotes, causing the eval function to fail.

@Wan95u Could you please provide more details on how you added the policy, such as which adapter you're using and the type of database? I performed some tests, and the results were correct even without calling Helper.loadPolicyLine().
Here is my test code:

public class MyTest {
    @Test
    public void jCasbin() {
        Request.Sub sub = new Request().new Sub();
        sub.setName("n3");
        sub.setAge(1);
        Request.Obj obj = new Request().new Obj();
        obj.setField(Arrays.asList("f1", "f2"));
        Request request = new Request();
        request.setSub(sub);
        request.setObj(obj);
        request.setAct("read");

        Policy policy = new Policy();
        policy.setSub("");
        policy.setObj("let test=seq.set('n3','n4');include(test,r.sub.name)");
        policy.setAct("read");

        Enforcer enforcer = new Enforcer("examples/test.conf");

        // addPolicy
        boolean flag = enforcer.addPolicy(policy.rule());
        System.out.println("add policy:" + flag);

        // verify
        AviatorEvaluatorInstance aviatorEval = enforcer.getAviatorEval();
        aviatorEval.setOption(Options.TRACE_EVAL, true);
        EnforceResult enforceResult = enforcer.enforceEx(request.getSub(), request.getObj(), request.getAct());
        System.out.println(enforceResult);
    }
}

the result:
image

@Wan95u
Copy link
Author

Wan95u commented Nov 26, 2024

@tx2002 let test=seq.set('n3','n4');include(test,r.sub.name)
Because this expression contains a comma, you need to add double quotation marks, otherwise the next start will report an error.

<dependency>
<groupId>org.casbin</groupId>
<artifactId>casbin-spring-boot-starter</artifactId>
<version>1.7.0</version>
</dependency>

I used casbin-spring-boot-starter:1.7.0, which is jscasbin:1.55.0.database type is mysql

yaml:

casbin:
  #Whether to enable Casbin, it is enabled by default.
  enableCasbin: true
  #Whether to use thread-synchronized Enforcer, default false
  useSyncedEnforcer: false
  #Whether to use distributed Enforcer, default false.
  #If both useSyncedEnforcer and useDistributedEnforcer are set to true, useDistributedEnforcer will take effect.
  useDistributedEnforcer: false
  #Whether to enable automatic policy saving, if the adapter supports this function, it is enabled by default.
  autoSave: true
  #Storage type [file, jdbc], currently supported jdbc database [mysql (mariadb), h2, oracle, postgresql, db2]
  #Welcome to write and submit the jdbc adapter you are using, see: org.casbin.adapter.OracleAdapter
  #The jdbc adapter will actively look for the data source information you configured in spring.datasource
  #Default use jdbc, and use the built-in h2 database for memory storage
  storeType: jdbc
  #Customized policy table name when use jdbc, casbin_rule as default.
  tableName: casbin_rule
  #Data source initialization policy [create (automatically create data table, no longer initialized if created), never (always do not initialize)]
  initializeSchema: create
  #Local model configuration file address, the default reading location: classpath: casbin/model.conf
  model: classpath:casbin/model.conf
  #If the model configuration file is not found in the default location and casbin.model is not set correctly, the built-in default rbac model is used, which takes effect by default.
  useDefaultModelIfModelNotSetting: true
  #Local policy configuration file address, the default reading location: classpath: casbin/policy.csv
  #If the configuration file is not found in the default location, an exception will be thrown.
  #This configuration item takes effect only when casbin.storeType is set to file.
  policy: classpath:casbin/policy.csv
  #Whether to enable the CasbinWatcher mechanism, the default is not enabled.
  #If the mechanism is enabled, casbin.storeType must be jdbc, otherwise the configuration is invalid.
  enableWatcher: false
  #CasbinWatcher notification mode, defaults to use Redis for notification synchronization, temporarily only supports Redis
  #After opening Watcher, you need to manually add spring-boot-starter-data-redis dependency.
  watcherType: redis
  #Watcher to support spring tx, the default is not enable.
  #If the mechanism is enabled, When updating policy in a spring transaction, watcher will trigger the update after commit
  watcherTxSupport: false

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants