Custom privilege types in real life projects

Playing around with a custom privilege type I think we hit an implementation limit, or at least I think we can improve the implementation.

Let me first explain the usecase I have seen in different projects now:

• Every account logging on to the website gets his own profile page which is implemented as a node
• This node is then used for making references to other pages, like groups of people, departments, and so on
• Based on the relation of that person to for example a group certain nodes should have read restriction
So in short: limit read access to node of type ‘My.Package:InternalPage’ if the ‘profile page’ node has no reference to the parent of the ‘InternalPage’
It’s doable to create a custom privilege target for that. This should then for example look like:

      matcher: 'nodeIsOfType("My.Package:InternalPage") && currentUserIsInParentGroup()'

Imagine this now all works. This matcher would now match a set of nodes based on the current security context. As such this specific resource is now protected as it is defined as privilegeTarget, so basically you’re done.

Done? Do I not need a GRANT or DENY? Nope, the opposite… If you add a GRANT for a role this privilege is granted and as such the sql generated by your custom privilege class is not taken into account which neutralizes the policy and will just give access to anybody.

I find this rather confusing tbh, but I feel like it is because using the current user from the security context inside of a matcher is wrong. When you do that you basically define a role (at runtime) that the user has. So probably it would be better to for example allow a configuration like:

      matcher: 'nodeIsOfType("My.Package:InternalPage") && currentUserIsInParentGroup()'
        privilegeTarget: 'My.Package:GroupInternalPages'
        permission: ${currentUserIsInParentGroup() ? 'GRANT' : 'DENY'}

I know multiple people have similar usecases in projects atm, like for example using dynamic roles, limiting site access and so on. So I’d really be curious to hear other experiences / opinions how we can improve this. Because the implementation I did now does not feel like a really nice integrator experience in this regard (although I really love the extensibility of the matchers)


you are totally right - I’ve explained some background on the current behavior on (taken from a german discuss thread, thanks @chkoeppel for translating it and adding it to the docs). Maybe that explains the current behavior some more. I personally do not “like” it the way it is, but I have spent a lot of time thinking it through, and I cannot come up with a better, more consistent way of modelling things either :wink:

I would suggest you do NOT use the “DENY” permission, but rather use “ABSTAIN” (which means “Deny unless somebody allows it”). When you use DENY, you say “Deny, no matter what the others say”.

I like your idea of making the permission an Eel expression :slight_smile: Cannot see any negative side effects right now, as they are evaluated at runtime anyway.

@bwaidelich, @andi , @christianm, @robert - what are your thoughts on this? (And others as well of course :slight_smile: )

All the best,