J3.x:Developing an MVC Component/Adding ACL
From Joomla! Documentation
Articles in This Series
- Introduction
- Developing a Basic Component
- Adding a View to the Site Part
- Adding a Menu Type to the Site Part
- Adding a Model to the Site Part
- Adding a Variable Request in the Menu Type
- Using the Database
- Basic Backend
- Adding Language Management
- Adding Backend Actions
- Adding Decorations to the Backend
- Adding Verifications
- Adding Categories
- Adding Configuration
- Adding ACL
- Adding an Install/Uninstall/Update Script File
- Adding a Frontend Form
- Adding an Image
- Adding a Map
- Adding AJAX
- Adding an Alias
- Using the Language Filter Facility
- Adding a Modal
- Adding Associations
- Adding Checkout
- Adding Ordering
- Adding Levels
- Adding Versioning
- Adding Tags
- Adding Access
- Adding a Batch Process
- Adding Cache
- Adding a Feed
- Adding an Update Server
- Adding Custom Fields
- Upgrading to Joomla4
This is a multiple-article series of tutorials on how to develop a Model-View-Controller Component for Joomla! Version
.
Begin with the Introduction, and navigate the articles in this series by using the navigation button at the bottom or the box to the right (the Articles in this series).
Introduction
This tutorial is part of the Developing an MVC Component for Joomla! 3.2 tutorial. You are encouraged to read the previous parts of the tutorial before reading this.
Adding Access Control
With Joomla!'s Access Control we can define which user groups are allowed or denied to do which actions in your component. In this example we use actions that are defined in the core. For the component as a whole: core.admin (access to the configuration) and core.manage (access to the backend). And at various levels actions like create, delete and edit. Besides those core actions you can define your own actions, but that is often not necessary and is not shown in this example. View/Read Access is not managed via those actions but with View Access Levels; see general documentation about Joomla!'s ACL for that.
In the #__assets table the actual list is stored: which user groups are allowed or denied to do which actions on which resources (assets). This is the implementation of the Access Control List (ACL).
In this article we will show how to add and use access permissions at several levels of granularity: for your component as a whole, for the categories and for the individual items.
To test this functionality create users and associate them with the user groups which have access to the back end admin functionality (ie those user groups which have Administrator Login permission in the Global Configuration Permission Settings). By default this is Manager and Administrator, but you can also define your own user groups, and optionally set them as children of Manager or Administrator.
If you're not already very familiar with Joomla Access Control then it's recommended to watch this video ACL Explained (between 2 minutes and 32 minutes is the section to watch) and read this Access Control List Tutorial.
Three videos associated with this tutorial step cover Joomla's Access Control Infrastructure, an explanation of this step's tutorial code and a supplementary video on Access View Levels.
Minimal ACL requirements at the component level
There are 2 actions that need to be defined at the component level for a Joomla! 2.5+ component to offer basic ACL support:
- Configure (core.admin): which groups are allowed to configure the component level permissions via the 'Options' toolbar button?
- Access Component (core.manage): which groups are allowed to access the component's backend?
This basic ACL support is done in 4 simple steps:
- Add the 2 minimal component level actions to access.xml
- Add the permissions fieldset to config.xml
- Add the 'Options' toolbar button
- Restrict the access to the component's backend
Add the 2 minimal component level actions to access.xml
A minimal ACL access.xml would consist of only those 2 basic actions:
Basic admin/access.xml
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
</section>
</access>
See admin/access.xml for the current and more elaborate version.
Add the permissions fieldset to config.xml
Add the following permissions fieldset to admin/config.xml in order to be able to set our component level permissions.
<fieldset
name="permissions"
label="JCONFIG_PERMISSIONS_LABEL"
description="JCONFIG_PERMISSIONS_DESC"
>
<field
name="rules"
type="rules"
label="JCONFIG_PERMISSIONS_LABEL"
class="inputbox"
validate="rules"
filter="rules"
component="com_helloworld"
section="component"
/>
</fieldset>
See the more elaborate config.xml example further downwards for the exact place where to insert this code.
Add the 'Options' toolbar button when user is authorised for it
In the admin/views/helloworlds/view.html.php file you can add the following code to check if the user can edit the preferences:
// Options button.
if (JFactory::getUser()->authorise('core.admin', 'com_helloworld'))
{
JToolBarHelper::preferences('com_helloworld');
}
See further downwards for a more elaborated example of admin/views/helloworlds/view.html.php where this JToolBarHelper::preferences('com_helloworld') is done in an addToolBar()-method together with the other toolbar buttons and the JUser->authorise()-check is done with JHelperContent, resulting in the $canDo-property.
Restrict the access to the component's backend to authorised usergroups
To control the access to the backend of the component add the following lines to the admin/helloworld.php entry-file:
// Access check: is this user allowed to access the backend of this component?
if (!JFactory::getUser()->authorise('core.manage', 'com_helloworld'))
{
throw new Exception(JText::_('JERROR_ALERTNOAUTHOR'));
}
See further downwards for the whole code of the admin/helloworld.php file.
Adding more actions, also at category level and item level
When adding more actions and more levels, the above described 4 steps are done too:
- Add the actions to access.xml; here we can add more actions and levels
- Add the permissions-fieldset to config.xml
- Add the 'Options' toolbar button
- Restrict the access to the component's backend
In addition we also have to do the following steps:
- Add an asset_id to the item's database table for item level access control
- Store the permissions in the assets table. Especially take care of setting the asset_id of the parent-asset
- Make the settings of the permissions at the item level editable
- Add some language strings
Describing the actions you want to control the access to
Each component (or part of it) has its own set of permissions that can be controlled. They are described in an access.xml file located at the root of the admin folder. In this helloworld-example the actions to which access is controlled are divided in three sections: at the component level, the category level and the item level. An 'item' is called a 'message' in our example component, hence the name of the third section.
admin/access.xml
<?xml version="1.0" encoding="utf-8" ?>
<access component="com_helloworld">
<section name="component">
<action name="core.admin" title="JACTION_ADMIN" description="JACTION_ADMIN_COMPONENT_DESC" />
<action name="core.manage" title="JACTION_MANAGE" description="JACTION_MANAGE_COMPONENT_DESC" />
<action name="core.create" title="JACTION_CREATE" description="JACTION_CREATE_COMPONENT_DESC" />
<action name="core.delete" title="JACTION_DELETE" description="JACTION_DELETE_COMPONENT_DESC" />
<action name="core.edit" title="JACTION_EDIT" description="JACTION_EDIT_COMPONENT_DESC" />
<action name="core.edit.state" title="JACTION_EDITSTATE" description="JACTION_EDITSTATE_COMPONENT_DESC" />
<action name="core.edit.own" title="JACTION_EDITOWN" description="JACTION_EDITOWN_COMPONENT_DESC" />
</section>
<section name="category">
<action name="core.create" title="JACTION_CREATE" description="COM_CATEGORIES_ACCESS_CREATE_DESC" />
<action name="core.delete" title="JACTION_DELETE" description="COM_CATEGORIES_ACCESS_DELETE_DESC" />
<action name="core.edit" title="JACTION_EDIT" description="COM_CATEGORIES_ACCESS_EDIT_DESC" />
<action name="core.edit.state" title="JACTION_EDITSTATE" description="COM_CATEGORIES_ACCESS_EDITSTATE_DESC" />
<action name="core.edit.own" title="JACTION_EDITOWN" description="COM_CATEGORIES_ACCESS_EDITOWN_DESC" />
</section>
<section name=