[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
july.
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
===========================
Introduction
-------------
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
hand,
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.
Setup
-----
::
#contact.py
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):
interface.implements(IContactInfo)
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
view,
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
grok.define_permission('mysite.ViewContacts')
grok.define_permission('mysite.AddContacts')
grok.define_permission('mysite.EditContact')
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
declaration
def render(self):
contact = self.context
return 'Contact: ' + contact.first_name +
contact.last_name +
contact.email
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
IPrincipalPermissionManager
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,
realname)
# 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
set)
permission_man.grantPermissionToPrincipal
('mysite.ViewContacts',
principals.prefix +
username)
permission_man.grantPermissionToPrincipal('mysite.AddContacts',
principals.prefix +
username)
Permissions are set for the context for which the PermissionManager is
created, and --if not explicitly overridden-- all it's children. The
above
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
have
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
anonymous/
# unauthenticated users-- could add Contacts to the site
grok.require('mysite.AddContacts')
form_fields = grok.AutoFields(IContactInfo) #automagically
generate
form fields
@grok.action('Create')
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)
permission_man.grantPermissionToPrincipal
('mysite.EditContacts',
self.request.principal.id)
self.redirect(self.url(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)
self.redirect(self.url(self.context))
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
IPrincipalRoleManager
from zope.app.securitypolicy.interfaces import
IRolePermissionManager
[FIXME: Roles have to be first defined / registered as a local
Utility????]
[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
::
role_man.grantPermissionToRole('mysite.ViewContacts',
'mysite.Member')
role_man.grantPermissionToRole('mysite.AddContacts',
'mysite.Member')
role_man.grantPermissionToRole('mysite.ViewContacts',
'mysite.Administrator')
role_man.grantPermissionToRole('mysite.AddContacts',
'mysite.Administrator')
role_man.grantPermissionToRole('mysite.EditContacts',
'mysite.Administrator')
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