Hey everyone,
I’ve already used Kirby in some projects, where everything worked like a charm and I’m really liking it so far.
However, for a current project I’m working on, more complex permissions that go beyond role-specific boolean definitions would be welcome (such as recursively checking pages for authorship).
Therefore I’m currently thinking about and building a plugin for more flexible permission definitions. A MVP is already running quite well thus far.
This should allow for example to define permissions like this: read: q{kirby.user.role.id} === 'admin' || q{page.checkAuthorship(kirby.user)} && q{page.template.name} === 'project'
.
This is my approach:
-
automatically inject Page (
AdvancedPage
) and User (AdvancedUser
) models for existing page types and user roles that override the standard kirbypermissions()
method. The overridden methods return instances of aAdvancedPagePermissions
class or aAdvancedUserPermissions
class respectively. These furthermore extend the KirbyPagePermissions
andUserPermissions
classes and override the defaultcan()
method by extending it with a custom flexible permission evaluator. -
The custom permission evaluator is executed last, which only happens if a
string
is set as permission value instead oftrue
orfalse
. -
At this point, the custom permission evaluator first executes all queries, which have to be marked with
q{your_query}
(all queries are fetched with a simple regex like/q{(.*?)}/
) and then evaluates the resulting string, which should only contain boolean operations.
Current problems:
-
The custom permission evaluator internally uses the php
eval()
function, which poses potential security implications and should be avoided. -
Project specific page models are overridden. A potential solution would be to check for existing page models and extend them dynamically instead of the Kirby Page class (if this can be realized with php).
-
Probably many more, not so obvious, that I haven’t yet encountered
The following questions arose during ideation and development:
-
Is there a possible simpler solution for my issue?
-
Are there any problems that might emerge with this approach, or are there any stumbling blocks I need to be aware of?
-
Could the flexible permissions syntax collide with Kirby query definitions? (
q{your_query}
) -
What is the most sophisticated way to fetch all existing Page types to set corresponding models? (a
$kirby->templates()
function, which guarantees a correct resolution of file names (e.g. kebab- to camel-case conversion), doesn’t seem to exist) -
One strange behavior I encountered was that Kirby apparently chose the correct
test
template for a page with atest.txt
in a multilingual setup, but not the corresponding page model. After renamingtest.txt
totest.en.txt
it worked again. I have to dig deeper to really understand and reproduce what’s happening, but can you give a short assessment of whether this is a bug or not?
Your help and assessment would be highly appreciated.
Please do not hesitate to criticize and make suggestions for improvement