Fork me on GitHub

Mastering Sites

Usefull site managing concepts.


issue #38
secure (who can do what)
access control lists (ACLs)


A “master site” in zena serves pages for a given domain name, and has a set of user accounts and data nodes.

Additional “alias sites” can be set up for a master site, each serving pages for an additional domain name, sharing the same user accounts and data nodes of the master site.

Every site may use a different “home” node (rendered as start/index page).

Node permissions are good where permissions are to get inherited by childnodes and only need to be administered by master site admins (like for fundamental webmaster node access permissions).

The core node permission system knows read/write/publish/delete/chmod rights, but they can only be assigned to single group. Thus, instead of directly giving an additional group access to a node, using the node permission system requires to have an admin create a new group, add the users of both groups to the new group, and assign the node permission to the new group.

Access control lists (ACLs) allow to define application level access permissions on a finer grained and more flexible basis.


Avoid depending on node instance tree structure for data organisation (grouping etc.). Use classes (can also have own template) and links, instead of instance tree sorting.

The node instance tree should only be used in terms of “location defines the basic node access”:
  • Inherit or set fundamental node access rights (for public and webmaster access) for nodes belonging to different subtrees or entire (alias) sites.
  • Inherit or set the default skin for rendering the nodes under the master site domain. (Alias site domains are usually set to a specific “forced” skin that renders only a subset of the nodes.)

The nodes can be scoped from the tree by referring to: in self, parent, project, section, sub_nodes, home, site, ... .
The tree provides no help to query for the individual node you want to scope from to begin with.

