diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mailman/app/lifecycle.py | 10 | ||||
| -rw-r--r-- | src/mailman/app/membership.py | 4 | ||||
| -rw-r--r-- | src/mailman/app/registrar.py | 4 | ||||
| -rw-r--r-- | src/mailman/config/configure.zcml | 11 | ||||
| -rw-r--r-- | src/mailman/email/validate.py | 60 | ||||
| -rw-r--r-- | src/mailman/interfaces/address.py | 23 |
6 files changed, 71 insertions, 41 deletions
diff --git a/src/mailman/app/lifecycle.py b/src/mailman/app/lifecycle.py index 39ec09aa7..b30266f3b 100644 --- a/src/mailman/app/lifecycle.py +++ b/src/mailman/app/lifecycle.py @@ -33,7 +33,7 @@ import logging from zope.component import getUtility from mailman.config import config -from mailman.email.validate import validate +from mailman.interfaces.address import IEmailValidator from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) from mailman.interfaces.listmanager import IListManager @@ -58,13 +58,15 @@ def create_list(fqdn_listname, owners=None): :type owners: list of string email addresses :return: The new mailing list. :rtype: `IMailingList` - :raises `BadDomainSpecificationError`: when the hostname part of + :raises BadDomainSpecificationError: when the hostname part of `fqdn_listname` does not exist. - :raises `ListAlreadyExistsError`: when the mailing list already exists. + :raises ListAlreadyExistsError: when the mailing list already exists. + :raises InvalidEmailAddressError: when the fqdn email address is invalid. """ if owners is None: owners = [] - validate(fqdn_listname) + # This raises I + getUtility(IEmailValidator).validate(fqdn_listname) # pylint: disable-msg=W0612 listname, domain = fqdn_listname.split('@', 1) if domain not in getUtility(IDomainManager): diff --git a/src/mailman/app/membership.py b/src/mailman/app/membership.py index 8ea8769a6..e8564bc60 100644 --- a/src/mailman/app/membership.py +++ b/src/mailman/app/membership.py @@ -33,7 +33,7 @@ from mailman import Utils from mailman.app.notifications import send_goodbye_message from mailman.core.i18n import _ from mailman.email.message import OwnerNotification -from mailman.email.validate import validate +from mailman.interfaces.address import IEmailValidator from mailman.interfaces.member import ( AlreadySubscribedError, MemberRole, MembershipIsBannedError, NotAMemberError) @@ -67,7 +67,7 @@ def add_member(mlist, email, realname, password, delivery_mode, language): :raises MembershipIsBannedError: if the membership is not allowed. """ # Let's be extra cautious. - validate(email) + getUtility(IEmailValidator).validate(email) if mlist.members.get_member(email) is not None: raise AlreadySubscribedError( mlist.fqdn_listname, email, MemberRole.member) diff --git a/src/mailman/app/registrar.py b/src/mailman/app/registrar.py index 181d48126..ec899237a 100644 --- a/src/mailman/app/registrar.py +++ b/src/mailman/app/registrar.py @@ -33,7 +33,7 @@ from zope.interface import implements from mailman.core.i18n import _ from mailman.email.message import UserNotification -from mailman.email.validate import validate +from mailman.interfaces.address import IEmailValidator from mailman.interfaces.listmanager import IListManager from mailman.interfaces.member import MemberRole from mailman.interfaces.pending import IPendable, IPendings @@ -57,7 +57,7 @@ class Registrar: """See `IUserRegistrar`.""" # First, do validation on the email address. If the address is # invalid, it will raise an exception, otherwise it just returns. - validate(email) + getUtility(IEmailValidator).validate(email) # Create a pendable for the registration. pendable = PendableRegistration( type=PendableRegistration.PEND_KEY, diff --git a/src/mailman/config/configure.zcml b/src/mailman/config/configure.zcml index a7d12e7a2..bf42d6635 100644 --- a/src/mailman/config/configure.zcml +++ b/src/mailman/config/configure.zcml @@ -6,14 +6,14 @@ <adapter for="mailman.interfaces.mailinglist.IMailingList" - provides="mailman.interfaces.autorespond.IAutoResponseSet" factory="mailman.model.autorespond.AutoResponseSet" + provides="mailman.interfaces.autorespond.IAutoResponseSet" /> <adapter for="mailman.interfaces.mailinglist.IMailingList" - provides="mailman.interfaces.mailinglist.IAcceptableAliasSet" factory="mailman.model.mailinglist.AcceptableAliasSet" + provides="mailman.interfaces.mailinglist.IAcceptableAliasSet" /> <utility @@ -52,8 +52,8 @@ /> <utility - provides="mailman.interfaces.registrar.IRegistrar" factory="mailman.app.registrar.Registrar" + provides="mailman.interfaces.registrar.IRegistrar" /> <utility @@ -61,4 +61,9 @@ provides="mailman.interfaces.membership.ISubscriptionService" /> + <utility + factory="mailman.email.validate.Validator" + provides="mailman.interfaces.address.IEmailValidator" + /> + </configure> diff --git a/src/mailman/email/validate.py b/src/mailman/email/validate.py index 4eb13eee8..0c4c6a5e0 100644 --- a/src/mailman/email/validate.py +++ b/src/mailman/email/validate.py @@ -21,15 +21,18 @@ from __future__ import absolute_import, unicode_literals __metaclass__ = type __all__ = [ - 'is_valid', - 'validate', + 'Validator', ] import re +from zope.interface import implements + + from mailman.email.utils import split_email -from mailman.interfaces.address import InvalidEmailAddressError +from mailman.interfaces.address import ( + IEmailValidator, InvalidEmailAddressError) # What other characters should be disallowed? @@ -37,34 +40,31 @@ _badchars = re.compile(r'[][()<>|;^,\000-\037\177-\377]') -def validate(address): - """Validate an email address. +class Validator: + """An email address validator.""" - :param address: An email address. - :type address: string - :raise InvalidEmailAddressError: when the address is deemed invalid. - """ - if not is_valid(address): - raise InvalidEmailAddressError(repr(address)) + implements(IEmailValidator) + def is_valid(self, email): + """See `IEmailValidator`.""" + if not email or ' ' in email: + return False + if _badchars.search(email) or email[0] == '-': + return False + user, domain_parts = split_email(email) + # Local, unqualified addresses are not allowed. + if not domain_parts: + return False + if len(domain_parts) < 2: + return False + return True - -def is_valid(address): - """Check if an email address if valid. + def validate(self, email): + """Validate an email address. - :param address: An email address. - :type address: string - :return: A flag indicating whether the email address is okay or not. - :rtype: bool - """ - if not address or ' ' in address: - return False - if _badchars.search(address) or address[0] == '-': - return False - user, domain_parts = split_email(address) - # Local, unqualified addresses are not allowed. - if not domain_parts: - return False - if len(domain_parts) < 2: - return False - return True + :param address: An email address. + :type address: string + :raise InvalidEmailAddressError: when the address is deemed invalid. + """ + if not self.is_valid(email): + raise InvalidEmailAddressError(repr(email)) diff --git a/src/mailman/interfaces/address.py b/src/mailman/interfaces/address.py index 446bae3f3..391eae849 100644 --- a/src/mailman/interfaces/address.py +++ b/src/mailman/interfaces/address.py @@ -26,6 +26,7 @@ __all__ = [ 'AddressNotLinkedError', 'ExistingAddressError', 'IAddress', + 'IEmailValidator', 'InvalidEmailAddressError', ] @@ -104,3 +105,25 @@ class IAddress(Interface): preferences = Attribute( """This address's preferences.""") + + + +class IEmailValidator(Interface): + """An email validator.""" + + def is_valid(email): + """Check if an email address if valid. + + :param email: A text email address. + :type email: str + :return: A flag indicating whether the email address is okay or not. + :rtype: bool + """ + + def validate(email): + """Validate an email address. + + :param email: A text email address. + :type email: str + :raise InvalidEmailAddressError: when `email` is deemed invalid. + """ |
