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

remove_grouping_policy: If there are duplicate group rules, remove_grouping_policy will be invalid #258

Closed
cs1137195420 opened this issue May 11, 2022 · 10 comments · Fixed by #259
Assignees
Labels
bug Something isn't working released

Comments

@cs1137195420
Copy link
Contributor

I accidentally created two identical group rules in mysql, and then when I called the remove_grouping_policy function, I found that it failed to delete. There were still two identical group rules in mysql. So, should the remove_grouping_policy function remove all the same grouping rules?

@cs1137195420
Copy link
Contributor Author

Here is my code:

    DATABAEE = peewee.MySQLDatabase('casbin', user='root', passwd='root')
    adapter = casbin_peewee_adapter.Adapter(database=DATABAEE)

    e = casbin.Enforcer('model.conf', adapter)

    uid = 'bob'
    role = 'admin'
    result = e.remove_grouping_policy(uid, role)
    print(result)

    sub = "bob"  # the user that wants to access a resource.
    obj = "data1"  # the resource that is going to be accessed.
    act = "write"  # the operation that the user performs on the resource.

    if e.enforce(sub, obj, act):
        print('pass')
    else:
        print('not pass')

mysql
image

model.conf

[request_definition]
r = sub, obj, act

[policy_definition]
p = sub, obj, act

[role_definition]
g = _, _

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

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

@casbin-bot
Copy link
Member

@ffyuanda @Zxilly @techoner @elfisworking

@abichinger
Copy link
Member

@cs1137195420 I tried to remove duplicate rules with remove_grouping_policy and it worked for me.
Example:

from casbin_peewee_adapter import CasbinRule, Adapter
import casbin
import peewee
import os

db_name = 'db.sqlite3'

if os.path.exists(db_name):
    os.remove(db_name)

db = peewee.SqliteDatabase(db_name)
adapter = Adapter(database=db)
db.create_tables([CasbinRule])

e = casbin.Enforcer('model.conf', adapter)

#add twice
e.add_grouping_policy('bob', 'admin')
e.add_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 1

#add manually
rule = CasbinRule.create(ptype='g', v0='bob', v1='admin')
rule.save()

assert CasbinRule.select().count() == 2

e.remove_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 0

print("OK")

output:

OK

Can you try this example with peewee.MySQLDatabase?

@cs1137195420
Copy link
Contributor Author

@cs1137195420 I tried to remove duplicate rules with remove_grouping_policy and it worked for me. Example:

from casbin_peewee_adapter import CasbinRule, Adapter
import casbin
import peewee
import os

db_name = 'db.sqlite3'

if os.path.exists(db_name):
    os.remove(db_name)

db = peewee.SqliteDatabase(db_name)
adapter = Adapter(database=db)
db.create_tables([CasbinRule])

e = casbin.Enforcer('model.conf', adapter)

#add twice
e.add_grouping_policy('bob', 'admin')
e.add_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 1

#add manually
rule = CasbinRule.create(ptype='g', v0='bob', v1='admin')
rule.save()

assert CasbinRule.select().count() == 2

e.remove_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 0

print("OK")

output:

OK

Can you try this example with peewee.MySQLDatabase?

I tried it with peewee.MySQLDatabase, and my program also printed OK. However, when I called the add_grouping_policy, CasbinRule.create and remove_grouping_policy functions respectively, the error reappeared.
The error appeared in this way:

  1. First run the following code
db = peewee.MySQLDatabase('casbin', user='root', passwd='root')
adapter = Adapter(database=db)
db.create_tables([CasbinRule])
e = casbin.Enforcer('model.conf', adapter)

# add twice
e.add_grouping_policy('bob', 'admin')
e.add_grouping_policy('bob', 'admin')
assert CasbinRule.select().count() == 1

# add manually
rule = CasbinRule.create(ptype='g', v0='bob', v1='admin')
rule.save()
assert CasbinRule.select().count() == 2

print("OK")

output:

OK
  1. Next run the following code
db = peewee.MySQLDatabase('casbin', user='root', passwd='root')
adapter = Adapter(database=db)
db.create_tables([CasbinRule])
e = casbin.Enforcer('model.conf', adapter)

e.remove_grouping_policy('bob', 'admin')
assert CasbinRule.select().count() == 0

print("OK")

output:

Traceback (most recent call last):
  File "D:/project_hyb/casbin/pycasbin/main.py", line 22, in <module>
    assert CasbinRule.select().count() == 0
AssertionError

Can you try again in this way?

@abichinger
Copy link
Member

abichinger commented May 12, 2022

This time I was able to reproduce your error.

Example:

from casbin_peewee_adapter import CasbinRule, Adapter
import casbin
import peewee
import os

db_name = 'db.sqlite3'

if os.path.exists(db_name):
    os.remove(db_name)

db = peewee.SqliteDatabase(db_name)
adapter = Adapter(database=db)
db.create_tables([CasbinRule])

e = casbin.Enforcer('model.conf', adapter)

#add twice
e.add_grouping_policy('bob', 'admin')
e.add_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 1

#add manually
rule = CasbinRule.create(ptype='g', v0='bob', v1='admin')
rule.save()

assert CasbinRule.select().count() == 2

e2 = casbin.Enforcer('model.conf', adapter)
e2.remove_grouping_policy('bob', 'admin')

assert CasbinRule.select().count() == 0, f'{CasbinRule.select().count()} == 0'

print("OK")

Output:

Traceback (most recent call last):
  File "main.py", line 32, in <module>
    assert CasbinRule.select().count() == 0, f'{CasbinRule.select().count()} == 0'
AssertionError: 2 == 0

The problem is, that the peewee adapter loads the rule twice into the enforcer instance e2.
This happens during a call to Enforcer.load_policy.

-> e2.model.model['g']['g'].policy
[['bob', 'admin'], ['bob', 'admin']]

When e2.remove_grouping_policy is called line 211 in policy.py returns False, because there is still one rule left, after removing one.

In my opinion, the best solution would be to prevent duplicate entries in the adapter, using a unique constraint.

@cs1137195420
Copy link
Contributor Author

@abichinger In case there are duplicate entries in the adapter, should remove_grouping_policy delete all of them?

@hsluoyz
Copy link
Member

hsluoyz commented May 12, 2022

@cs1137195420 @abichinger plz see how Golang Casbin works

@abichinger
Copy link
Member

abichinger commented May 13, 2022

@abichinger In case there are duplicate entries in the adapter, should remove_grouping_policy delete all of them?

I would say yes, but that's something the adapter has to do.

@hsluoyz The golang version has a similar issue. (link is above)

I think we could fix this issue, if we use Policy.add_policy inside persist.load_policy_line, instead of directly modifying the policy. This way, the duplicate rule should only be added once and remove_grouping_policy should work as expected

@cs1137195420 Would you like to create a PR for this?

@cs1137195420
Copy link
Contributor Author

@abichinger In case there are duplicate entries in the adapter, should remove_grouping_policy delete all of them?

I would say yes, but that's something the adapter has to do.

@hsluoyz The golang version has a similar issue. (link is above)

I think we could fix this issue, if we use Policy.add_policy inside persist.load_policy_line, instead of directly modifying the policy. This way, the duplicate rule should only be added once and remove_grouping_policy should work as expected

@cs1137195420 Would you like to create a PR for this?

Sure, I would like to.

@hsluoyz hsluoyz added bug Something isn't working and removed question Further information is requested labels May 20, 2022
@github-actions
Copy link

🎉 This issue has been resolved in version 1.16.5 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working released
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants