ACL Administration for sections of a component

195 views
Skip to first unread message

Robert

unread,
Jul 26, 2012, 4:38:54 AM7/26/12
to joomla-de...@googlegroups.com
Hi All,

I am working in a project where we develop a large component and we have the need to configure the ACL for a certain area. Maybe think about a CRM (it isn't a CRM but seems to me to be an easier path to explain), we have people, leads, offers, contracts and invoices. Not all people should be allowed to do anything with any of the parts. Some people are allowed to create people and leads, but can't create offers, contracts and invoices. So I'll administrate the rights: admin, manage, create, delete, edit, edit.state for any of the parts, in this easy example I end up with 6*5 == 30 access rights. My first idea was that I split it in sections, we have this in the access.xml you can write '<section name="component">' or '<section name="person">'. My expectation for this was that I can administrate this out of the box. So I created a config.xml and used the rules field more than ones in a config.xml and changed the sections that it fits to my configuration (In fact I copied the permission filesset). I tried to set up the configuration and it looked as it would work. But I would not write all this if it works weel. You get the output and it looks you can do it but with a closer look you'll find out that ids are not unique and it doesn't works at all.

I asked myself some questions:

Does it makes sense to have this option for configure a component?
I think it makes sense, but I am happy to hear others thoughts.

Was the system build for it?
Maybe, we have often the situation that the basic ideas are very good and it looks very flexible, but the real implementation stopped at some point. That is ok, because we need to finish the job and release a software package in time.

What do we have to do to extend the system that we can do the sections administration?

1) We need to change the rules field, so that it is using unique id's. I think the best way is to use the section value for that because we need that information later for saving the data.

2) Extending the save function. At the moment it uses a hard coded "rules" the find out if rules information should be saved.


I think that is not such a big deal and would extend the functionality in the right direction. I don't think that we have backwards compatibility problems, because it is only extending functionality and when we define that rules.component == rules is then we don't change the old system.

What do you think about that? Anything I missed?

Cheers,
Robert

subtextproductions

unread,
Jul 26, 2012, 12:35:11 PM7/26/12
to joomla-de...@googlegroups.com
Robert,

Based on what you've said, I think the Joomla ACL system should work for you right out of the box. Does your access.xml file look like this?

<?xml version="1.0" encoding="utf-8" ?>
<access component="com_mycomponent">
<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="people">
<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="leads">
<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="offers">
<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="contracts">
<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="invoices">
<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>
</access>

If so, you should be able to use the configure modal in your administrator interface to set up permissions based on each group that you have. Then in your controllers for each of the individual sections you authorize the user against the permissions. For instance if someone wanted to create an invoice the following code would be invoked:

$user = JFactory::getUser();
$user->authorise('core.create', 'com_mycomponent.invoice');

You might want to check out this thread from a few weeks back:


Good Luck

elin

unread,
Jul 26, 2012, 7:58:54 PM7/26/12
to joomla-de...@googlegroups.com
You can make different sections corresponding to different tables but to make it work there are a number of other things you must do. 

First, decide how you want inheritance to work and map it out. That will require you to decide what you want to inherit directly from the component and what you want to inherit from some intermediary level such a categories (and what you want to inherit from root if you want that) and if you want to track assets at the individual item level.

Second decide on a naming structure. As part of this you will need to extend _getAssetName for each type


Third set up the access.xml with the specific sections each with their own actions, most of which will probably be inherited from the component section. Use the same names for inheritance. You might also want to track individual assets (deals = section deal = item for example) and you will include those as sections also.

I'm not really sure what you are talking about with extending the save function. Save happens automatically in the rules fields.  I think I probably can guess though ... ok so you have 

component
   section1
           item1-1
           item1-2
   section2
           item2-1
           item2-2
   section3
           item3-1
           item3-2

so saving component is obvious (asset parented to  the extensions table) as is saving the items (these assets are linked to the individual items tables). However you want them  inheriting from section not component so they need to have a parent asset corresponding to the section. That means you need an asset for each section. These are then going to have to be stored somewhere so you can build a view in which the permissions for the sections can be edited. So you need a separate table, tracking assets, that has as a parent your component and that also your items are foreign keyed to and also use as a parent_id in the asset table. Each row in the table is one of the sections. 

