Skip to content

Pagebreak editor button Authorization problem #17754

@LivioCavallo

Description

@LivioCavallo

Steps to reproduce the issue

Create new category ONE and set permissions to registered users group to 'create', 'edit' or 'edit.own'.
Create a menuitem to Create (or edit, or edit.own) a new article in that category.
Create a 'Registered' user, login and go to that menuitem.

Expected result

Pagebreak button should be displayed.

Actual result

Pagebreak button is NOT be displayed.

System information (as much as possible)

J! 3.7.5

Comments and proposed solution

The problem is that the plugin button code does authorisation check at component level, not at asset level.
We could solve adding proper checks in pagebreak plugin button onDisplay function this way:

public function onDisplay($name, $asset, $author)
{
	$user  = JFactory::getUser();
	
// Original code was simply:
/*	if ($user->authorise('core.create', 'com_content')
		|| $user->authorise('core.edit', 'com_content')
		|| $user->authorise('core.edit.own', 'com_content'))
*/

// New code to authorise on asset - BEGIN
	$app       = JFactory::getApplication();
	$currView  = $app->input->get('view');
	
	// If a_id is missing, $articleId is forced to 0, so supposing a malformed url, lacking a_id=0, to create a new article
	$articleId = (int) $app->input->get('a_id');
			
	if ($currView === 'form' && $articleId === 0)
	{
		// Retrieve current menuitem
		$currMenuItem = empty($menu = $app->getMenu()) ? null : $menu->getActive();
		
		// Retrieve and sanitize 'enable_category' param
		$enableCategory = empty($currMenuItem) ? 0 : $currMenuItem->params->get('enable_category');
		$enableCategory = empty($enableCategory) ? 0 : $enableCategory;
		
		// If we have a valid 'enable_category' we can retrieve 'catid' from menuitem
		$catId = $enableCategory ? $currMenuItem->params->get('catid') : 0;
		
		// If the menuitem does not specify a predefined category, then use 0
		$catId = empty($catId) ? 0 : $catId;
		
		if ($enableCategory && $catId)
		{
			$authorised = $user->authorise('core.create', 'com_content.category.' . $catId);
		}
		else
		{
			/* User is authorised if it has component permission OR if it has permissions at least on a category.
			Strictly speaking we should authorise just the exact category in which user has permissions to create
			but if user has not permissions to create the the form view is forbidden too and we never reach this code row.
			Moreover doing so is a bit faster */

			// TODO: authorise on the category selected by user in editor, if it's not too time-expensive
			$authorised = $user->authorise('core.create', 'com_content') || count($user->getAuthorisedCategories('com_content', 'core.create'));
		}
	}
	else
	{
		$authorised = $user->authorise('core.edit', $asset) || ($user->authorise('core.edit.own', $asset) && $author === $user->id);
	}
	
	if ($authorised)
// New code to authorise on asset - END
	{
		JFactory::getDocument()->addScriptOptions('xtd-pagebreak', array('editor' => $name));
		$link = 'index.php?option=com_content&view=article&layout=pagebreak&tmpl=component&e_name=' . $name;

		$button          = new JObject;
		$button->modal   = true;
		$button->class   = 'btn';
		$button->link    = $link;
		$button->text    = JText::_('PLG_EDITORSXTD_PAGEBREAK_BUTTON_PAGEBREAK');
		$button->name    = 'copy';
		$button->options = "{handler: 'iframe', size: {x: 500, y: 300}}";

		return $button;
	}
}

So we'll have a fine-grained authorisation.

Additional comments

Similar issues are in other buttons.

But do we really need authorisation checks here?
Or could we just do as Readmore plugin does: NO authorisation check at all ?

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions