def mailPassword(self, forgotten_userid, REQUEST): """ Wrapper around mailPassword """ membership = getToolByName(self, 'portal_membership') if not membership.checkPermission('Mail forgotten password', self): raise Unauthorized("Mailing forgotten passwords has been disabled") utils = getToolByName(self, 'plone_utils') # XXX Here is the change compared to the default method. Try # to find this user via the login name. In fact, we REFUSE to # find a user by id, as in that case the password reset may # work, but we could fail to login. Especially this is the # case when the user has registered with [email protected], # changed this to [email protected] and now tries to reset the # password for [email protected]. member = email_utils.getMemberByLoginName(self, forgotten_userid, allow_userid=False) if member is None: raise ValueError('The username you entered could not be found') # We use the id member as new forgotten_userid, as in our # patched version of resetPassword we ask for the real member # id too, instead of the login name. forgotten_userid = member.getId() # assert that we can actually get an email address, otherwise # the template will be made with a blank To:, this is bad email = member.getProperty('email') if not email: raise ValueError('That user does not have an email address.') else: # add the single email address if not utils.validateSingleEmailAddress(email): raise ValueError('The email address did not validate') check, msg = _checkEmail(email) if not check: raise ValueError(msg) # Rather than have the template try to use the mailhost, we will # render the message ourselves and send it from here (where we # don't need to worry about 'UseMailHost' permissions). reset_tool = getToolByName(self, 'portal_password_reset') reset = reset_tool.requestReset(forgotten_userid) email_charset = getattr(self, 'email_charset', 'UTF-8') mail_text = self.mail_password_template( self, REQUEST, member=member, reset=reset, password=member.getPassword(), charset=email_charset) if isinstance(mail_text, unicode): mail_text = mail_text.encode(email_charset) host = self.MailHost try: host.send(mail_text) return self.mail_password_response(self, REQUEST) except SMTPRecipientsRefused: # Don't disclose email address on failure raise SMTPRecipientsRefused('Recipient address rejected by server')
class TestEmailValidityChecker(unittest.TestCase): check = lambda _, email: _checkEmail(email) def test_generic_tld(self): result = self.check("*****@*****.**") self.assertTrue(*result) def test_normal_cc_tld(self): result = self.check("*****@*****.**") self.assertTrue(*result) def test_idn_cc_tld(self): result = self.check(u"[email protected]") self.assertTrue(*result) def test_long_tld(self): result = self.check(u"*****@*****.**") self.assertTrue(*result)