5 min read

Security primitives

Zope’s security is declarative: views, actions, and attributes on content objects are declared to be protected by permissions. Zope takes care of verifying that the current user has the appropriate access rights for a resource. If not, an AccessControl.Unauthorized exception will be raised. This is caught by an error handler which will either redirect the user to a login screen or show an access denied error page.

Permissions are not granted to users directly. Instead, they are assigned to roles. Users can be given any number of roles, either site-wide, or in the context of a particular folder, in which case they are referred to as local roles. Global and local roles can also be assigned to groups, in which case all users in that group will have the particular role. (In fact, Zope considers users and groups largely interchangeable, and refers to them more generally as principals.) This makes security settings much more flexible than if they were assigned to individual users.

Users and groups

Users and groups are kept in user folders, which are found in the ZMI with the name acl_users. There is one user folder at the root of the Zope instance, typically containing only the default Zope-wide administrator that is created by our development buildout the first time it is run. There is also an acl_users folder inside Plone, which manages Plone’s users and groups.

Plone employs the Pluggable Authentication Service (PAS), a particularly flexible kind of user folder. In PAS, users, groups, their roles, their properties, and other security-related policy are constructed using various interchangeable plugins. For example, an LDAP plugin could allow users to authenticate against an LDAP repository.

In day-to-day administration, users and groups are normally managed from Plone’s Users and Groups control panel.

Permissions

Plone relies on a large number of permissions to control various aspects of its functionality. Permissions can be viewed from the Security tab in the ZMI, which lets us assign permissions to roles at a particular object. Note that most permissions are set to Acquire—the default—meaning that they cascade down from the parent folder. Role assignments are additive when permissions are set to acquire.

Plone 4 Development: Understanding Zope Security

Sometimes, it is appropriate to change permission settings at the root of the Plone site (which can be done using the rolemap.xml GenericSetup import step—more on that follows), but managing permissions from the Security tab anywhere else is almost never a good idea. Keeping track of which security settings are made where in a complex site can be a nightmare.

Permissions are the most granular piece of the security puzzle, and can be seen as a consequence of a user’s roles in a particular context. Security-aware code should almost always check permissions, rather than roles, because roles can change depending on the current folder and security policy of the site, or even based on an external source such as an LDAP or Active Directory repository.

Permissions can be logically divided into three main categories:

  • Those that relate to basic content operations, such as View and Modify portal content. These are used by almost all content types, and defined as constants in the module Products.CMFCore.permissions. Core permissions are normally managed by workflow.
  • Those that control the creation of particular types of content, such as ATContentTypes: Add Image. These are usually set at the Plone site root to apply to the whole site, but they may be managed by workflow on folders.
  • Those that control site-wide policy. For example, the Portlets: Manage portlets permission is usually given to the Manager and Site Administrator roles, because this is typically an operation that only the site’s administrator will need to perform. These permissions are usually set at the site root and acquired everywhere else. Occasionally, it may be appropriate to change them here. For example, the Add portal member permission controls whether anonymous users can add themselves (that is, “join” the site) or not. Note that there is a control panel setting for this, under Security in Site Setup.

Developers can create new permissions when necessary, although they are encouraged to reuse the ones in Products.CMFCore.permissions if possible.

The most commonly used permissions are:

Permission

Constant

Zope Toolkit name

Controls

Access contents information

AccessContents Information

zope2.AccessContents Information

Low-level Zope permission controlling access to objects

View

View

zope2.View

Access to the main view of a content object

List folder contents

ListFolderContents

cmf.ListFolderContents

Ability to view folder listings

Modify portal content

ModifyPortalContent

cmf.ModifyPortalContent

Edit operations on content

Change portal events

N/A

N/A

Modification of the Event content type (largely a historical accident)

Manage portal

ManagePortal

cmf.ManagePortal

Operations typically restricted to the Manager role.

Request review

RequestReview

cmf.RequestReview

Ability to submit content for review in many workflows.

Review portal content

ReviewPortalContent

cmf.ReviewPortalContent

Ability to approve or reject items submitted for review in many workflows.

Add portal content

AddPortalContent

cmf.AddPortalContent

add new content in a folder. Note that most content types have their own “add” permissions. In this case, both this permission and the type-specific permission are required.

The Constant column in the preceding table refers to constants defined in Products. CMFCore.permissions. The Zope Toolkit name column lists the equivalent names found in ZCML files in packages such as Products.CMFCore, Products.Five and (at least from Zope 2.13), AccessControl. They contain directives such as:

<permission
id="zope2.View"
title="View"
/>

This is how permissions are defined in the Zope Toolkit. Custom permissions can also be created in this way. Sometimes, we will use ZCML directives which expect a permission attribute, such as:

<browser:page
name="some-view"
class=".someview.SomeView"
for="*"
permission="zope2.View"
/>

The permission attribute here must be a Zope Toolkit permission ID. The title of the <permission /> directive is used to map the Zope 2-style permissions (which are really just strings) to Zope Toolkit permission IDs.

To declare that a particular view or other resource defined in ZCML should not be subject to security checks, we can use the special permission zope.Public.

LEAVE A REPLY

Please enter your comment!
Please enter your name here