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

feat: add IPatternFuncs #1029

Open
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

abichinger
Copy link
Member

@abichinger abichinger commented Jun 7, 2022

fix: #1027

Changelog

  • add interface IPatternMatcher
  • add function SetNamedRoleMatcher
  • add function SetNamedDomainMatcher
  • mark AddNamedMatchingFunc and AddNamedDomainMatchingFunc as deprecated (these function should be removed with the next major release)

@kizjig please review these changes.
roleManager.AddDomainMatchingFunc("KeyMatch", util.KeyMatch) needs to be replaced with:

domainMatcher := defaultrolemanager.NewPatternMatcher(util.IsKeyMatch4Pattern, util.KeyMatch4)
roleManager.SetDomainMatcher(domainMatcher)

Benchmarks

before:
BenchmarkBuildRoleLinksWithPatternLarge-12                             1        11420789697 ns/op       5610426576 B/op 63632133 allocs/op
BenchmarkBuildRoleLinksWithDomainPatternLarge-12                      70          16872961 ns/op         4251498 B/op      86735 allocs/op
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge-12             1        11617835457 ns/op       5619315344 B/op 63660158 allocs/op

after:
BenchmarkBuildRoleLinksWithPatternLarge-12                           135           8714727 ns/op         2660236 B/op      62784 allocs/op
BenchmarkBuildRoleLinksWithDomainPatternLarge-12                     142           8885176 ns/op         2848862 B/op      62765 allocs/op
BenchmarkBuildRoleLinksWithPatternAndDomainPatternLarge-12           130           9349494 ns/op         2896310 B/op      65735 allocs/op

Signed-off-by: Andreas Bichinger [email protected]

@casbin-bot
Copy link
Member

@tangyang9464 @closetool @sagilio please review

@hsluoyz
Copy link
Member

hsluoyz commented Jun 7, 2022

@tangyang9464 @JalinWang @imp2002 plz review

Copy link
Member

@sagilio sagilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, the new matcher uses IsPattern to pre-check the tokens whether needed to call the Match function to avoid calling duplicate and useless match functions and storing useless match results.

role_manager_b_test.go Outdated Show resolved Hide resolved
Copy link
Member

@tangyang9464 tangyang9464 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@kizjig
Copy link

kizjig commented Jun 8, 2022

Thank you for these changes. Looks good to me too.

I have a related question, forgive me if I'm misunderstanding something here btw... If we create a role/domain manager with a max hierarchy of less than the default 10, for example 4. How is that value preserved when the enforcer has hardcoded calls to recreate the role manager with functions like this?

