[Grok-dev] Re: Re: Local permissions?

Sebastian Ware sebastian at urbantalk.se
Fri Jul 6 04:52:35 EDT 2007


Fantastic! Great job! I haven't tried it, but you have made it look  
easy! :)

Some comments inline.

Mvh Sebastian


5 jul 2007 kl. 01.45 skrev Luis De la Parra:

> ===========================
> 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, Grok allows access to everythig  
> unless you
> explicitly restrict it.
>
> [FIXME: is this really correct??? if yes, do we really need to  
> explain it to
> newbies ??]
> Another difference is that the standard-Zope3 performs  
> authorization checks
> for the content objects, Grok makes the checks on the Views used to  
> access
> (display/manipulate) the objects.
> [FIXME]

This is good to know.

>
>
> 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
>

Excellent!

>
> 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 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
>
>

Excellent!

>
> 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 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  
> ViewContents and
> #       EditContacts
> #       this assumes you are using a Pluggable Authentication  
> Utility /
> PrincipalFolder

Is this the default setup? Or do I have to add the PAU?

>         pau = component.getUtility(IAuthentication)
>         principals = pau['principals']
>         principals[user] = InternalPrincipal(username, password,  
> realname)

What is user? Where did it come from?

>
> #       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.

Excellent!

>
> 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

Excellent!

>
> ::
>
>     class AddContact(grok.AddForm):
>         grok.require('mysite.AddContacts')  #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
>
>         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)
>

Excellent!!!

>
>             self.redirect(self.url(contact)) #display the newly  
> created
> contact
>
>
>
>     class EditContact(grok.EditForm):
>         grok.require('mysite.EditContacts') #only users with
> permission 'mysite.EditContacts' can use this
>
>         form_fields = grok.AutoFields(IContactInfo) #automagically  
> generate
> form fields
>
>         @grok.action('Save Changes')
>         def edit(self, **data):
>             self.applyData(self.context, **data)
>             self.redirect(self.url(self.context))
>

How do I check permissions in a page template and in python code when  
generating the UI? I don't want to add an edit button if the user  
can't edit the content.

>
>
> Learning More
> --------------
> Permissions can be grouped together in Roles, which makes granting  
> all the
> permissions a particular type of user might need much easier.

I think this should be in a section "Defining roles". "Learning More"  
would be great if there were some links to more documentation and  
hints on which components to examine.

>
> ::
>     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????]
>     role_manager = IRolePermissionManager( grok.getSite() )
>
> #   group all permissions in two roles: one for normal site  
> members, and one
> for admins
>
> role_manager.grantPermissionToRole('mysite.ViewContacts',  
> 'mysite.Member')
>
> role_manager.grantPermissionToRole('mysite.AddContacts',   
> 'mysite.Member')
>
>
> role_manager.grantPermissionToRole('mysite.ViewContacts',  
> 'mysite.Administrator')
>
> role_manager.grantPermissionToRole('mysite.AddContacts',   
> 'mysite.Administrator')
>
> role_manager.grantPermissionToRole('mysite.EditContacts',  
> 'mysite.Administrator')
>
> #   If the context here is the Site/Application, users with the
> Administrator role can
> #   edit all ContactInfos, regardless who the creator is
>     role_manager = IPrincipalRoleManager(context)
>     role_manager.assignRoleToPrincipal('mysite.Administrator',  
> principalID)
>



More information about the Grok-dev mailing list