User tests: Successful: Unsuccessful:
Joomla! has a fantastic permissions system that allows fine-grained settings in components, categories till to the article level.
In the major part of cases all these settings are correctly checked and respected but in some circumstancies 'com_content' only checks permissions at component level: article, articles and featured models.
[The following problem is now in PR #17735 - BEGIN]
populateState
function authorises at component level and eventually filters published and archived articles.
A 'TODO' in comments seems to me to clearly suggest that a different authorisation was intended.
This PR authorises at article level.
getItem
function authorises at component level and eventually filters not-expired and not-future articles.
It seems to me that article level authorisation was simply forgotten.
This PR authorises at article level.
[Previous problem is now in PR #17735 - END]
populateState
function authorises at component level and eventually filters only published articles.
In fact I think that it cannot do otherwisely as we still do not have article ids here.
The only way to authorise at article level here would be to build a SQL query to do all the authorization work, but I think it's impossible, given the complexity of authorise
code.
This PR postpones authorization and article selection, based on publishing state, to getItems
function so authorization can be done there at article level.
getListQuery
function authorises at component level and eventually filters not-expired and not-future articles.
Like in populateState
function, here is the only option.
This PR analogously postpones to getItems
.
getItems
function just uses authorise
function to detect if user can edit articles.
This PR does all the previously posponed jobs: authorises, here at article level, and eventually filters out articles that are not published or are expired or future, if user hasn't 'edit' or 'edit.own' permissions.
To filter out articles that the user must not see, we remove them from the articles collection (the $items
array) during usual foreach
loop, so the successive code will just work on permitted/authorised articles.
populateState
function authorises at component level and eventually filters only published articles.getItems
.Create some featured articles in different categories (but "Uncategorised" would be enought); articles should have different publishing status: published, unpublished, published-expired, unpublished-expired, published-in-future, unpublished-in-future.
Create a 'Featured' menuitem.
Set permissions in 'Uncategorised' category to allow 'Registered' group to 'edit' and 'edit.own'.
Create a user in registered group and login in frontend.
All the unpublished, expired and in-future articles in "Uncategorised" category should be displayed (as user has permissions to 'edit' and 'edit-own').
All the unpublished, expired and in-future articles in "Uncategorised" category are NOT displayed.
I have not evaluated the performance impact of foreach
loop in articles model getItems
function that removes unwanted articles.
Should the 'filter.published'
settings be managed? How?
Category | ⇒ | Front End com_content |
Status | New | ⇒ | Pending |
Labels |
Added:
?
|
About 1.
Slowing down: the performance penalty can came only from:
Pagination: Oh! Pagination! Right.
About 2.
Thanks. Seems resonable.
Ok, we could move the authorisation and 'filtering' logic to view, but how to solve the pagination problem? (I think it will remain)
Or could we simply display empty placeholders and a message like "Some elements may have been hidden as you have not permissions to display them." ?
besides the pagination problem i also mentioned and the slow down
there is 3rd thing that i mentioned:
even if pagination is off you will show a random number of items into the category view / multi-article listings
so i say let's not change at all the getItems method
you can make your PR just for the case of single item
with 1 modification for new records $pk is zero , do not try to check ACL on asset:
com_content.article.0
Do you have a measure or an estimate of the slow down?
Calling authorise on 'com_content.article.0' simply returns false when needed.
Moreover article model is not used for new records, in that case J! uses the form model, then article model will never be passed a $pk value of 0.
I cannot reproduce your problem with random items in category view / multi-article listings. When does it happen?
Yes, we now have PR #17735 for single article and this for featured and article listings.
Title |
|
Title |
|
hi, lets forget the slow down totally ! (when listing more than 50 or more than 100 items)
and focus on the 2 bugs that this PR introduces
Any checks of which items to include
e.g. you can fix your reported issue by another way
suggest a PR that unpublished items will be shown to
or you can introduce a new ACL rule (component level only) "Ignore publication status"
the above are just some ideas
@LivioCavallo are the Bugs mentioned by @ggppdk are solved and this PR is good for Test?
Sorry that it has taken so long to respond to this pull request. Unfortunately this pr has unknown side effects, especially with pagination. In the current state it is not something we can consider to get merged, so I'm closing it. If you still see it as an issue, then please rebase to the 4.2 branch. For the testers, please do some proper testing with front end list views and pagination. Also consider to add some system tests for API testing pagination. Thanks for your contribution and help, making Joomla better.
Status | Pending | ⇒ | Closed |
Closed_Date | 0000-00-00 00:00:00 | ⇒ | 2022-03-20 10:57:16 |
Closed_By | ⇒ | laoneo | |
Labels |
Added:
?
?
Removed: ? |
Hi
You can not apply such changes to the loop of get items
you are removing items after the query, which has 3 problems
the decision to include or exclude published items must be part of the query
Now about the existing approach of using the
if ((!$user->authorise('core.edit.state', 'com_content')) && (!$user->authorise('core.edit', 'com_content')))
i agree the above is not so good either because having edit/edit.state at component level but not having edit/edit.state e.g. in a category AA , will allow someone to list articles of category AA that are not published
my approach (in our component) is always to filter out unpublished items, and use 1 extra ACL rule, only at component level to allow listing unpublished items (or if user is not guest and is owner of the items)
in any case ACL checks per item in the item loop after the query are not good option for the reasons stated above
allowing viewing unpublished if user has edit / edit.state at the particular article asset is correct
you are fixing an existing approach,
Now to comment on the existing approach
existing approach is not proper, it is not proper to do such check at DB model
e.g. on some page visit, some plugin is triggered to do some work
and loads the article DB model to do it
now because DB model will not return the unpublished item such work can not be done
ok and the plugin has to use direct SQL queries to do the work
I argue that DB model should only have methods to calculate access view / edit / etc
but it should not make use of them
as said above my point 2 is not relevant to your PR , for number 2 you are improving the existing approach
getItem() needs to check view publication state (and bypass publication state according to ACL edit/edit.state on the item) via a parameter that will be given to getItem() !
now such option does not exist