[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