Plone 4 Development: Understanding Zope Security

Exclusive offer: get 50% off this eBook here
Professional Plone 4 Development

Professional Plone 4 Development — Save 50%

Build robust, content-centric web applications with Plone 4.

$35.99    $18.00
by Martin Aspeli | August 2011 | Content Management Open Source Web Development

Security should never be an afterthought when building web applications. Zope and Plone provide a robust and flexible security model that lets us worry about our application logic instead of thinking too much about how to lock it down, so long as we understand a few basics.

In this article by Martin Aspeli, author of Professional Plone 4 Development, we will explain the building blocks of Zope security: users, roles, and permissions.

 

Professional Plone 4 Development

Professional Plone 4 Development

Build robust, content-centric web applications with Plone 4.

        Read more about this book      

(For more resources on Plone, see here.)

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.

Professional Plone 4 Development Build robust, content-centric web applications with Plone 4.
Published: August 2011
eBook Price: $35.99
Book Price: $59.99
See more
Select your format and quantity:
        Read more about this book      

(For more resources on Plone, see here.)

Roles

Roles can be assigned globally to users and/or groups from the Users and Groups control panel. It is usually easier to create logical groups that can be assigned a set of roles once, rather than manage those roles for each user. The default Administrators and Reviewers groups have the Manager and Reviewer roles, respectively. There is also a pseudo-group called Logged-in users, which can be used to manage global and local roles that should apply to everybody who logs into the site. Every user is automatically a member of this group.

The Sharing tab, which appears on most content items, can be used to search for users or groups and assign them local roles. Note that the set of roles on the sharing tab is limited to those explicitly white-listed.

The sharing.xml GenericSetup import step can be used to list additional local roles on the sharing tab. See http://plone.org/documentation/manual/developer-manual/generic-setup for more details.

There are seven main roles in a default Plone installation.

Role

Purpose

Member

This is the default role for a Plone user. Quite a few permissions that normally apply to logged in users are given to this role. In CMF and Plone, the term member is also used more generally to describe users who are managed inside the site (as opposed to Zope-wide users).

 

Manager

This is the super-user role. Members of the Administrators group will have this role. Use it sparingly: a user with Manager rights has almost unlimited power over a Plone site.

Site Administrator

This role, which was introduced with Plone 4.1, allows us to define users with the ability to change the settings in Plone's control panels and view and edit almost all content, without giving them access to potentially destructive actions in the Zope Management Interface.

Reviewer

Users with this role, which is granted to the Reviewers group, can view and approve content that has been submitted for review.

Reader

This role is intended to be used as a local role only. It can be assigned from the Sharing tab, where it appears as Can view. When granted the Reader role, a user will usually be allowed to view a content object, even when normal Members cannot, for example, because the object is private.

Editor

This is the counterpart to Reader, is it used to assign modification rights locally. It is called Can edit on the Sharing tab. This allows content owners to delegate edit rights selectively to other users.

Contributor

This is used to delegate the right to add content items in folders. It appears on the Sharing tab under the title Can add.

If you create a new content type with a custom "add" permission, you should normally grant this to the Contributor role globally, using rolemap.xml. Similarly, if you have any custom permissions necessary to view an object, they should normally be granted to the Reader role, whilst any permissions necessary to modify an object should be granted to the Editor role.

In addition, Zope defines three automatically assigned roles:

Role

Purpose

Owner

This role is given to the owner of the current content item. Normally, this is the user who created it.

Authenticated

This is given to all logged-in users. This is more low-level than the Member role and cannot be revoked or granted explicitly. Therefore, it is usually better to rely on the Member role when designing a permission scheme for logged-in users.

Anonymous

This role refers to non-logged in users. There is a special user object, also called Anonymous, which is always granted this role.

Wherever a permission is granted to Anonymous, Zope will in effect stop checking the permission. This means that it is not possible to assign a permission to non-logged in users without also granting it to all authenticated users.

It is possible to create new roles through the rolemap.xml import handler in a GenericSetup profile (or through the Security tab in the ZMI).