But there are a few things that can be modeled completely and well with the node instance tree:
  • Truly unique hierarchies like land divisions.
  • A convenient way to render menus by listing child nodes of some class. The default skin lists “Page” class nodes in the menu. (->TODO: Support for a MenuEntryPage class (to render entries pointing elsewhere) and a not_in_menu Page property (NotInMenu role?).

In the above cases, you can get away with just defining a single head node of a special “head node” class (to query for the “head node in home”), and using the tree scoping from there.

In general, use tags and link relations to organize you data nodes in an accessible fashion (for database queries).

Specifically, use link relations to define administrative things.
  • acl-match-set nodes (see permission managment below)

Node management

Multi (alias site) domain nodes

In addition to the multi-site feature, that allows one zena installation to host completely seprate sites, zena’s multi-domain feature allows to host websites that share common node data. The shared node data of a master site can be accessed through multiple alias site domains with distinct appearance and functionality.

All alias sites of a master site share the same user, group, acl, etc. definitions.

You may configure the master site to host the administrative domain name of the server, with the root node (1) as the home node for the master site (default). The skin of the root node (1) may publicly render nothing but a login link, and render only the nodes appropriate for the logged-in user.

The real website domains may then be created as “alias sites” of the master site with their own home nodes.

root node

The root node has the zip 1 and all other nodes are either direct childs of the root node or childs of further childs.

Home nodes

If sites have…

... the same home node: The sites share the same content nodes.

For the rendering, specific skins might be forced for different sites, or an adaptive skin might render differently according to the domain name used in the request.

... child home nodes: Content below a subpage from the parent site appears on the index page of the child site.

... sibling home nodes: The sites have their own content nodes but may share nodes in every way.

Container Nodes

Container notes (may be a class with a not, or conditionally, listing template) can be used to save data nodes without littering the root or other scopes with nodes. They provide default places to browse node collections of a class or similar kind. Yet, the collections don’t have to be complete, because nodes of a class may actually be freely located anywhere in the website tree (e.g. to assign them to a specific site manager group). Usage: Query the desired parent container using a title filter.

Or put data nodes (and containers?) in project/section for deeper enumeration?

  • Use …-container node child classes as parent node for multiple other nodes of a class. These parent container nodes may then be linked like the parent class, without being itself considered of exactly the same ”=” class (i.e. may be filtered using ”=” or ”!=”).

Or use …-container parent classes?

Example node instance tree hierarchy

/ (section container, belongs to master site admins, contains alias site nodes with read/write/publish/delete/chmod permissions set to corresponding alias-site groups)
/ (project home node, or project container for home node of other class)
/ (container)
/ (container) Contacts possibly editable by a acl-match-set “contacts-mgr” group.

/site contacts/ (container belonging to master site admins)
/land divisions/country/state/region/... (containers for references linked to contacts)

Permission management

Core, application, and system level

  • Only use zena’s core user groups to assign node permissions (read, write, publish, delete, chmod) to basic groups like public, siteX-read, siteX-write, siteX-publish, siteX-delete and siteX-chmod. (When you are using application level permissions, the only members directly assigned to these groups are the webmasters of the sites (with general rights on a tree of nodes).
  • Set up further site-, node-, class-, ... specific application level permissions by linking your users’s contact nodes as well as the nodes that should be accessible to them to “acl-match-set nodes”, and define ACLs that provide desired permissions for the linked nodes to the linked users. In the same way you can set up “acl-match-set admin nodes” that allow specific or peer users to manage the links of the acl-match-set nodes itself.
  • Login accounts with a status above “user” provide additional administrative permissions with effects on the master and alias sites.

Permission assignments


user: (login status) gives access to site(s) according to its group memberships and acls

read_group: (node attribute) allows specified group to read node properties.

write_group: (node attribute) allows specified group to write node properties.

publish_group: (node attribute) allows specified group to

-> delete_group: (node attribute) allows specified group to delete versions and the node. (Let delete actions (e.g. on r:link) fall back to unpublish if not possible?)

-> chmod_group: (node attribute) allows to manipulate node access rights

-> This asks for a small change when the write_group changes the parent node:

If the user does not have chmod rights,
  if the node currently inherits the access permissions,
    set the access rights as formerly inherited, in order to
    preserve the permissions
  if the adjusted permissions equal those of the new parent node,
    reset the permissions to "inherit" again

user groups: (administrative lists) assign users to groups that can be assigned to access righs.

Node based (admin) permissions

Define basic read, write, publish, and delete groups on the node tree (e.g. site, section- or project-tree specific groups), to divide fundamental webmaster node access permissions on the node instance tree.

If required, define additional core groups to further divide permissions to create and edit specific node class instances (e.g. “HtmlDocument uploaders”):

create_group: renamed to edit_group? (class attribute) allows to create and edit? node instances of the given class.

-> Please drop requiring to hardcode a custom skin setting together with custom node permissions. The settings should be independent. An option to select “inherit” for individual custom settings could be sufficient.


Admins may manually assign individual users to an arbitrary number of core groups as required.

To ease the day to day administration, it is possible to define user account profiles.

Admins and manger users may then simply assigned to one of the predefined user profiles to regular users, to make them inherit the predefined set of (group) permissions.

Because the profiles are mutually exclusive (users can only be assigned to one profile), the profiles can only be used to model access levels (where higher levels cover all lower levels) without risking assignment conflicts.


node managers (...-mgr): (acl match set node) linked users are referenced in ACLs to provide them access to a set of queried to nodes (possibly referring to nodes linked from the acl match set node). The ACLs may provide access only to nodes under specific home nodes.

manager admins (...-mgr-adm): (acl match set node) allows linked users to edit the corresponding acl match set node (linked users, and nodes if they can write to them).

System (common master site settings):

manager: (user status) can create user accounts? and update contact auth data which includes assigning profiles to regular users (but no direct core group memberships).

-> webdeveloper: (user attribute or build-in group) gives access to dev mode, clear_cache, and rebuild_index (without needing to be a master site admin), can read (but not to edit/delete) the classes, relations etc. shared throughout the master site. Write access to specific skins (templates, css, assets) can be assigned separately through a core user group and node permissions, or application level acl-match-sets. (Thus, a build-in “webdeveloper” group makes this easier than a user attribute.)

-> (In the future, classes, relations, etc. should also be loaded as part of webdeveloper editable skins.)

admin: (login status) can edit users/groups/acls/classes/.../img-formats. Used to set up the ACLs for site and node specific application level acl-match-sets.

-> superuser: (login status) full master site permissions (incl. Sites table and creating and editing sites)

-> Make the “Sites” table only accessible to the superuser group.

acl match sets


ACLs can be restricted to nodes fetched with an arbitrary sqliss query. Thus, if user restrictions are incorparated in the node query, the ACLs group restriction may be set to only a very broad restriction on the allowed users (just the basic public, write, publish, delete, or chmod group).

As a result, the application of the ACL can be controlled by linking user’s contact nodes to acl-match-set nodes, and these acl-match-set nodes to the nodes where the ACL should apply. The links can then be used in the ACL query to determine the nodes a visitor can access through this ACL.

The same acl-match-set method can even be used to allow users to edit acl-match-set nodes and user nodes (or acl-match-set nodes and content nodes) to manage the links, and thus the users (or nodes) of acl-match-sets.


Used to constrain acl queries to nodes linked “from acl match set nodes from visitors node”.
The acl may then switches exec_group to proper site’s read/write/publish group

•acl-match-set nodes (reference childclass) public/logged-in(former “site”) (linked relations: set_accessor contacts, set_include? sets? and set_nodes)

Used in acls to query nodes accessible for the site’s basic read/write/publish/delete core groups (To enable voting, contact forms, self-registration, ... managed by “group admins” that don’t need to be zena admins.)

• acl-match-set admin sets (linked: set_admin contacts, set_include sets?, mgt_groups)

Used to query acl match set nodes and users for acls that allow match admins to edit set_accessor and grp_admin links.


skinning concepts

adaptive skin: (same skin for different sites) adapts favicon, .css and divs according to requested domain and node hierachry

domain specific style sheets (editable by site managers)

specific skins: (separate skins, typically per site) used only for a subset of nodes (usually the home node and its childs) that inherit the skin.

A request for another node (out-of-home zip) will get rendered with the nodes own (inherited) other domain specific skin, if the requested (alias) domain has no forced skin defined, and if the node’s own template allows rendering the node for the visitors domain.

=> Specific skins thus usually have to be the forced skin for a domain (if they are not only specializing a generic master skin?) to ensure coherent rendering under the domain name, and have to render out-of-scope nodes conditionally.

specializing skins: builds upon (includes) generic skin parts from a master or template library skin.

specific specializing adaptive skins: sites have specific skins that specialize a generic adaptive skin.

set a specific skin in nodesystem skin setting that conditionally includes and specializes adaptive skin

requires a way to include every nonexisting class from generic template?

Skin selection

Note, that all nodes of a master site are shared between the master site and all its alias sites.

And that templates have the last say concerning rendering (even if the visitor has read access), and may make use of arbitrary domain ( == “”) group, node or anything specific rendering conditions.

However, admins may configure a forced skin for a domain, that can render the readable nodes of all sites (even if the node’s inherited skin would prevent rendering it for other domains). And a template editor can create templates that could render arbitrary properties of every readable node. Other alias sites are thus always able to re-render nodes with their templates (possibly just a little easier then re-rendering html pages from other public servers).

The responsible (used) skin is determined by:

  • acl’s exec_skin
  • (alias) domain’s forced skin setting
  • node inherited skin setting

-> Add (alias) domain default skin setting? (used if inherit is set to “site-default-skin”?)

Should allow rendering “shared” nodes for all domains with their own default template!

-> Add (alias) domain setting to disallow domain default skin to render any out-of-home nodes?

(shortcut alternative to conditional rendering in (alias) domain default skin)

  • node inheritance from nodesystem (parent, home, root)
  • the “default” template (if none is selected)

-> To avoid having to hardcode domains into templates, allow templates to test if equals or home.master_host (refering to nearest home node ancestor)? (home specializing template)
-> Add (alias) domain option to not render (non-shared) in-home-nodes in other domains?
(shortcut alternative to conditional rendering in all skins used by in-home-nodes)
-> Add (alias) domain option to dissallow rendering out-of-home-nodes under own domain?
(shortcut alternative to conditional rendering in (alias) domain override skin for out-of-home nodes)