[4.0] [PoC] Leverage access check form the plugin loader in to the plugin#25152
[4.0] [PoC] Leverage access check form the plugin loader in to the plugin#25152HLeithner wants to merge 8 commits intojoomla:4.0-devfrom
Conversation
| $pluginAccessLevel = (int) PluginHelper::getPlugin($pluginType, $pluginName)->access; | ||
|
|
||
| // if the accesss level is public we don't need to load the user session | ||
| if ($publicAccessLevel !== $pluginAccessLevel) |
There was a problem hiding this comment.
It's everything in this conditional that lets you not load a plugin if ACL doesn't match, which is the scenario that needs to be avoided IMO. If you remove the changes from this file, in theory this PR is good to go for removing the access check from the root query and deferring responsibility into the plugin.
There was a problem hiding this comment.
This condition is only a shortcut for plugins that have the access level "public". If the access level is not "public" it will load the user and make a proper access check. this is also be done if the access level is set to guest.
The plugin is not loaded in line 168 if the user has no access to it, that's the same behavior then in the query. Because in the getAuthorisedViewLevels() function every user is automatically added to the public access level.
There was a problem hiding this comment.
The plugin is not loaded in line 168 if the user has no access to it, that's the same behavior then in the query.
That's the part I feel like needs to go away. A plugin should always load because there are going to be cases where the plugin needs to handle a failing ACL check for something within it, and with this condition that keeps the plugin from being able to deal with that.
IMO the aim should be the access checks are 100% within the plugin, there should be no checks outside of the plugin determining whether a plugin is even loaded.
There was a problem hiding this comment.
Set the access on the "Content - Load Modules" plugin to Registered, and view an article that has the {loadmodule} shortcode within it as a guest. I would expect that the shortcode is removed from the article when it is displayed, but because the plugin isn't loaded at all, the shortcode is going to print on the page. This is the exact type of scenario that moving the ACL checks to be solely within the plugin helps address, anything that's making ACL decisions outside the plugin means something that needs to be addressed in a negative access scenario cannot be done unless the plugin author implements a second ACL like field and instructs users to never touch the core Access field.
There was a problem hiding this comment.
Exactly this scenario is covered with this Pr but not for the legacy plugins. Only for plugins using a ServiceProvider.
In line 142 we register the service provider and only come to this code path for legacy code in Line 147
So every plugin for Joomla 4 have to manage the access control when a event is triggered. All legacy plugins are handled like in J3 (not loaded if the access level doesn't match).
There was a problem hiding this comment.
Then we're better off keeping the existing behavior instead of trying to replicate it in a round-about way. I think we just need to accept the B/C break and not have any form of ACL in front of plugins, the plugins themselves need to be responsible for handling it. Actually, I'd suggest the internal behavior is worse off if this code path is arbitrarily applying an ACL decision and the other code path isn't; there's too much inconsistency involved, both in the code and in trying to explain to end users why plugins selectively get loaded.
Plugins need to always load, period. It should not be possible for a plugin class to not at a minimum be instantiated if its group is loaded.
There was a problem hiding this comment.
I'm completely with you, the plugin should always be loaded. But doing this in J4 for legacy plugins makes no sense if we try to simulate the old code path.
The code path we are looking at is deprecated for Joomla 5 isn't it?
So we have the same behavior for J3 plugins and the new behavior for J4 plugins. The enduser will never notice this. If the plugin is correctly implemented the user will not have the choice to select a access level if the plugin doesn't support it.
There was a problem hiding this comment.
Why do we need to simulate the old code path though? And no, it won't be something that goes unnoticed by the end user.
- A plugin which uses the service provider approach and has a non-hidden access field will be loaded at all times (unless the developer puts ACL code in the service provider, which is IMO a huge mistake, but we've all seen some "interesting" code in extensions so this is going to be 100% in the realm of possibility)
- A "legacy" plugin which has a non-hidden access field can be not loaded if the ACL check fails
How does the user know if a plugin is "legacy" or uses the service provider?
This is creating a by-design inconsistency in the API and one that isn't transparent to the user.
There was a problem hiding this comment.
I see a high risk if we load a "legacy" plugin which doesn't do the access check and have no way to warn the user that the access field seen in the plugin configuration is ignored.
We can remove this field for all plugin ins and require the plugin author to implement it by him self.
If that's the way to go I can update the PR. Any opinions by @wilsonge ?
|
At the moment Benjamin is trying to delete the public access level only with the backend ;-) but I think he is failing. The parameter I used was not the public access level it was the "default" access level which is used when creating new items. |
Are you saying that you are using the value of "default" access level in global configuration to determine if an item is public? |
Yes that was my fault assuming that a config option that class "access" and the title "default access level" could be public... but @bembelimen corrected me that this that only the default value for newly created (content?) items. Thats the reason for the last commit going to use the hardcoded value "1" instead of the config option. |
|
If you are referring to an access level with an id of 1 (not at a pc right now) then that wont work. There is nothing to say that a site has an access level with an id of 1 |
Not sure what you mean with this. It's also not possible to delete this access level, if you manage to deleted it your site will no longer work because the login doesn't work any longer and without login you can't see anything because everything that has a access level that should be seen by the public has to be 1. |
|
Sorry i was unclear. There is nothing to say that the access level with id =1 is in use on the site. It is perfectly possible to build a site that doesn't use the access level that has an id of 1 |
No it's not possible, the value 1 is hard coded in getAuthorisedViewLevels see And even if you get this magically done the code still works because all menu and plugin items will by pass the "short cut" and validate against the user object as it is now. |
|
Well that's a bug then if you are saying that even if you remove any "User Groups Having Viewing Access" from the "access level" public that it still works |
|
technical it's a limitation of the system and it's not too bad in my opinion, at least I can't create a use case that needs a change. But I'm sure it's possible to construct one. |
|
Forcing there to be one access group isn't bad. Hardcoding it to ID 1 is. Even on a closed off system, making arbitrary assumptions that a specific row in a specific table will have a specific identifier is a bad idea. |
Changing this into a configurable value shouldn't be hard because iirc it's only on one position but it will impossible to change it at runtime. If someone wants to implement it I'm happy to look at it, I see no benefit. |
I guess we should be using |
No it doesn't. |
|
Then what does it do? |
|
It holds the access level new items (e.g. articles) get as default. See #25152 (comment) |
|
This is a massive backwards breaking change that serves almost no benefit at all. |
|
Whilst I understand the benefits of this in terms of there being no active sessions I'm not sure the benefits of this outweigh the cons. I'm going to choose to close this |
This is a proof of concept to remove the "always session creation" because of loading plugins incl. full b/c.
I know that this could be done better, this is only to get some feedback.
Summary of Changes
The quickicon joomlaupdate plugin is the only plugin at the moment that uses the service helper. I changed this to support access check on event trigger and disabled the access field as example. (make no sense to do both).
before patch
after patch
This mean we are not finished decoupling the cms from the user session, we have to do something similar to the menu. The simplest is to check for public access before loading the user.
Documentation Changes Required
Plugin authors has to do the access check on each event listener
If the plugin doesn't need support for access levels it can override the access field with a hidden field in the config file.