? ? Success

User tests: Successful: Unsuccessful:

avatar LivioCavallo
LivioCavallo
26 Aug 2017

Summary of Changes

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]

  1. article model:
  • 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]


  1. articles model:
  • 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.

  1. featured model:
  • populateState function authorises at component level and eventually filters only published articles.
    Just like in articles model function this PS pospones to getItems.

Testing Instructions

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.

Expected result

All the unpublished, expired and in-future articles in "Uncategorised" category should be displayed (as user has permissions to 'edit' and 'edit-own').

Actual result

All the unpublished, expired and in-future articles in "Uncategorised" category are NOT displayed.

Notes

  1. I have not evaluated the performance impact of foreach loop in articles model getItems function that removes unwanted articles.

  2. Should the 'filter.published' settings be managed? How?

avatar joomla-cms-bot joomla-cms-bot - change - 26 Aug 2017
Category Front End com_content
avatar LivioCavallo LivioCavallo - open - 26 Aug 2017
avatar LivioCavallo LivioCavallo - change - 26 Aug 2017
Status New Pending
avatar LivioCavallo LivioCavallo - change - 26 Aug 2017
Labels Added: ?
avatar ggppdk
ggppdk - comment - 26 Aug 2017

Hi

  1. About category view / multi-article listings

You can not apply such changes to the loop of get items
you are removing items after the query, which has 3 problems

  • you will make pagination look broken , some pages will have 3 items some will have 10
  • even if pagination is off you will show a random number of items into the category view / multi-article listings
  • you are slowing down the view when retrieving a large number of items e.g. 50 - 500 items

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


  1. About retrieving a single record , then yes you can apply the changes that you did
    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

  • the DB model should return the item and the controller or the view should decide to how to use it , show it or not
  • it is OK if view / controller will call a method of the DB model to get view/edit/etc access, so i do not say that having ACL calculation in the DB model is bad, the bad thing is to use it inside the DB model the way that it is used

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

  • **my suggestion is that it should be left to the caller to decide if
    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
avatar LivioCavallo
LivioCavallo - comment - 26 Aug 2017

About 1.

Slowing down: the performance penalty can came only from:

  • the foreach loop at the end of getItems function that removes articles from $items array or
  • the different authorisation: at article level than at component level.
    In fact authorisations and selections are the same done at the moment by J!3.7.5.
    How much do you think would be the percentual penalization?

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." ?

avatar ggppdk
ggppdk - comment - 26 Aug 2017

@LivioCavallo

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

avatar LivioCavallo
LivioCavallo - comment - 27 Aug 2017

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.

avatar LivioCavallo LivioCavallo - change - 27 Aug 2017
The description was changed
avatar LivioCavallo LivioCavallo - edited - 27 Aug 2017
avatar LivioCavallo LivioCavallo - change - 27 Aug 2017
Title
Authorization at article level in com_content not always working
Authorization at article level in com_content not always working: Featured and Articles models
avatar LivioCavallo LivioCavallo - change - 27 Aug 2017
Title
Authorization at article level in com_content not always working
Authorization at article level in com_content not always working: Featured and Articles models
avatar LivioCavallo LivioCavallo - edited - 27 Aug 2017
avatar ggppdk
ggppdk - comment - 27 Aug 2017

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

  • you are breaking pagination, some pages will have 3 items some will have 10
  • even if pagination is off you will show a random number of items into the category view / multi-article listings

Any checks of which items to include

  • must be done / decided before the SQL query items

e.g. you can fix your reported issue by another way
suggest a PR that unpublished items will be shown to

  • super-users
  • item owners

or you can introduce a new ACL rule (component level only) "Ignore publication status"
the above are just some ideas

avatar franz-wohlkoenig
franz-wohlkoenig - comment - 5 Nov 2017

@LivioCavallo are the Bugs mentioned by @ggppdk are solved and this PR is good for Test?

avatar laoneo
laoneo - comment - 20 Mar 2022

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.

avatar laoneo laoneo - change - 20 Mar 2022
Status Pending Closed
Closed_Date 0000-00-00 00:00:00 2022-03-20 10:57:16
Closed_By laoneo
Labels Added: ? ?
Removed: ?
avatar laoneo laoneo - close - 20 Mar 2022

Add a Comment

Login with GitHub to post a comment