php-casbin/laravel-authz

root for rbac with all pattern model can not pass the verify. But the casbin editor does.

oknixus opened this issue · 12 comments

My codes:

    // adds permissions to a user
    Enforcer::addPermissionForUser('admin', 'article', 'content', 'read');
    Enforcer::addPermissionForUser('admin', 'goods', 'content', 'write');

    Enforcer::addPermissionForUser('root', '*', '*', '*');

    // adds a role for a user.
    Enforcer::addRoleForUser('eve', 'root', '*');
    Enforcer::addRoleForUser('bob', 'admin', '*');
    Enforcer::addRoleForUser('tom', 'admin', 'goods');

    if (Enforcer::enforce("eve", "article", "content", "read")) {
        return sprintf('yes. %s', now()->format('Y-m-d H:i:s'));
    }

    if (Enforcer::enforce("bob", 'goods', 'content', 'read')) {
        return sprintf('bob has this perm. %s', now()->format('Y-m-d H:i:s'));
    }

    if (Enforcer::enforce('tom', 'goods', 'content', 'write')) {
        return sprintf('this is tom. %s', now()->format('Y-m-d H:i:s'));
    }

Enforcement result in my requests, only the last one without * passed enforcement:
image

In the casbin editor:

image

I found the dom can't use the pattern.

If I change the code to(use '*' instead of 'article'):

    if (Enforcer::enforce("eve", "*", "content", "read")) {
        return sprintf('yes. %s', now()->format('Y-m-d H:i:s'));
    }

It works fine:
image

@oknixus this is possible because Casbin Editor is powered by Node.js version Casbin: https://github.com/casbin/casbin-editor , however, this repo is powered by PHP version Casbin

@leeqvip any ideas?

Thanks very much!

I could implement the global super user permission via Enforcer::hasRoleForUser($userId, 'root', '*'), but can't implement the local super user permission.
eg: There are two module named article and goods, and the admin role has their privileges. One user need get All the privileges of the admin.

Would you being to finish it ? Or some suggestions? Thanks again.

I add this !Enforcer::enforce($userId, '*', $model, $action) in the middleware, implement the local super user permissions.

Then the whole conditions:

        if (
            (
                !Enforcer::enforce($userId, $module, $model, $action)
                && !Enforcer::enforce($userId, '*', $model, $action)
            )
            && !Enforcer::hasRoleForUser($userId, 'root', '*')
        ) {
            return \response()->json(['msg' => '无操作权限']);
        }

@oknixus glad to see that you have resolved the issue. Why open again?

I resolved too rough. Expect your elegant solution.😄

Well……I'd better close this issue. Thanks very much.

@oknixus refer to this: Super Admin

@oknixus Can you check whether your model configuration is correct? I wrote a demo using php-casbin, and the result is as expected.

<?php
require_once './vendor/autoload.php';

use Casbin\Enforcer;
use Casbin\Model\Model;

$model = Model::newModelFromString(
    <<<EOT
    [request_definition]
    r = sub, dom, obj, act
    
    [policy_definition]
    p = sub, dom, obj, act
    
    [role_definition]
    g = _, _, _
    
    [policy_effect]
    e = some(where (p.eft == allow))
    
    [matchers]
    m = g(r.sub, p.sub, r.dom) && keyMatch2(r.obj, p.obj) && keyMatch2(r.act, p.act) || p.act == "*"
    EOT
);

$e = new Enforcer($model);

// adds permissions to a user
$e->addPermissionForUser('admin', 'article', 'content', 'read');
$e->addPermissionForUser('admin', 'goods', 'content', 'write');
$e->addPermissionForUser('root', '*', '*', '*');
// adds a role for a user.
$e->addRoleForUser('eve', 'root', '*');
$e->addRoleForUser('bob', 'admin', '*');
$e->addRoleForUser('tom', 'admin', 'goods');

if ($e->enforce("eve", "article", "content", "read")) {
    echo sprintf('yes. %s'.PHP_EOL, now()->format('Y-m-d H:i:s'));
}

if ($e->enforce("bob", 'goods', 'content', 'read')) {
    echo sprintf('bob has this perm. %s'.PHP_EOL, now()->format('Y-m-d H:i:s'));
}

if ($e->enforce('tom', 'goods', 'content', 'write')) {
    echo sprintf('this is tom. %s'.PHP_EOL, now()->format('Y-m-d H:i:s'));
}

Actual results:

# php index.php 
yes. 2023-03-23 15:58:21
bob has this perm. 2023-03-23 15:58:21
this is tom. 2023-03-23 15:58:21

@leeqvip No. I'm afraid there's a problem in your matchers:
The admin only have the permission write for goods. In your matchers, bob have read permission for the content of goods. This expends the permissions of bob.

Well……my code also is wrong:

if (
            (
                !Enforcer::enforce($userId, $module, $model, $action)
                && !Enforcer::enforce($userId, '*', $model, $action)
            )
            && !Enforcer::hasRoleForUser($userId, 'root', '*')
        ) {
            return \response()->json(['msg' => '无操作权限']);
        }

I think my matchers is wrong. This package is ok.
@leeqvip Thanks your codes help me found the error.