Fork me on GitHub

access control lists (ACLs)

For the basic group permissions see: secure (who can do what)

Access control lists can be used in addition to the group based permissions, to give users higher privileges for specific requests.

ACLs allow to grant existing groups read/write/update/delete access to a selection of additional nodes (defined with a SQLiss query).



An “Acl” is composed of :

  1. target users: Who can benefit from the Acl.
  2. action: What those users can do with this Acl.
  3. query: On which nodes they can use it.
  4. exec: Privileges and skin to use for the request execution.

The “priority” field is used to order the rules: the first appropriate rule where the query returns the node in question is used.

The “mode” and “format” fields refer to the type of pages. For example, you might want to only allow access to “_preview” pages.

The “format” is to allow access to “pdf” or “jpg” or “xml” or “html”.

The query is ruby code, a nonsense example that matches all nodes (filtering by class) with a title that starts with “scrap” is:

%Q{nodes in site where title like "scrap%"}

“%Q{...}” acts like a double quoted string in ruby.

For put, get, delete operations the accessed node has to be among the result of the query. For “create” ACLs, the the parent node has to match.

To use “create” ACLs in conjuction with new, the “edit group” of the class needs to include the group of the user as well.

How does it work ?

Curently (for performance reasons) ACLs are only checked if the request of a user would otherwise fail (because the user is not in the appropriate group for the node). Then Zena checks if this user has “acls” enabled. If this is the case Zena tries to find a rule that the user can use to access the content by searching through the list of defined Acls.

To determine if a rule can be applied to the visited page, the rule’s SQLiss query is executed from the context of the visitor’s contact node. This means that the “assigned_projects” relation above would allow access to any node found through this relation when starting from the visitor’s node.

You can use “self” as auto-relation so that the visitor can view her own page.

Once a first matching rule is found, its “exec_group” is added to the visitor for the duration of the request.

You can also force the use of a given Skin for the request. This is usefull, if your default skin would render more (everything) for the added group (is not considering, for example, further relations), because you usually still want to restrict what less privileged visitors can see when the acl provides them read access.

Showing visitors controls for their ACL permissions

Because zena is not checking every ACL on every read request (for performance reasons), the ACLs alone do not trigger the rendering of appropriate automatically generated forms.

Until a tag is available that can be added to templates to load ACLs conditionally, the simplest solution for this is to create templates to show the desired forms whenever someone visits the page with ACLs (independent from the normal Zena checks for write access):

<r:if test='visitor.in_group?("acl-group")'>

<li id='add' do='t'>add_btn</li>
<li id='form' style='display:none'>

<r:form klass='Post' redir='url(main)'>
  <r:input label='t' name='date' type='date'/>
  <r:input label='t' name='title'/>