import re import grok from grok import index from zope.interface import Interface from zope import schema from z3c.widget.tiny.widget import TinyWidget from zope.app.authentication import PluggableAuthentication from zope.app.authentication.principalfolder import PrincipalFolder from zope.app.authentication.principalfolder import InternalPrincipal from zope.app.authentication.principalfolder import IInternalPrincipal from zope.app.authentication.interfaces import IPasswordManager from zope.app.authentication.session import SessionCredentialsPlugin from zope.app.security.interfaces import IAuthentication from zope.app.security.interfaces import IUnauthenticatedPrincipal from zope.securitypolicy.interfaces import IPrincipalRoleManager from zope.securitypolicy.interfaces import IRole from zope.securitypolicy.interfaces import IRolePermissionManager from zope.securitypolicy.role import LocalRole from zope.i18n import MessageFactory from zope.component import provideAdapter from zope.component import getUtility from zope.interface import implements from zope.component import adapts from zope.component import getUtility from zope.component import getUtilitiesFor from zope.annotation.interfaces import IAnnotations from persistent.dict import PersistentDict from zope.i18n import MessageFactory import appconfig from zope import component expr = re.compile(r"^(w&.%#$&'*+-/=?^_`{}|~]+!)*[w&.%#$&'*+-/=?^_`{}|~]+" r"@(([0-9a-z]([0-9a-z-]*[0-9a-z])?.)+[a-z]{2,6}|([0-9]{1,3}" r".){3}[0-9]{1,3})$", re.IGNORECASE) check_email = expr.match ############################################################################## ### I N T E R F A C E S ###################################################### ############################################################################## _ = MessageFactory('tpi') ################################################## email validation class NotAnEmailAddress(schema.ValidationError): __doc__ = _(u"Invalid email address") check_email = re.compile(r"[a-zA-Z0-9._%-]+@([a-zA-Z0-9-]+.)*[a-zA-Z]{2,4}").match def valid_email(value): if check_email(value): return True raise NotAnEmailAddress(value) ################################################## interfaces class IUser(Interface): """Basic user data.""" login = schema.TextLine(title=_(u"Login"), required=True) password = schema.Password(title=_(u"Password"), required=True) password_repeat = schema.Password(title=_(u"Password repeat"), required=True) fname = schema.TextLine(title=_(u"First name"), required=False) lname = schema.TextLine(title=_(u"Last name"), required=False) email = schema.ASCIILine(title=_(u"E-mail"), required=False, constraint=valid_email) ### H E L P E R S C R I P T S ############################################# def setup_pau(pau): pau['principals'] = PrincipalFolder('tpi.principals.') pau.authenticatorPlugins = ('principals',) pau['session'] = session = SessionCredentialsPlugin() session.loginpagename = 'login' pau.credentialsPlugins = ('No Challenge if Authenticated', 'session',) def role_factory(*args): def factory(): return LocalRole(*args) return factory ############################################################################## ### A P P L I C A T I O N #################################################### ############################################################################## class Tpi(grok.Application, grok.Container): def __init__(self): super(Tpi, self).__init__() ### U T I L I T I E S ################################################### # register authentication utility grok.local_utility(PluggableAuthentication, IAuthentication, setup=setup_pau) # register Admin Role grok.local_utility(role_factory(u'TPI Administrator'), IRole, name='tpi.Admin', name_in_container='tpi.Admin') # register Employee Role grok.local_utility(role_factory(u'TPI Employees'), IRole, name='tpi.Employee', name_in_container='tpi.Employees') # register Employee Role grok.local_utility(role_factory(u'TPI Member'), IRole, name='tpi.Member', name_in_container='tpi.Member') ### S U B S C R I B E R S #################################################### @grok.subscribe(Tpi, grok.IObjectAddedEvent) def grant_permissions(app, event): role_manager = IRolePermissionManager(app) # Admin Permissions role_manager.grantPermissionToRole('tpi.ViewClients', 'tpi.Employees') role_manager.grantPermissionToRole('tpi.AddClient', 'tpi.Employees') role_manager.grantPermissionToRole('tpi.DeleteClient', 'tpi.Admin') role_manager.grantPermissionToRole('tpi.ViewMemberListing', 'tpi.Admin') # Employee Permissions role_manager.grantPermissionToRole('tpi.ViewClients', 'tpi.Employees') role_manager.grantPermissionToRole('tpi.AddClient', 'tpi.Employees') class GlobalMacros(grok.View): grok.context(Interface) grok.name('globalmacros') class Index(grok.View): grok.context(Tpi) grok.name('index') def navLIST(self, name): if name not in appconfig.menuitems.keys(): pass else: return appconfig.menuitems[name] ############################################################################## ### A U T H E N T I C A T I O N ############################################## ############################################################################## class Register(grok.Form): form_fields = grok.AutoFields(IUser) label = u'User registration' template = grok.PageTemplateFile('form.pt') @grok.action('Sign up') def save(self, login, password, password_repeat, fname, lname, email): # TODO: validate password is equal to password_repeat # add principal to principal folder pau = component.getUtility(IAuthentication) principals = pau['principals'] assert(login not in principals) name = fname + ' ' + lname principals[login] = user = InternalPrincipal(login, password, name) # save the email to an IUser instance user.email = email # grant principal the role role_manager = IPrincipalRoleManager(self.context) role_manager.assignRoleToPrincipal('tpi.Employee', principals.prefix + login) self.redirect('index') class MemberListing(grok.Adapter): grok.implements(IUser) grok.template('form.pt') def fieldNames(self): return (f for f in IUser) def members(self): pau = component.getUtility(IAuthentication) principals = pau['principals'] roster = [ ] for id in sorted(principals.keys()): print id print principals[id] user = IUser(principals[id]) # <----- this is where the code is breaking fields = {} for field in IUser: fields[field] = getattr(user, field) roster.append(fields) return roster