Back to index

plone3  3.1.7
RegistrationTool.py
Go to the documentation of this file.
00001 ##############################################################################
00002 #
00003 # Copyright (c) 2001 Zope Corporation and Contributors. All Rights Reserved.
00004 #
00005 # This software is subject to the provisions of the Zope Public License,
00006 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
00007 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
00008 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
00009 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
00010 # FOR A PARTICULAR PURPOSE.
00011 #
00012 ##############################################################################
00013 """ CMFDefault portal_registration tool.
00014 
00015 $Id: RegistrationTool.py 77182 2007-06-28 17:25:27Z yuppie $
00016 """
00017 
00018 from warnings import warn
00019 
00020 from AccessControl import ClassSecurityInfo
00021 from AccessControl.requestmethod import postonly
00022 from Acquisition import aq_base
00023 from Globals import InitializeClass
00024 from Products.MailHost.interfaces import IMailHost
00025 from zope.component import getUtility
00026 from zope.schema import ValidationError
00027 
00028 from Products.CMFCore.interfaces import IRegistrationTool
00029 from Products.CMFCore.RegistrationTool import RegistrationTool as BaseTool
00030 from Products.CMFCore.utils import _checkPermission
00031 from Products.CMFCore.utils import getToolByName
00032 
00033 from permissions import ManagePortal
00034 from utils import checkEmailAddress
00035 from utils import Message as _
00036 
00037 
00038 class RegistrationTool(BaseTool):
00039 
00040     """ Manage through-the-web signup policies.
00041     """
00042 
00043     __implements__ = BaseTool.__implements__
00044 
00045     meta_type = 'Default Registration Tool'
00046 
00047     security = ClassSecurityInfo()
00048 
00049     def _getValidEmailAddress(self, member):
00050         email = member.getProperty('email')
00051 
00052         # assert that we can actually get an email address, otherwise
00053         # the template will be made with a blank To:, this is bad
00054         if email is None:
00055             msg = _(u'No email address is registered for member: '
00056                     u'${member_id}', mapping={'member_id': member.getId()})
00057             raise ValueError(msg)
00058 
00059         checkEmailAddress(email)
00060         return email
00061 
00062     #
00063     #   'portal_registration' interface
00064     #
00065     security.declarePublic( 'testPasswordValidity' )
00066     def testPasswordValidity(self, password, confirm=None):
00067 
00068         """ Verify that the password satisfies the portal's requirements.
00069 
00070         o If the password is valid, return None.
00071         o If not, return a string explaining why.
00072         """
00073         if not password:
00074             return _(u'You must enter a password.')
00075 
00076         if len(password) < 5 and not _checkPermission(ManagePortal, self):
00077             return _(u'Your password must contain at least 5 characters.')
00078 
00079         if confirm is not None and confirm != password:
00080             return _(u'Your password and confirmation did not match. '
00081                      u'Please try again.')
00082 
00083         return None
00084 
00085     security.declarePublic( 'testPropertiesValidity' )
00086     def testPropertiesValidity(self, props, member=None):
00087 
00088         """ Verify that the properties supplied satisfy portal's requirements.
00089 
00090         o If the properties are valid, return None.
00091         o If not, return a string explaining why.
00092         """
00093         if member is None: # New member.
00094 
00095             username = props.get('username', '')
00096             if not username:
00097                 return _(u'You must enter a valid name.')
00098 
00099             if not self.isMemberIdAllowed(username):
00100                 return _(u'The login name you selected is already in use or '
00101                          u'is not valid. Please choose another.')
00102 
00103             email = props.get('email')
00104             if email is None:
00105                 return _(u'You must enter an email address.')
00106 
00107             try:
00108                 checkEmailAddress(email)
00109             except ValidationError:
00110                 return _(u'You must enter a valid email address.')
00111 
00112         else: # Existing member.
00113             email = props.get('email')
00114 
00115             if email is not None:
00116                 try:
00117                     checkEmailAddress(email)
00118                 except ValidationError:
00119                     return _(u'You must enter a valid email address.')
00120 
00121             # Not allowed to clear an existing non-empty email.
00122             existing = member.getProperty('email')
00123 
00124             if existing and email == '':
00125                 return _(u'You must enter a valid email address.')
00126 
00127         return None
00128 
00129     security.declarePublic( 'mailPassword' )
00130     def mailPassword(self, forgotten_userid, REQUEST):
00131         """ Email a forgotten password to a member.
00132 
00133         o Raise an exception if user ID is not found.
00134         """
00135         # XXX: this method violates the rules for tools/utilities:
00136         # it depends on a non-utility tool
00137         membership = getToolByName(self, 'portal_membership')
00138         member = membership.getMemberById(forgotten_userid)
00139 
00140         if member is None:
00141             raise ValueError(_(u'The username you entered could not be '
00142                                u'found.'))
00143 
00144         email = self._getValidEmailAddress(member)
00145 
00146         # Rather than have the template try to use the mailhost, we will
00147         # render the message ourselves and send it from here (where we
00148         # don't need to worry about 'UseMailHost' permissions).
00149         method = self.password_email
00150         kw = {'member': member, 'password': member.getPassword()}
00151 
00152         if getattr(aq_base(method), 'isDocTemp', 0):
00153             mail_text = method(self, REQUEST, **kw)
00154         else:
00155             mail_text = method(**kw)
00156 
00157         host = getUtility(IMailHost)
00158         host.send( mail_text )
00159 
00160         return self.mail_password_response( self, REQUEST )
00161 
00162     security.declarePublic( 'registeredNotify' )
00163     def registeredNotify(self, new_member_id, password=None, REQUEST=None):
00164         """ Handle mailing the registration / welcome message.
00165         """
00166         # XXX: this method violates the rules for tools/utilities:
00167         # it depends on a non-utility tool and uses self.REQUEST
00168         if REQUEST is None:
00169             REQUEST = self.REQUEST
00170             warn("registeredNotify should be called with 'REQUEST' as third "
00171                  "argument. The BBB code will be removed in CMF 2.3.",
00172                  DeprecationWarning, stacklevel=2)
00173 
00174         membership = getToolByName( self, 'portal_membership' )
00175         member = membership.getMemberById( new_member_id )
00176 
00177         if member is None:
00178             raise ValueError(_(u'The username you entered could not be '
00179                                u'found.'))
00180 
00181         if password is None:
00182             password = member.getPassword()
00183 
00184         email = self._getValidEmailAddress(member)
00185 
00186         # Rather than have the template try to use the mailhost, we will
00187         # render the message ourselves and send it from here (where we
00188         # don't need to worry about 'UseMailHost' permissions).
00189         method = self.registered_email
00190         kw = {'member': member, 'password': password, 'email': email}
00191 
00192         if getattr(aq_base(method), 'isDocTemp', 0):
00193             mail_text = method(self, REQUEST, **kw)
00194         else:
00195             mail_text = method(**kw)
00196 
00197         host = getUtility(IMailHost)
00198         host.send( mail_text )
00199 
00200     security.declareProtected(ManagePortal, 'editMember')
00201     @postonly
00202     def editMember(self, member_id, properties=None, password=None,
00203                    roles=None, domains=None, REQUEST=None):
00204         """ Edit a user's properties and security settings
00205 
00206         o Checks should be done before this method is called using
00207           testPropertiesValidity and testPasswordValidity
00208         """
00209         # XXX: this method violates the rules for tools/utilities:
00210         # it depends on a non-utility tool
00211         mtool = getToolByName(self, 'portal_membership')
00212         member = mtool.getMemberById(member_id)
00213         member.setMemberProperties(properties)
00214         member.setSecurityProfile(password,roles,domains)
00215 
00216         return member
00217 
00218 InitializeClass(RegistrationTool)