Custom ACL rule(s)

138 views
Skip to first unread message

Adam Rifat

unread,
Sep 11, 2012, 9:43:55 AM9/11/12
to joomla-de...@googlegroups.com
I want to have a finer grain control over which users can edit state. 

For example, I want one user group to be able to reorder but not publish. So I simply defined two new rules in access.xml:

<action name="core.edit.reorder" title="JACTION_REORDER" description="JACTION_EDITOWN_COMPONENT_DESC" />
<action name="core.edit.publish" title="JACTION_PUBLISH" description="JACTION_EDITOWN_COMPONENT_DESC" />

and then override canEditState in my model like below:

protected function canEditState()
{
    
    $task = JRequest::getVar('task', '', 'POST', 'string' );
    
$user = JFactory::getUser();
    if ($task == 'orderdown' || $task == 'orderup') {
      return $user->authorise('core.edit.reorder', $this->option);

    } else if ($task == 'publish' || $task == 'unpublish') {

      return $user->authorise('core.edit.state', $this->option);

    } else {
      return false;
    }
}

Does that seem reasonable? If so, I am going to have fun creating some more custom rules, me thinks.

A

tomfuller

unread,
Sep 11, 2012, 9:52:34 AM9/11/12
to joomla-de...@googlegroups.com
I have wanted to provide finer grain control over what menus admins can access on my component. Having this kind of flexibility with rules would be great. Will be following this post.

Ove

unread,
Sep 11, 2012, 12:27:34 PM9/11/12
to joomla-de...@googlegroups.com, Adam Rifat
Hi Adam,
I don't understand what you are trying to achieve. The task is checked in the controller. If a user isn't allowed to order/publish you should first disable or remove this from the view. (editform or list).
Adding actiions is of course possible. I think it's wise not to use core.xyz as a core.edit.publish and alike might appear in the core settings to split up the core.edit.state in future.

If you explain more I*ll try to give you some hints.

Ove
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To view this discussion on the web, visit https://groups.google.com/d/msg/joomla-dev-general/-/mZpRZ3Khjf0J.
To post to this group, send an email to joomla-de...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-gene...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/joomla-dev-general?hl=en-GB.

Adam Rifat

unread,
Sep 12, 2012, 4:26:49 AM9/12/12
to joomla-de...@googlegroups.com
Hi Ove, 

Essentially I want one user group to be able to reorder items using the standard orderup/orderdown tasks but not I do not want that group to be able to publish/unpublish the items they are editing. The items will be published either via an admin user or after the user makes the appropriate payment.

It seems that the core.edit.state permission combines these two actions into one which is why I am trying to split it out.

Are you suggesting that I should deny core.edit.state from the non admin user group (actually it is at the moment) and then define a custom reorder action and implement that along with a custom ACL rule? I guess that would also do the job but would involve more work. Do you think there is a problem simply overriding canEditState in the model?

I take your point about the naming. Perhaps I could call my custom rules mycomponent.edit.reorder and mycomponent.edit.publish to avoid any future conflicts. The publish action is hidden from the list view and the edit view.

Thanks,

Adam



To unsubscribe from this group, send email to joomla-dev-general+unsub...@googlegroups.com.

Ove

unread,
Sep 12, 2012, 6:32:16 AM9/12/12
to joomla-de...@googlegroups.com, Adam Rifat
I did understand order/up/orderdown and publish/unpublish but not what the task is doing in the model.

If you use a form you check core.edit/core.edit.own in the controller, mostly  named MycomponentControllerMyview (or automaticly by the parent). Then you modify the form in the model depending on some Acl rules see e.g. backend com_content  article.php line 333... .

