ACL Tutorial
This article will give you a quick overview about the new MidCOM ACL system. It is by no means complete and you should keep an eye on the API documentation on the classes that are in use here. But for a start it should give you the great picture.
This article gives you a real-life overview over the current state of the MidCOM ACL system as defined in the mRFC 0015: MidCOM Authentication and Access Control service.
Be aware, that there have been slight changes to the API defined in
there during the course of the implementation, so this document takes
priority over the mRFC.
Privilege structure wrapup
Basically we have two situations:
You want to assign a privilege to a user or group directly
These are the privileges, which are completly independant of a content object and assigned to the user directly. They use the string SELF as assignee and are always assigned to either a MidgardPerson or a MidgardGroup.
These privileges are loaded only once when the user is loaded (in midcom_core_user) and are used as the base for all further privilege checks against content objects.
You want to assign a privilege to a content object
An object is considered a content object at the time you specify it for a permission check. They are merged into the privilege set of the user itself during the check time as midcom_services_auth::can_do requires a content object as parameter.
So, on all objects you intend to use as a content object (which could very well be Persons or Groups), you can set privileges and assign them to users or groups. During the can_do checks MidCOM climbs the content tree and merges the privileges collected there with the set it initially got from the user in question. You may use the magic assignee EVERYONE to apply a content privilege for everyone.
Mixing EVERYONE and SELF
When you mix these two magics on Persons and Groups, be aware that EVERYONE does not include the SELF range. Thus, a privilege assigned to a MidgardPerson with the magic EVERYONE will not be in the privilege set assigned to the user directly. Instead, it will only be accessed if the User in question is used as a content object.
Using Privileges
Defining privileges
Right now, there is no place where privileges are defined, you do this on the fly when setting the parameter.
However, this is not the way things will be in the future.
Within the next one or two weeks there will be an interface in the Component system which has to provide a list of privileges to the core along with their default values (granted or prohibited). So stay tuned at this front, I'll update this document as soon as this interface becomes available.
Working with privileges
You use the midcom_services_auth class, available as $_MIDCOM->auth as a entry point. As you can see in its API documentation, it already provides several ways of checking for permissions, group memberships and so on.
The most important part is the can_do and, correspondingly, the require_do functions. You should use both in combination, using can_do to limit the actual UI correctly (so that users don't see what they can't do anyway) and require_do to protect the corresponding functions in addition to the UI manipulation (to prevent direct URL access). So, usually can_do is in the layout/output code, while require_do is used in the handle phase.
These two methods always require a content object to correctly merge the privilege chain. If you do not have an explicit content object (like an article) handy for your check, check against the current content topic.
Setting privileges using the MidCOM API
There is currently no GUI for this, but you can use the API functions of the MidCOM DB classes as defined in the MidCOM Database layer class API. See there for the exact method signatures. They are available on all classes built with the new MidCOM DB layer.
Setting privileges manually
Until you have an UI for setting privileges, you might want to set them manually, for testing purposes. This is not recommended for real code (use the set_privilege call instead)!
All parameters are in the domain midcom.auth.
The parameter's name combines the assignee and the privilege, while the value contains the privilege value.
Name syntax is "{$assignee_identifier}:{$privilege_string}".
The assignee_identifier is one of
- EVERYONE
- SELF
- group:$group->guid
- user:$user->guid
The privilege string is, as outlined in the mRFC, a prefixed by the namespace you are in (de.linkm.newsticker
for example) and the privilege name (which should basically be a simple
string), separated by a colon. So valid privileges for components are de.linkm.newsticker:post or, for the core, midcom:poweruser.
The user/group strings can easily be retrieved by using the property midcom_core_user->id or midcom_core_group->id, respectivly.
The privilege value is either 1 for ALLOW or 2 for DENY, clear the parameter to revert operation to INHERIT.