Assuming the list of sections is fixed, the tricky thing that you are going to need to do is to inject an asset for each section during installation. It is absolutely essential that you do this properly with the API in order to assure that the asset table does not become corrupted.

Anyway the system itself can absolutely do what you want, it is just more complex than the item component only or component/categories model that most extensions use.

Elin

Robert

unread,
Jul 27, 2012, 5:41:12 AM7/27/12
to joomla-de...@googlegroups.com
Thanks you for looking into this:

@subtextproductions, it seems we are have both the same expectations. The missing pice is the administration part, the modal window doesn't work for configurations like this.

@elin, thanks for your posting. You are right with the inheritance and how it works. Probably I didn't explained it very good. What I'll do it using parallel configurations.It is not component->category->item it is
* component-> ....
* person->
* leads ->

and so on.

I created a small component com_acltest, hope that makes it more clear what I am trying to do. The archive can be downloaded form here: https://dl.dropbox.com/u/959364/com_acltest.zip

It should be installable. When you click on the options icon you can see two panels component and area51. Both panels are rules fields and it looks good so far but it doesn't work. 

Hope it is now more understandable what I am trying to achieve.

Cheers,
Robert

elin

unread,
Jul 27, 2012, 7:16:46 AM7/27/12
to joomla-de...@googlegroups.com
Where are you expecting the rules2 field to save? 

The only thing you can/should save in the component options are the permissions at the component level because those are going to save in the rules field of the asset table in the row for your component.  

You could turn permissions at the section level  into component level permissions by giving them custom names.  So in addition to/instead of the basic core.edit you could have core.leads.edit, core.invoices.edit all in the component section of your access.xml. These would not inherit from global configurations because they have different names.  Then instead of canEdit when you do your checks you will do canEdit.invoices. 

Elin

Robert

unread,
Jul 27, 2012, 7:25:17 AM7/27/12
to joomla-de...@googlegroups.com


Am Freitag, 27. Juli 2012 13:16:46 UTC+2 schrieb elin:
Where are you expecting the rules2 field to save? 

#__asset as name=com_acltest.area51

I know this doesn't happen. That's why I ask, if this makes sense. I think it makes. 

 

The only thing you can/should save in the component options are the permissions at the component level because those are going to save in the rules field of the asset table in the row for your component.  

You could turn permissions at the section level  into component level permissions by giving them custom names.  So in addition to/instead of the basic core.edit you could have core.leads.edit, core.invoices.edit all in the component section of your access.xml. These would not inherit from global configurations because they have different names.  Then instead of canEdit when you do your checks you will do canEdit.invoices. 

But that would end in many permissions at one level and the administration would be confusing.


Robert
 

elin

unread,
Jul 27, 2012, 8:51:55 AM7/27/12
to joomla-de...@googlegroups.com

Unless you make that happen in a Jtable extension it is not going to happen.   All the core cms is going to take care of for you is:
com_acltest

and 
com_acltest.item.id  assuming you set up your table to track assets and set it to use  the name com_acltest.item. Otherwise #__acltesttable.id.

The whole thing works around the assumption that you have a table with an asset_id column for every asset that you want to work with. So you must have a table with that list of your sections with asset_id for each.

You will need to inject those into the asset table on install (or some other time, like if the user enables invoices as an option, you inject that asset then). This is not part of the standard installation which just injects a row and asset for the component as a whole.
  Those assets (that don't exist) are what you are trying to modify, but you can't because you are doing it in the UI for changing permissions of com_acltest not in the UI for changing the permissions of com_acltest.area.

Yes it would be complex UI to do the other option (treat them all as component level) which is why it would be better to give each section its own asset and then making a UI for managing the permissions on those assets.  

This is a really complex thing and not intuitive at all, which is why we all struggle with it. But if you look at com_content for example, you do not set the permissions for the categories in the component options. You set them at the individual category level and those levels inherit from the general settings for the whole component. What you need is something like com_categories that lets you set the permissions at the section level level that you have.

If you look at the access.xml for com_content you see 3 sections. One for the component that is managed in the options ui of the article manager. One for category which is handled in the UI for editing individual categories in com_categories. And one for article that is handled in the UI for editing individual articles.  That's the structure you need to set up, but you are missing the UI and the assets for your sections. 

Elin
Reply all
Reply to author
Forward
0 new messages