[ZDP] ZBook - Access Control in Zope topic

kamon.ayeva@bureauveritas.com kamon.ayeva@bureauveritas.com
Wed, 24 Nov 1999 16:07:06 +0100

Hi all,

I am trying to write an "Access Control in Zope" chapter for ZBook with
some advanced stuff and examples.
But I am new to the topic and this is a starting point.
So I would like your feedback on the content and directions for developing
or clarifying things.

At this point I essentially merged some chapters from DC's Zope Content
Managers Guide with the How-to from Amos, and the How-to proposed this week
by Anthony (Local Roles and the Owner Role).
I think it needs one or two additional examples and also information on the
GenericUserFolder product currently in development (I think ?). (If anyone
has information on this...)

*Managing Users*

Within a Zope site, users are represented by objects called User Objects
which are
managed in special folders called User Folders.
User objects maintain the information needed to identify and authenticate
users with the security system.

In standard Zope User Folders, the user authentication information consists
of a password and/or an internal domain name.
Other user folders may use different authentication information.

Users are tied into the authorization system by their assignment of roles.
Roles describe the kind of responsibility and
authorization possessed by a user.

*Controlling Access to Objects*

Access control or authorization is defined in terms of which roles are
assigned to which permissions.
In addition to specifying roles assigned for each permission, each
permission has an option for acquiring permission settings from containing
folderish objects.
So access to objects will generally be handled entirely from folders
containing the objects.

To perform access control settings for a given object, go to the "Security"
management screen...
Go to the _Applications_ section to see specificities of managing
authorization in Zope.

*Managing Permissions and Roles*

Administrators can create new roles and apply them to security settings on
When a role is added at a particular point in an object hierarchy, it is
made available for use at that point and below.

Zope has pre-defined roles that have either a special meaning or a
conventional usage. These roles are:

  o Anonymous. All users, including users that do not supply authentication
credentials. Giving a permission to the Anonymous role makes the
corresponding operations publicly accessible.
    By default, this role has "View" and similar innocuous permissions.

  o Manager. By convention, the Manager role is assigned to users with
responsibility for managing a Zope website or
     portions of a website. By default, all permissions associated with
modifying Zope objects are given to the Manager role.

  o Owner. When an object is created, the user who created it is given a
local role of Owner. By default, the Owner role
     has the same permissions as the Manager role.

In addition to specifying which roles have each permission, each permission
has an option for acquiring permission settings from containing folders.

The top-level or root folder  is where Zope's default permission settings
are defined. Access control for an entire Zope installation can
be controlled from that folder.

Different types of objects in Zope define different kinds of permissions.
For instance, all Zope objects have a permission called View Management
However, while Folder objects have a permission called Add objects, DTML
Method objects
do not since they cannot contain other objects. Similarly, an object with
specific functionality like a Confera Topic might have a
permission called "Add messages". Thus, the permissions available on an
object depend on the capabilities of that object.
You could notice that security views for folders show many permissions.
Folder security views show all permissions for
operations on all objects, not just those for folder operations. This is
necessary so that permission settings may be defined
centrally and acquired by contained objects.

*Local Roles*

Local roles allow users to be bound to roles at the level of an individual
object. Roles which are not acquired.
As well as the normal roles that you assign to a user, it's possible to
give a user local roles.
These are roles that are only valid in the context of the object. So if I
assign the local role
Editor to the user fredbert in the folder /documentation/userguide, this
role will only apply to objects in the folder /documentation/userguide.

To edit local roles for an object, go to the "Security" management screen
and click on the local roles link. You will then be
presented with the Local Roles management screen (manage_listLocalRoles).
To add a given local role for a given user, click on the user in the left
list, and select the role in the right hand list.
Say you give the user fredbert the Owner role in a folder - fredbert now
has all the access of the owner role, but only in that folder (and in
subfolders, of course).

Important note: Regardless of the permissions you give a local role, if you
grant them the Change Permissions permission, you're effectively granting
them the Manager role in that
folder (since they can just edit the permissions in that folder to boost
their own role).

A common use of local roles is to identify the owner of an object. This is
done with the special local role 'Owner'.
When an object is being created, Zope automatically assigns a local role of
Owner for the user who creates it.
As a consequence, the user who creates an object is given authorization to
manage that object.
This owner role can also be reassigned to another user using the
manage_listLocalRoles page.
This allows you to create for example a folder for a particular user, which
only they can edit, without having to create
a special role per user and per folder. This is how you can very easily
create 'home folders' for people, in a way similar to the zope.org site.

