-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
feat: support domain hierarchical and GetNamedRoleManager #1040
base: master
Are you sure you want to change the base?
Conversation
@closetool @sagilio please review |
@shipovalovyuriy plz review. You can ues it like the example in the test code func TestDomainHierarchical(t *testing.T) {
e, _ := NewEnforcer("examples/rbac_with_domains_hierarchical_model.conf", "examples/rbac_with_domains_hierarchical_policy.csv")
origin := e.GetNamedRoleManager("g").(*defaultrolemanager.RoleManager)
dest := e.GetNamedRoleManager("g2").(*defaultrolemanager.RoleManager)
origin.SetTenantManager(dest)
testDomainEnforce(t, e, "alice", "dom2", "data", "read", true)
} |
Great job! Could you add |
done |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -557,6 +574,17 @@ func (dm *DomainManager) getRoleManager(domain string, store bool) *RoleManagerI | |||
return true | |||
}) | |||
} | |||
if dm.tenantManager != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even though I do not know much about golang
, this feels little repetitive, don't you think?
I think some comments would also be warranted. These specific conditions should be explained, otherwise somebody would just scratch their head in the future when they try to figure out why these are done as they are.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
did some refactoring
@@ -0,0 +1,6 @@ | |||
p, admin, dom3, data, read |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also little more complexity to the domain is warranted. At least one extra user to test out that they do not have access to domain1 if they only have access to domain2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more tests
@@ -267,3 +268,12 @@ func TestGetAllDomains(t *testing.T) { | |||
|
|||
testGetAllDomains(t, e, []string{"domain1", "domain2"}) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think singular test case is not sufficient for such a complex feature. At least one which supports deep hierarchy should also be done. Like here:
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More specifically: Multiple subjects, multiple objects, multiple domains
- Test cases for accessing data in an upper domain from a lower domain (Failure)
- Test cases for accessing data in a lower domain from a middle domain (Success)
- Test cases for accessing data in a sibling domain from another sibling (Failure)
- Test cases for accessing data in a sibling domain from parent (success)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more tests
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to implement this in casbin/node-casbin#380
I think it's not possible to define g2
in the format of child, parent
. At least in nodeJS, it provided incorrect results, but maybe golang
has a different RoleManager definition.
You can try to replicate the test case I did for nodeJS. I think it provides quite good coverage on all the possible use cases. Especially the 4 domain structure is essential.
I have tried to comment on why certain decisions were made in the pull request and a little bit about the thought behind the hierarchy model.
rbac_api_with_domains_test.go
Outdated
dest := e.GetNamedRoleManager("g2").(*defaultrolemanager.RoleManager) | ||
origin.SetTenantManager(dest) | ||
|
||
testDomainEnforce(t, e, "alice", "dom2", "data", "read", true) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think in terms of the nature of this test case, alice should be tested from domains 1, 2 and 3 since she has access to all of them.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Added more tests
@@ -528,6 +535,16 @@ func (dm *DomainManager) rangeAffectedRoleManagers(domain string, fn func(rm *Ro | |||
return true | |||
}) | |||
} | |||
if dm.tenantManager != nil { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same thing about repetition as in my review.
@@ -449,6 +451,11 @@ func NewDomainManager(maxHierarchyLevel int) *DomainManager { | |||
return dm | |||
} | |||
|
|||
func (dm *DomainManager) SetTenantManager(tm rbac.RoleManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Needs documentation on how to use this. Though at the same time, shouldn't the hierarchy be enabled by default?
What is base definition for Named Grouping Policies? If you set up a grouping policy for domains shouldn't they be hierarchical by default? @hsluoyz
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't quite understand what you are saying. This PR is to use the RoleManager to manage the hierarchy of the domain
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking out loud and more broadly how hierarchy should be enabled for the DomainManager. Not something that is necessary to solve in this pull request.
@@ -438,6 +439,7 @@ type DomainManager struct { | |||
domainMatchingFunc MatchingFunc | |||
logger log.Logger | |||
matchingFuncCache *util.SyncLRUCache | |||
tenantManager rbac.RoleManager // Used to manage hierarchical relationships between domains, see |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
, see
what? I think the naming should also be OKed by @hsluoyz, so that it's clear for the purpose.
hierarchyManager
could also be a name option. Or something similar. Tenant
feels little bit generic and might cause confusion. What's the definition of tenant in casbin?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
rename
c537f74
to
de04510
Compare
@Sefriol Some changes have been made in response to your suggestion, please review again. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we need somebody else to review this than just me 😀.
@@ -267,3 +268,12 @@ func TestGetAllDomains(t *testing.T) { | |||
|
|||
testGetAllDomains(t, e, []string{"domain1", "domain2"}) | |||
} | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried to implement this in casbin/node-casbin#380
I think it's not possible to define g2
in the format of child, parent
. At least in nodeJS, it provided incorrect results, but maybe golang
has a different RoleManager definition.
You can try to replicate the test case I did for nodeJS. I think it provides quite good coverage on all the possible use cases. Especially the 4 domain structure is essential.
I have tried to comment on why certain decisions were made in the pull request and a little bit about the thought behind the hierarchy model.
@@ -449,6 +451,11 @@ func NewDomainManager(maxHierarchyLevel int) *DomainManager { | |||
return dm | |||
} | |||
|
|||
func (dm *DomainManager) SetTenantManager(tm rbac.RoleManager) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking out loud and more broadly how hierarchy should be enabled for the DomainManager. Not something that is necessary to solve in this pull request.
e, _ := NewEnforcer("examples/rbac_with_domains_hierarchical_model.conf", "examples/rbac_with_domains_hierarchical_policy.csv") | ||
origin := e.GetNamedRoleManager("g").(*defaultrolemanager.RoleManager) | ||
dest := e.GetNamedRoleManager("g2").(*defaultrolemanager.RoleManager) | ||
origin.SetDomainHierarchyManager(dest) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we add a helper function, so that you can enable the hierarchy without digging up the RoleManager? Like EnableDomainHierarchy
which would set DomainHierachy to g
with g2
by default.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It might be good, but I don't have time to do it right now
Maybe you should use |
@tangyang9464 Sure. I changed the implementation to use |
@zsh1995 I tested all your use cases and all passed. Maybe we don't need to change g2 to |
@zsh1995 At the same time, I want to discuss the difference between |
Yeah I am not sure what kind of exact solution we should be looking for. My intent with following policy lines:
is to create domain structure like domain1
├── domain2
│ └── domain3
└── sibling2 Which would result that Alice is an admin in all domains and Bob only in domains 2 and 3 with as few Key things I am trying to achieve here:
Policy testing should include that:
Checks like I guess more important factor in this case is performance. In a case of not knowing which domain object I derived my implementation from a model used in our production, so using hierarchy would not require us to do any conversation work. I'll add your model too to |
For some reason these tests in @tangyang9464 Can you send me the results of |
Signed-off-by: tangyang9464 <tangyang9464@163.com>
@nodece Commented on this in the In general I am in favor of implementing this directly to the model definition. |
@Sefriol Agree, modify later |
@tangyang9464 Have you heard any updates on the issue? Is there currently a plan on how this could be implemented? @hsluoyz Pinging you as well if there is anything to update :) |
@tangyang9464 on latest casbin code, following test cases are not working. testDomainEnforce(t, e, "alice", "domain1", "data2", "read", true) // Failed
testDomainEnforce(t, e, "alice", "domain1", "sdata2", "read", true) // Failed
testDomainEnforce(t, e, "alice", "domain1", "data3", "write", true) // Failed
testDomainEnforce(t, e, "alice", "domain2", "data3", "write", true) // Failed
testDomainEnforce(t, e, "bob", "domain2", "data3", "write", true) // Failed |
@sujit-baniya Current code is unlikely to be accepted anyway since there was more preferred idea to support this directly in the model definition. |
@Sefriol Can you please suggest preferred ways to implement via model definition? |
I suggest we should do so to avoid diversification. |
I think Casbin Team should decide what kind of approach we should be going into. They have a better idea than I do on what needs to be taken into account. I can be part of the implementation on the NodeJS side, but |
@nodece @tangyang9464 @hsluoyz Have you had a discussion about this? NodeJS version of this was kinda just merged with unsolved questions. |
Signed-off-by: tangyang9464 tangyang9464@163.com
for: #1032 (comment)