예제 #1
0
    def validate(self, email):
        """Validate an email address.

        :param address: An email address.
        :type address: string
        :raise InvalidEmailAddressError: when the address is deemed invalid.
        """
        if not self.is_valid(email):
            raise InvalidEmailAddressError(email)
예제 #2
0
 def _step_sanity_checks(self):
     # Ensure that we have both an address and a user, even if the address
     # is not verified.  We can't set the preferred address until it is
     # verified.
     if self.user is None:
         # The address has no linked user so create one, link it, and set
         # the user's preferred address.
         assert self.address is not None, 'No address or user'
         self.user = getUtility(IUserManager).make_user(self.address.email)
     if self.address is None:
         assert self.user.preferred_address is None, (
             "Preferred address exists, but wasn't used in constructor")
         addresses = list(self.user.addresses)
         if len(addresses) == 0:
             raise AssertionError('User has no addresses: {}'.format(
                 self.user))
         # This is rather arbitrary, but we have no choice.
         self.address = addresses[0]
     assert self.user is not None and self.address is not None, (
         'Insane sanity check results')
     # Is this subscriber already a member?
     if (self.which is WhichSubscriber.user
             and self.user.preferred_address is not None):
         subscriber = self.user
     else:
         subscriber = self.address
     if self.mlist.is_subscribed(subscriber):
         # 2017-04-22 BAW: This branch actually *does* get covered, as I've
         # verified by a full coverage run, but diffcov for some reason
         # claims that the test added in the branch that added this code
         # does not cover the change.  That seems like a bug in diffcov.
         raise AlreadySubscribedError(  # pragma: nocover
             self.mlist.fqdn_listname, self.address.email,
             MemberRole.member)
     # Is this email address banned?
     if IBanManager(self.mlist).is_banned(self.address.email):
         raise MembershipIsBannedError(self.mlist, self.address.email)
     # Don't allow the list posting address.
     if self.address.email.lower() == self.mlist.posting_address:
         raise InvalidEmailAddressError('List posting address not allowed')
     # Check if there is already a subscription request for this email.
     pendings = getUtility(IPendings).find(mlist=self.mlist,
                                           pend_type='subscription')
     for token, pendable in pendings:
         if pendable['email'] == self.address.email:
             raise SubscriptionPendingError(self.mlist, self.address.email)
     # Start out with the subscriber being the token owner.
     self.push('verification_checks')
예제 #3
0
 def create(self, store, fqdn_listname):
     """See `IListManager`."""
     fqdn_listname = fqdn_listname.lower()
     listname, at, hostname = fqdn_listname.partition('@')
     if len(hostname) == 0:
         raise InvalidEmailAddressError(fqdn_listname)
     list_id = '{}.{}'.format(listname, hostname)
     notify(ListCreatingEvent(fqdn_listname))
     mlist = store.query(MailingList).filter_by(_list_id=list_id).first()
     if mlist:
         raise ListAlreadyExistsError(fqdn_listname)
     mlist = MailingList(fqdn_listname)
     mlist.created_at = now()
     store.add(mlist)
     notify(ListCreatedEvent(mlist))
     return mlist
 def subscribe(self, store, subscriber, role=MemberRole.member,
               send_welcome_message=None):
     """See `IMailingList`."""
     member, email = self._get_subscriber(store, subscriber, role)
     test_email = email or subscriber.lower()
     # Allow list posting address only for nonmember role.
     if (test_email == self.posting_address and
             role != MemberRole.nonmember):
         raise InvalidEmailAddressError('List posting address not allowed')
     if member is not None:
         raise AlreadySubscribedError(self.fqdn_listname, email, role)
     if IBanManager(self).is_banned(test_email):
         raise MembershipIsBannedError(self, test_email)
     member = Member(role=role,
                     list_id=self._list_id,
                     subscriber=subscriber)
     member.preferences = Preferences()
     store.add(member)
     notify(SubscriptionEvent(
         self, member, send_welcome_message=send_welcome_message))
     return member
def add_member(mlist, record, role=MemberRole.member):
    """Add a member right now.

    The member's subscription must be approved by whatever policy the list
    enforces.

    :param mlist: The mailing list to add the member to.
    :type mlist: `IMailingList`
    :param record: a subscription request record.
    :type record: RequestRecord
    :param role: The membership role for this subscription.
    :type role: `MemberRole`
    :return: The just created member.
    :rtype: `IMember`
    :raises AlreadySubscribedError: if the user is already subscribed to
        the mailing list.
    :raises InvalidEmailAddressError: if the email address is not valid or
        is the list posting address.
    :raises MembershipIsBannedError: if the membership is not allowed.
    """
    # Check to see if the email address is banned.
    if IBanManager(mlist).is_banned(record.email):
        raise MembershipIsBannedError(mlist, record.email)
    # Check for list posting address, but allow for nonmember.
    if (record.email.lower() == mlist.posting_address
            and role != MemberRole.nonmember):
        raise InvalidEmailAddressError('List posting address not allowed')
    # Make sure there is a user linked with the given address.
    user_manager = getUtility(IUserManager)
    user = user_manager.make_user(record.email, record.display_name)
    user.preferences.preferred_language = record.language
    # Subscribe the address, not the user.
    # We're looking for two versions of the email address, the case
    # preserved version and the case insensitive version.   We'll
    # subscribe the version with matching case if it exists, otherwise
    # we'll use one of the matching case-insensitively ones.  It's
    # undefined which one we pick.
    case_preserved = None
    case_insensitive = None
    for address in user.addresses:
        if address.original_email == record.email:
            case_preserved = address
        if address.email == record.email.lower():  # pragma: no branch
            case_insensitive = address
    assert case_preserved is not None or case_insensitive is not None, (
        'Could not find a linked address for: {}'.format(record.email))
    address = (case_preserved
               if case_preserved is not None else case_insensitive)
    # Create the member and set the appropriate preferences.  It's
    # possible we're subscribing the lower cased version of the address;
    # if that's already subscribed re-issue the exception with the correct
    # email address (i.e. the one passed in here).
    try:
        member = mlist.subscribe(address, role)
    except AlreadySubscribedError as error:
        raise AlreadySubscribedError(error.fqdn_listname, record.email,
                                     error.role)
    member.preferences.preferred_language = record.language
    member.preferences.delivery_mode = record.delivery_mode
    # Check for and remove nonmember subscriptions of the user to this list.
    if role is MemberRole.member:
        for address in user.addresses:
            nonmember = mlist.nonmembers.get_member(address.email)
            if nonmember is not None:
                nonmember.unsubscribe()
    return member