func (e *Enforcer) initRmMap() {
	for ptype := range e.model["g"] {
		if rm, ok := e.rmMap[ptype]; ok {
			_ = rm.Clear()
		} else {
			e.rmMap[ptype] = defaultrolemanager.NewRoleManager(10)
		}
	}
}```

@kizjig
Copy link

kizjig commented Jun 8, 2022

And as a follow up clarification question...

What's the best flow or best time to customise/recreate the role manager in terms of setting domain matching functions and max hierarchy level?

Should it be once we've created the enforcer with our model but before we've done the first initial load of the policy data?

@tangyang9464
Copy link
Member

tangyang9464 commented Jun 8, 2022

@kizjig In fact, you must call e.SetRoleManager (need to customize RoleManger, including setting max hierarchy level and domain matching functions) after NewEnforcer, then rebuild role links(e.BuildRoleLinks). Code like

e, _ := NewEnforcer("","")

roleManager := NewRoleManager(4)

domainMatcher := defaultrolemanager.NewPatternMatcher(util.IsKeyMatch4Pattern, util.KeyMatch4)
roleManager.SetDomainMatcher(domainMatcher)

e.SetRoleManager(roleManager)
e.BuildRoleLinks()

@kizjig
Copy link

kizjig commented Jun 8, 2022

@kizjig In fact, you must call e.SetRoleManager (need to customize RoleManger, including setting max hierarchy level and domain matching functions) after NewEnforcer, then rebuild role links(e.BuildRoleLinks). Code like

e, _ := NewEnforcer("","")

roleManager := NewRoleManager(4)

domainMatcher := defaultrolemanager.NewPatternMatcher(util.IsKeyMatch4Pattern, util.KeyMatch4)
roleManager.SetDomainMatcher(domainMatcher)

e.SetRoleManager(roleManager)
e.BuildRoleLinks()

Thanks. So if I take that approach in your code above, and then afterwards load policy data from disk/file, it will automatically build the role links for the incoming data right (assuming e.EnableAutoBuildRoleLinks(true) is already set)?

I'm trying to avoid loading/processing the data twice. So I see the flow working as something like...

  1. create enforcer
  2. customise new role manager and domain matching.
  3. set new role manager on enforcer
  4. Set e.EnableAutoBuildRoleLinks(true)
  5. load policy data from disk into enforcer internal memory model.

Does that sound correct?

@tangyang9464
Copy link
Member

@kizjig do like this

// 1. don't set adapter first to avoid calling LoadPolicy automatically.
e, _ := NewEnforcer(model)

// 2. customise new role manager and domain matching.
roleManager := NewRoleManager(4)
domainMatcher := defaultrolemanager.NewPatternMatcher(util.IsKeyMatch4Pattern, util.KeyMatch4)
roleManager.SetDomainMatcher(domainMatcher)

// 3. set new role manager and adapter on enforcer
e.SetRoleManager(roleManager)
e.SetAdapter(adapter)

// 4. load policy
e.LoadPolicy()

Unfortunately, autoBuildRoleLinks is set to true by default when the enforcer is created, so e.EnableAutoBuildRoleLinks(true) has no effect. Maybe we will add a NewEnforcerWithOutBuild API to set autoBuildRoleLinks when creating an enforcer. So for now, we can only do it like the above

@kizjig
Copy link

kizjig commented Jun 8, 2022

Yes. thanks. That's what I had in mind. I am glad I was on the same page.

@kizjig
Copy link

kizjig commented Jun 22, 2022

Can we get this change progressed and merged in soon please?

@hsluoyz
Copy link
Member

hsluoyz commented Jun 22, 2022

@abichinger SetNamedRoleMatcher should be renamed to SetNamedRoleMatchingFunc. Matcher is a reserved keyword to specify the matcher (m = xxxx part) in PERM metamodel. It should not be pointed to anything else in Casbin. Actually in Casbin, anything called XXXer should be a complete and non-trivial component, like adapter, watcher, etc. A matching function is quite small and should not be named after XXXer.

@abichinger
Copy link
Member Author

abichinger commented Jun 23, 2022

@hsluoyz renaming SetNamedRoleMatcher to SetNamedRoleMatchingFunc and removing the reserved word Matcher would probably lead to the following function definition: (first solution)

//drm is defaultrolemanager
func (e *Enforcer) SetNamedRoleMatchingFunc(ptype string, isMatch drm.MatchingFunc, isPattern drm.IsPatternFunc) bool

IPatternMatcher would be split into MatchingFunc and IsPatternFunc
This would lead to minor disadvantages over the current solution:

  • we could remove redundant code if we move the cache from DomainManager and RoleManagerImpl to IPatternMatcher
  • no default implementations of IPatternMatcher like PrefixMatcher

How about I do the following renames: (second solution)

  • rename SetNamedRoleMatcher to SetPatternFuncsForRoles
  • rename SetNamedDomainMatcher to SetPatternFuncsForDomains
  • rename IPatternMatcher to IPatternFuncs
  • rename PrefixMatcher to PatternFuncsWithPrefix

I would prefer the second solution.
Please let me know which solution you would like me to implement.

add function SetNamedRoleMatcher
add function SetNamedDomainMatcher
mark AddNamedMatchingFunc and AddNamedDomainMatchingFunc as deprecated

Signed-off-by: Andreas Bichinger <[email protected]>
@abichinger abichinger changed the title feat: add IPatternMatcher feat: add IPatternFuncs Jul 23, 2022
@timabilov
Copy link

why this one is not merged yet?

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

Successfully merging this pull request may close these issues.

[Bug] - Domain manager rebuild() infinite loop?
7 participants