As core.edit.stateI is used on a group of fields I probably would add one new for publishing and one for ordering
Modified to use only component Acl and two new access conrols with only field state(published) and ordering I think somethink like this is ok:
No canEditState method needed.

        // Modify the form based on Edit State access controls.
      // state field
        if (  !$user->authorise('mycomponent.edit.publish', 'com_mycomponent')
        {
            // Disable fields for display.
            $form->setFieldAttribute('state', 'disabled', 'true');

            // Disable fields while saving.
            $form->setFieldAttribute('state', 'filter', 'unset');
        }

       // ordering field
        if (  !$user->authorise('mycomponent.edit.ordering', 'com_mycomponent')
        {
            // Disable fields for display.
            $form->setFieldAttribute('ordering', 'disabled', 'true');

            // Disable fields while saving.
            $form->setFieldAttribute('ordering', 'filter', 'unset');
        }

If you use a Joomla type list you have to modify the toolbar and the item lines depending on those Acl controls.
You'll need a getActions method in the helpers/mycomponent.php. e.g. see com_banners/helpers/banners.php where you can remove the category code if you do not use it.
Then see the banners view.html.php for the toolbar and the tmpl/default.php for the table list header and item code.

 I know to little to have a specific idea for the "payment" but guess a payment would be a task of it's own that change the state to published and is checked in the controller.

Ove
To view this discussion on the web, visit https://groups.google.com/d/msg/joomla-dev-general/-/fdZ6llvc3hEJ.

To post to this group, send an email to joomla-de...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-gene...@googlegroups.com.

Adam Rifat

unread,
Sep 12, 2012, 8:32:47 AM9/12/12
to joomla-de...@googlegroups.com
I think we are on the same page more or less. ;-)

I am fine with setting the toolbar in view.html.php. I have the getActions method set-up in my helper and that all works fine. If the user isn't authorised to change state they don't see the publish/unpublish buttons etc. Also, in the view template I am hiding the column if the user doesn't have the correct authorisation. Actually, it hadn't occurred to me to show the field but set it to disabled. That might be a better solution so at least the user can see what state the item is in! 

All I am doing with canEditState is overriding the method provided by the base class. In the com_content article model that method is also overridden so I guess that's fine. The base canEditState only checks core.edit.state so I override it to check the custom rules I added. I need to do this as core.edit.state is not allowed but for some users mycomponent.edit.reorder is allowed. This explicitly prevents a user from changing the published state.

I'm not sure if a user can spoof the form if the field is 'disabled' but at least this way they should always be prevented from that action. 

Does that make sense?

Thanks, as usual you provide a different perspective which really helps.

Adam

Ove

unread,
Sep 12, 2012, 10:10:34 AM9/12/12
to joomla-de...@googlegroups.com, Adam Rifat
Yes, normaly it's better to show the fields but you could also set them to hidden instead of disabled. A much less elegant way would be to handle it in the view template. If wanted: with a couple of more if's you could also allow users to see the ordering column in the table and sort by this column but not change the order. See the core examples.

I can't see that the article model use canEditState even if it's there. i.e you shouldnt need it, as in my example. The banner model does, but nothing won only more code. I would also prefer not to hardcode any relationships as in your first post. i.e. set the Acl for each user group separatly is all.

The filter line that deletes the field on save

            // Disable fields while saving.
            $form->setFieldAttribute('state', 'filter', 'unset');

is there to prevent any spoofing I think.

Ove

elin

unread,
Sep 12, 2012, 10:29:31 PM9/12/12
to joomla-de...@googlegroups.com, Adam Rifat
Andrew has discussed this a few times and he usually recommends against detailed rules as part of the main system and instead for a plugin that would respond to the context and for example disable+unset  fields as one example. 

Elin 

Adam Rifat

unread,
Sep 13, 2012, 9:52:12 AM9/13/12
to joomla-de...@googlegroups.com
Elin, that's another approach which I hadn't thought about. At least that way the logic and code would be kept in one place rather than being scattered across (potentially) several model files. 

Ove, the canEditState method is overriden on line 193 of the article model.

One thing that I am slightly confused about is the 'unset' filter. Does that literally just remove the fields from the POST data when it is filtered? In that case the data would never be passed to the backend even if the user did manage to somehow spoof the form? 

Thanks,

Adam

elin

unread,
Sep 13, 2012, 1:29:23 PM9/13/12
to joomla-de...@googlegroups.com
Yes exactly, can't use firebug or anything because it is never sent. Totally the way to go. 

Elin

Ove

unread,
Sep 14, 2012, 12:17:41 PM9/14/12
to joomla-de...@googlegroups.com, Adam Rifat
@Elin Is your comment about a future idea? Is it about the current Cms core extensions?  I agree you can't create Acl rules for every field in the Cmc core components.
An example might be the alias field. Why not let a publisher or any other specified group change it in frontend?  How do you handle this with a plug-in responding to a context?

@Adam As I wrote there is a  canEditState method but it's not called! Using it is not wrong just needs some more coding.
You got me on the way to find out what the unset really means, I was 100% wrong.  As far as I can see it only disbales the filter and do not remove the field from the form array as I believed. Conclusion?

Ove
--
You received this message because you are subscribed to the Google Groups "Joomla! General Development" group.
To view this discussion on the web, visit https://groups.google.com/d/msg/joomla-dev-general/-/V-cuzml5lWMJ.

To post to this group, send an email to joomla-de...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-gene...@googlegroups.com.

elin

unread,
Sep 14, 2012, 1:32:51 PM9/14/12
to joomla-de...@googlegroups.com, Adam Rifat
You can do it now.
Myself  I would be extremely cautions of allowing anyone to change an alias field since it potentially impacts your urls, so unless you also are giving them access to com-redirect it's a bit dangerous for SEO unless managed carefully. However letting someone with create make their own alias seems reasonable to me.

Elin
To unsubscribe from this group, send email to joomla-dev-general+unsub...@googlegroups.com.

Ove

unread,
Sep 15, 2012, 6:18:51 AM9/15/12
to joomla-de...@googlegroups.com, elin, Adam Rifat
Elin,

In Quote "you can't create Acl rules for every field in the Cmc core components." You was meant as "Joomla Cms core" The plug ins are nice to override conceptual behaviour but not allways to implement them. You're right about my alias example but you might also want to give the publisher a chance to modify it before the item is publsihed. Conclusion: You (we) can't cover it all in the core code.

Ove
To view this discussion on the web, visit https://groups.google.com/d/msg/joomla-dev-general/-/ttGEV8M43FQJ.

To post to this group, send an email to joomla-de...@googlegroups.com.
To unsubscribe from this group, send email to joomla-dev-gene...@googlegroups.com.

Adam Rifat

unread,
Sep 17, 2012, 5:06:41 AM9/17/12
to joomla-de...@googlegroups.com, elin, Adam Rifat
I think elin's point was more to do with how to deal with the display of forms that have specific/custom ACL rules applied to them. As per your comment above if a certain action is not authorised then those fields are disabled using JForm->setFieldAttribute. The point is that if you have several rules and several edit screens in your component it might get messy to have that logic in your model. In which case it might be appropriate to move that into a plugin where you can respond to different contexts within the component. 

The user profile plugin does this where it responds to the various contexts in which a user profile may be edited. Sure, this could be done in the model but it's easier to maintain in a plugin and also a new plugin can be added to override the default behaviour.

If you only add one or two custom ACL rules it's probably not such an issue. If you have lot's of ACL rules and want more flexibility perhaps a plugin is the way to go.

Also, I think canEditState is called at some point by the framework otherwise the core.edit.state rule wouldn't work at all. It does work (even if I don't overload it) so it must be called... ;-)

Thanks,

Adam
Reply all
Reply to author
Forward
0 new messages