[Grok-dev] HEADS UP: grok.define_permission gone in favor of grok.Permission

Sebastian Ware sebastian at urbantalk.se
Wed Aug 22 09:42:47 EDT 2007

I just want to remind about the permissions tutorial... it needs to  
be updated :)

Mvh Sebastian

Luis De la Parra <lparrab at gmx.net>:

Hi all,

I'm re-opening the thread on security/permissions from beginning of  
Sebastian did proof-read it and made some comments on it, but I was  
over 3
weeks with tons of work and pretty much off-line, so I'm just  
starting to
catch up with stuff..

here it goes again, with sebastian's comments addressed..
cheers. luis

Newbie Permissions Tutorial

Zope3 and Grok come with authorization capabilities out of the box.  
While a
vanilla Zope3 application protects all content by default and performs
authorization checks on the content objects themselves. On the other  
Grok allows access to everything unless you explicitly restrict it,  
and the
authorization checks are done on the Views used to access
(display/manipulate) the content.

     from zope import component, interface, schema
     import grok

     class IContactInfo(interface.Interface):
         """ Interface/Schema for Contact Information """
         first_name = schema.Text(title=u'First Name')
         last_name  = schema.Text(title=u'Last Name')
         email      = schema.Text(title=u'E-mail')

     class ContactInfo(grok.Model):

         first_name = ''
         last_name  = ''
         email = ''

     class ViewContact(grok.View)
         """ Display Contact Info, without E-mail. Anyone can use  
this view,
             even unauthenticated users over the internet
         def render(self):
             contact = self.context
             return 'Contact: ' + contact.first_name + contact.last_name

Defining Permissions and restricting access
As all Views in Grok default to public access, anyone can use the
ViewContact-view defined above. If you want to restrict access to a  
you have to explicitly protect it with a permission.


#   Define Permissions. This can be any string, but it is
#   strongly recommended to make them unique by prefixing
#   them with the application name


     class ViewContactComplete(grok.View)
         """ Display Contact Info, inclusive email.
             Only users which have the permission 'mysite.ViewContacts'
             can use this view
         grok.require('mysite.ViewContacts')  #this is the security

         def render(self):
             contact = self.context
             return 'Contact: ' + contact.first_name +  
contact.last_name +

Granting Permissions

You can grant permissions to principals with a "PermissionManager". For
example, if all registered users
should have permission to view contact details and create new  
contacts, you
could grant them the permissions when the user account is created:

     from zope.app.security.interfaces import IAuthentication
     from zope.app.securitypolicy.interfaces import

     def addUser(username, password, realname):
         # create a new user and give him the authorizations  
ViewContacts and
         # EditContacts. This example assumes you are using a
         # Pluggable Authentication Utility / PrincipalFolder, which  
you have
         # to create and register when creating your Application
         pau = component.getUtility(IAuthentication)
         principals = pau['principals']
         principals[username] = InternalPrincipal(username, password,

         # grant the user permission to view and create contacts
         # everywhere in the Site
         permission_man = IPrincipalPermissionManager( grok.getSite() )

         # NOTE that you need a principal ID. If you are  
authenticating users
         # with a PAU this is normally the user name prepended with the
         # principals-folder prefix (and  the PAU-prefix as well, if  
                                               principals.prefix +  
                                              principals.prefix +  

Permissions are set for the context for which the PermissionManager is
created, and --if not explicitly overridden-- all it's children. The  
example gives the 'View' and 'Add' permissions for the complete site,
unless a folder down in the hierarchy revokes the permission.

If you want users to be able to edit only their own ContactInfos, you  
to give them the 'Edit' permission only within the context of the
ContactInfo-object itself


     class AddContact(grok.AddForm):
         # only users with permission 'mysite.AddContacts' can use this.
         # NOTE that if you don't protect this Form, anyone --even  
         # unauthenticated users-- could add Contacts to the site

         form_fields = grok.AutoFields(IContactInfo) #automagically  
form fields

         def create(self, **kw):
              # Create and Add the ContactInfo to our context  
(normally a
              # Folder/Container)
             contact = ContactInfo()
             self.applyData(contact, **kw)
             self.context[contact.first_name] = contact

             # Grant the current user the Edit permission, but only  
in the
             # context of the newly created object
             permission_man = IPrincipalPermissionManager(contact)


     class EditContact(grok.EditForm):
         grok.require('mysite.EditContacts') #only users with
permission 'mysite.EditContacts' can use this

         form_fields = grok.AutoFields(IContactInfo)

         @grok.action('Save Changes')
         def edit(self, **data):
             self.applyData(self.context, **data)

Checking Permissions
[FIXME How to check permissions in a page template and from python code?
User Interfaces should not contain any links/actions which users cannot
access / for which users don't have authorizations]

Defining Roles
Permissions can be grouped together in Roles, which makes granting  
all the
permissions for a particular type of user much easier.

     from zope.app.securitypolicy.interfaces import  
     from zope.app.securitypolicy.interfaces import  

[FIXME: Roles have to be first defined / registered as a local  
[FIXME: As of July 2007, there has been some discussion on the  
mailing list
about simplifying role definitions. This section may be outdated]

     role_man = IRolePermissionManager( grok.getSite() )

As an example, let's group all permissions in two roles: one for  
normal site
members, and one for admins



Now, if the context here is the Site/Application, users with the
Administrator role can edit all ContactInfos, regardless who the  
creator is

     role_man = IPrincipalRoleManager(context)
     role_man.assignRoleToPrincipal('mysite.Administrator', principalID)

22 aug 2007 kl. 15.19 skrev Jan-Wijbrand Kolman:

> Hi,
> This is an important heads up!
> As has been discussed before (http://thread.gmane.org/ 
> gmane.comp.web.zope.grok.devel/1637/) the define_permission is now  
> gone in favor of the grok.Permission component base class.
> So, from now on, instead of:
>   grok.define_permission('grok.NicePermission')
> you do:
>   class NicePermission(grok.Permission):
>       grok.name('grok.NicePermission')
>       grok.title('Title for Nice Permission') # optional
> As an added bonus (and the reason for this refactoring) there's now  
> an easy way to define roles:
>   class NiceRole(grok.Role):
>       grok.name('grok.NiceRole')
>       grok.title('Title for Role') # optional
>       # multiple permissions ids allowed here
>       grok.permissions('grok.NicePermission', ...)
> Writing this post reminds me of updating CHANGES.txt - I will do so  
> rightaway...
> kind regards,
> jw
> _______________________________________________
> Grok-dev mailing list
> Grok-dev at zope.org
> http://mail.zope.org/mailman/listinfo/grok-dev

More information about the Grok-dev mailing list