from zope.i18nmessageid import MessageFactory _ = MessageFactory('krihvel') from zope.component import getUtility from zope.publisher.browser import BrowserView from zope.exceptions.interfaces import UserError from zope.security.proxy import removeSecurityProxy from zope.app.pagetemplate import ViewPageTemplateFile from zope.app.security.interfaces import IAuthentication from zope.app.authentication.interfaces import IPluggableAuthentication from zope.app.securitypolicy.interfaces import IPrincipalRoleManager from krihvel.signup import ISignup import re from krihvel.MembersFolder import MemberFolder from krihvel.interfaces import IMembersFolder from zope.app.component.hooks import getSite from zope.component import createObject from zope.traversing.browser import absoluteURL # XXX Allowed patter for login and password. Might want to put that to some general place and import, in case it will be needed elswhere. default_allowed_pattern = "^[A-Za-z][A-Za-z0-9_]*$" _ALLOWED_PATTERN = re.compile(default_allowed_pattern) class BaseSignUpView(BrowserView): def _signupfolder(self): pau = getUtility(IAuthentication) if not IPluggableAuthentication.providedBy(pau): raise LookupError("Signup requires a PAU instance.") for name, plugin in pau.getAuthenticatorPlugins(): if ISignup.providedBy(plugin): return plugin raise TypeError("Signup requires a sign-up capable athenticator " "plugin.") class SignUpView(BaseSignUpView): signUpForm = ViewPageTemplateFile('signup.pt') def signUp(self, login, title, password, confirmation): if not login: raise UserError(_(u"Please provide a valid username.")) if not title: raise UserError(_(u"Please provide a valid fullname.")) if not password or not confirmation: raise UserError(_(u"Please provide a valid password and confirmation.")) if not _ALLOWED_PATTERN.match(login): raise UserError(_(u"User name can not have any special characters.")) if not _ALLOWED_PATTERN.match(password): raise UserError(_(u"Password can not have any special characters.")) folder = self._signupfolder() if login in folder: raise UserError(_(u"This login has already been chosen.")) if confirmation != password: raise UserError(_(u"Password and confirmation didn't match")) principal_id = folder.signUp(login, password, title) role_manager = IPrincipalRoleManager(self.context) role_manager = removeSecurityProxy(role_manager) for role in folder.signup_roles: role_manager.assignRoleToPrincipal(role, principal_id) # Create a MemberFolder membersfolder = getUtility(IMembersFolder) membersfolder[login] = createObject(u"krihvel.MemberFolder") mfolder = membersfolder[login] self.request.response.redirect(absoluteURL(mfolder, self.request)) class PasswordView(BaseSignUpView): changePasswordForm = ViewPageTemplateFile('password.pt') def changePassword(self, title, password=None, confirmation=None): if confirmation != password: raise UserError(_(u"Password and confirmation didn't match")) folder = self._signupfolder() pau = getUtility(IAuthentication) info = folder.principalInfo(self.request.principal.id[len(pau.prefix):]) if info is None: raise UserError(_(u"Can only change the title and password " "of users who signed up.")) folder.changePasswordTitle(info.login, password, title) self.request.response.redirect(".")