php-casbin / database-adapter

Database adapter for PHP-Casbin, Casbin is a powerful and efficient open-source access control library.
Apache License 2.0
28 stars 5 forks source link

Duplicate entries (again) #3

Closed killua-eu closed 3 years ago

killua-eu commented 3 years ago

Hi all, this is a followup back again - now with a different model and policies, but with the same result as #2 (sorry for not replying earlier, I had to move to different projects unexpectedly). The problem is possibly related to https://github.com/php-casbin/php-casbin/issues/61 ... When using the file adapter, i get i.e. 47 lines, when I use the database, I get 2013 lines. For example, with

$rules = [
            'p' => [ 
                // admininstration role
                [ 'admin', '0', '*', 'c' ],
                [ 'admin', '0', '*', 'r' ],
                [ 'admin', '0', '*', 'u' ],
                [ 'admin', '0', '*', 'd' ],
                // usage role
                [ 'usage', '0', '/ui/worklog', 'r' ],
                [ 'usage', '0', '/ui/core/accounts/self', 'r' ],
                [ 'usage', '0', '/ui/core/profiles/self', 'r' ],
                [ 'usage', '0', '/ui/stor', 'r' ],
            ],
            // The `g` policy assigns a {role} in {domain} to a {user}
            // Per model definition, `g = user, role, domain`.
            'g' => [
                [ '1', 'admin', '0' ],
            ],
];

and model

[request_definition]
r = sub, dom, obj, act

[policy_definition]
p = sub, dom, obj, act

[role_definition]
g = _, _, _
g2 = _, _

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

[matchers]
m = g(r.sub, p.sub, r.dom) && g2(r.dom, p.dom) && keyMatch2(r.obj, p.obj) && r.act == p.act

... During my testing of casbin, I first noted that I must envelope the addPolicy with a hasPolicy method, otherwise I get duplocate data.

if (!$m->hasPolicy('g', 'g2', $rule)) { $m->addPolicy('g', 'g2', $rule);
$e->savePolicy(); }

I also noticed, that integers in the $rule array (where strings are expected, but not type-enforced) cause another set of duplication. Upon writing a wrapper function, that casts all $rule elements to string. the problem with duplicate data disappeared when using the file adapter, but remains with the database adapter.

Either there's a difference in how data are handled by the adapters before storing them, or its the difference between mysql and a textfile. The sql table uses varchar, so that should be fine, but it inherits from the database the default charset (in my case utf8mb4_0900_ai_ci) , which means accent and case insensitive. I can't imagine how numbers could be a problem, but there's a lot to consider.

I think php-casbin and the database-adapter need a stricter type checking and comparing to avoid these problems.

hsluoyz commented 3 years ago

@killua-eu I'm afraid currently there's no way to do static type checking in PHP. Do you have a better proposal for this?

killua-eu commented 1 year ago

Maybe type casting? a simple $rule = array_map('strval', $rule); ?