But local roles application is not limited to controlling ownership. You
can assign any user any role on a given object. However, it is
probably a good idea to restrict one's use of local roles to exceptional
cases, since it is much more time consuming to assign
local roles for objects than it is to assign roles to folders and allow
contained objects to acquire those role settings.


**Control Delegation**  (I am not really sure i am presenting the example
here correctly. If you have other suggestions, let me know.)

To illustrate a concept which is called Control Delegation and which
demonstrates Zope's powerfull security design, let's assume we have a site
functionning the following way:
- The site hierarchy is:
     +- Public (Folder)
     +- DeptA (Folder)
              +- index_html
     +- DeptB (Folder)
              +- index_html

- userAdmin is the superuser. You recall the one created in the setup phase
of Zope for managing the whole site.
- The Root and Public folders are publicly accessible in read mode without
- Folder DeptA is secured: userA is Manager, and userB & userC have access
limited to viewing documents (without modification).
- Folder DeptB is secured: userB is Manager, and userA & userC have access
limited to creating and modifying objects but they cannot manage

Let's decompose the access settings into several parts:

1/ To be more precise, the site's design actually looks like this:
     +- acl_users (UserFolder)
     +- Public (Folder)
     +- DeptA (Folder)
              +- index_html
     +- DeptB (Folder)
              +- index_html

We need to create a user folder containing users userA, userB and userC,
for authenticating them accross the site.
To do that, expand the root folder in the navigation frame of the
management interface, and access to it's subfolder 'acl_users'.
Use the Add button of this view to add userA, then enter a password and
confirm it. Now, press Add. Repeat this operation for userB and userC.

2/ Settings for Root folder: We grant only Default permission to the
Anonymous role.
So all users can publicly access the site without authentication, but they
cannot create objects, modify them or manage the site.

3/ Since Public is contained in Root, it acquires the same authorization
settings. We have nothing to do and you have now seen what acquisition in
security is.

4/ Settings for DeptA folder:
We assign Manager role to userA for this folder.
Then we create a new role called DeptAReaders to be set in the folder's
security, and give it only the Default permission.
So unauthenticated users cannot access the site.
This is Control Delegation, as userA can manage a portion of the site, i.e.
folder DeptA.

5/ Settings for DeptB folder:
We assign Manager role to userB for this folder.
Then we create a new role called DeptBEditors to be set in the folder's
security, and give it the following permissions:

  View management screens
  Undo changes
  Add objects
  Delete objects
  Add properties
  Change properties
  Delete properties
  Default permission

6/ Now let's check the Security view for the DTML method DTMLMethodA. Go to
See Figure...

All permissions acquire permission settings and no roles are assigned to
permissions explicitly.
Access to objects with permission settings like those shown in the figure
can be
controlled entirely from folders containing the object.

**Detecting User Roles in DTML**

DTML Methods can refer to the current user using the variable,
When this variable is inserted in a DTML Method, the user's name is
As an application, you may want to customize the look and feel of a page
based on the roles of the user viewing it.

1/ You can find out if a user has a role with the User object's has_role

  <dtml-if "AUTHENTICATED_USER.has_role('somerole')">

Note that AUTHENTICATED_USER is the user who is currently viewing a page.
This user may be the Anonymous user if they have not logged in.
You may also pass a list of roles to has_role. (Explain/develop that ?)

Zope 2 introduced the notion of local roles which complicates things a
little. It is possible to have different roles for different objects.
So if I am a Manager I may also have a local role of Owner on a Folder.

2/ To get the real roles that the user has in the context of a given object
(which takes into account local roles given in that object and in other
object higher up in the hierarchy),
you need to also pass in an object for context. For example:

   <dtml-if "AUTHENTICATED_USER.has_role('Owner',this())">
     You own this Folder.

this() returns the object on which a DTML method is being run.

3/ Alternatively, you can test for permissions on objects rather than role
with the has_permission method like so:

   <dtml-if "AUTTHENTICATED_USER.has_permission('View',someObject)">

This way, you can detect if a user is authorized to perform a given action
on a given object.