Think carefully before adding too many new roles. A large number of custom roles is normally a sign that the security policy is not well thought-through. New roles usually require changes to the site's workflows.

Manipulating permissions and roles programmatically

To validate a permission in a particular context, such as the current content object, for the current user, we can do:

from AccessControl import getSecurityManager
from Products.CMFCore.permissions import ModifyPortalContent

sm = getSecurityManager()
if sm.checkPermission(ModifyPortalContent, context):
# do something

Permissions are identified by strings, so we could use "Modify portal content" instead of importing and using ModifyPortalContent, but using the constant is less error-prone.

To grant a particular permission to a list of roles, we can do:

context.manage_permission("Portlets: Manage portlets",
roles=['Manager', 'Site Administrator', 'Owner'], acquire=1)

Of course, it would be better to use a constant (provided there is one defined), but as the example shows, strings work too. Set acquire=0 to turn off acquisition of role assignments.

To find out if the current user is logged in (that is, whether the user is "anonymous" or not), we can use the portal_membership tool:

from Products.CMFCore.utils import getToolByName

mtool = getToolByName(context, 'portal_membership')
if mtool.isAnonymousUser():
# do something

Similarly, we can obtain the current member from this tool:

member = mtool.getAuthenticatedMember()
if member is not None:
userId = member.getId()

The user ID is a string that uniquely identifies the user. It should not be confused with the user's login name, which is the name used in combination with a password to log into the site. Sometimes, the user ID and login name are the same, but this is not always the case, particularly when authenticating against external user sources such as LDAP or Active Directory repositories.

Once we have a member object, we can look up member properties as in the following code:

fullName = member.getProperty('fullname')
email = member.getProperty('email')

Member properties are enumerated on the Properties tab of the portal_memberdata tool.

We can also find members by ID, using the following line of code:

adminUser = mtool.getMemberById('admin')

Take a look at the Doc tab of the portal_membership tool in the ZMI, or see Products.CMFCore.MembershipTool for more information about its API.

Summary

In this article, we have taken a look at Plone's approach to security, including key concepts such as users, groups, roles, and permissions.


Further resources related to this subject:


Professional Plone 4 Development Build robust, content-centric web applications with Plone 4.
Published: August 2011
eBook Price: $35.99
Book Price: $59.99
See more
Select your format and quantity:

About the Author :


Martin Aspeli

Martin Aspeli is an experienced Plone consultant and a prolific Plone contributor. He served on the Framework Team for Plone 3.0, and is responsible for many new features such as the improved portlets infrastructure, the “content rules” engine, and several R&D efforts relating to Plone 4.0. He is a former leader of the Plone Documentation Team and has written a number of well-received tutorials available on plone.org. He is also the author of Professional Plone Development and was recognized in 2008 by Packt Publishing as one of the “Most Valuable People” in Open source Content Management Systems.

Books From Packt


Practical Plone 3: A Beginner's Guide to Building Powerful Websites
Practical Plone 3: A Beginner's Guide to Building Powerful Websites

Plone 3 Intranets
Plone 3 Intranets

Plone 3 Products Development Cookbook
Plone 3 Products Development Cookbook

Plone 3.3 Site Administration
Plone 3.3 Site Administration

Building Websites with Plone
Building Websites with Plone

Plone 3 Multimedia
Plone 3 Multimedia

Plone 3 for Education
Plone 3 for Education

Plone 3 Theming
Plone 3 Theming


No votes yet

Post new comment

CAPTCHA
This question is for testing whether you are a human visitor and to prevent automated spam submissions.
f
h
9
e
L
G
Enter the code without spaces and pay attention to upper/lower case.
Code Download and Errata
Packt Anytime, Anywhere
Register Books
Print Upgrades
eBook Downloads
Video Support
Contact Us
Awards Voting Nominations Previous Winners
Judges Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software
Resources
Open Source CMS Hall Of Fame CMS Most Promising Open Source Project Open Source E-Commerce Applications Open Source JavaScript Library Open Source Graphics Software