Exemplo n.º 1
0
 def test_delete_nonmembers_on_adding_member(self):
     # GL: #237 - When a new address is subscribed, any existing nonmember
     # subscriptions for this address; or any addresses also controlled by
     # this user, are deleted.
     anne_nonmember = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.nonmember)
     # Add a few other validated addresses to this user, and subscribe them
     # as nonmembers.
     for email in ('*****@*****.**', '*****@*****.**'):
         address = anne_nonmember.user.register(email)
         address.verified_on = now()
         self._mlist.subscribe(address, MemberRole.nonmember)
     # There are now three nonmembers.
     self.assertEqual(
         {address.email for address in self._mlist.nonmembers.addresses},
         {'*****@*****.**',
          '*****@*****.**',
          '*****@*****.**',
          })
     # Let's now add one of Anne's addresses as a member.  This deletes all
     # of Anne's nonmember memberships.
     anne_member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.member)
     self.assertEqual(self._mlist.nonmembers.member_count, 0)
     members = list(self._mlist.members.members)
     self.assertEqual(len(members), 1)
     self.assertEqual(members[0], anne_member)
Exemplo n.º 2
0
 def test_add_member_with_mixed_case_email(self):
     # LP: #1425359 - Mailman is case-perserving, case-insensitive.  This
     # test subscribes the lower case address and ensures the original
     # mixed case address can't be subscribed.
     email = '*****@*****.**'
     add_member(
         self._mlist,
         RequestRecord(email.lower(), 'Ann Person', DeliveryMode.regular,
                       system_preferences.preferred_language))
     with self.assertRaises(AlreadySubscribedError) as cm:
         add_member(
             self._mlist,
             RequestRecord(email, 'Ann Person', DeliveryMode.regular,
                           system_preferences.preferred_language))
     self.assertEqual(cm.exception.email, email)
Exemplo n.º 3
0
    def test_action_munge_from_display_name_in_list(self):
        self._mlist.dmarc_mitigate_action = DMARCMitigateAction.munge_from
        add_member(self._mlist, RequestRecord('*****@*****.**',
                                              'Anna Banana'))
        msgdata = {'dmarc': True}
        msg = mfs(self._text)
        dmarc.process(self._mlist, msg, msgdata)
        self.assertMultiLineEqual(
            msg.as_string(), """\
To: [email protected]
Subject: A subject
X-Mailman-Version: X.Y
Message-ID: <*****@*****.**>
Date: Fri, 1 Jan 2016 00:00:01 +0000
Another-Header: To test removal in wrapper
MIME-Version: 1.0
Content-Type: multipart/alternative; boundary="=====abc=="
From: Anna Banana via Ant <*****@*****.**>
Reply-To: [email protected]

--=====abc==
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: 7bit

Some things to say.
--=====abc==
Content-Type: text/html; charset="us-ascii"
Content-Transfer-Encoding: 7bit

<html><head></head><body>Some things to say.</body></html>
--=====abc==--
""")
Exemplo n.º 4
0
    def add_members(self, mlist, args):
        """Add the members in a file to a mailing list.

        :param mlist: The mailing list to operate on.
        :type mlist: `IMailingList`
        :param args: The command line arguments.
        :type args: `argparse.Namespace`
        """
        with ExitStack() as resources:
            if args.input_filename == '-':
                fp = sys.stdin
            else:
                fp = resources.enter_context(
                    open(args.input_filename, 'r', encoding='utf-8'))
            for line in fp:
                # Ignore blank lines and lines that start with a '#'.
                if line.startswith('#') or len(line.strip()) == 0:
                    continue
                # Parse the line and ensure that the values are unicodes.
                display_name, email = parseaddr(line)
                try:
                    add_member(mlist,
                               RequestRecord(email, display_name,
                                             DeliveryMode.regular,
                                             mlist.preferred_language.code))
                except AlreadySubscribedError:
                    # It's okay if the address is already subscribed, just
                    # print a warning and continue.
                    if not display_name:
                        print(_('Already subscribed (skipping): $email'))
                    else:
                        print(_('Already subscribed (skipping): '
                                '$display_name <$email>'))
Exemplo n.º 5
0
def add_members(mlist, add_infp):
    for line in add_infp:
        # Ignore blank lines and lines that start with a '#'.
        if line.startswith('#') or len(line.strip()) == 0:
            continue
        # Parse the line and ensure that the values are unicodes.
        display_name, email = parseaddr(line)
        if email == '':
            line = line.strip()
            print(_('Cannot parse as valid email address (skipping): $line'),
                  file=sys.stderr)
            continue
        try:
            add_member(
                mlist,
                RequestRecord(email, display_name, DeliveryMode.regular,
                              mlist.preferred_language.code))
        except InvalidEmailAddressError:  # pragma: nocover
            # There is a test for this, but it hits the if email == '' above.
            # It's okay if the address is invalid, we print a warning and
            # continue.
            line = line.strip()
            print(_('Cannot parse as valid email address (skipping): $line'),
                  file=sys.stderr)
        except AlreadySubscribedError:
            # It's okay if the address is already subscribed, just print a
            # warning and continue.
            if not display_name:
                print(_('Already subscribed (skipping): $email'),
                      file=sys.stderr)
            else:
                print(
                    _('Already subscribed (skipping): $display_name <$email>'),
                    file=sys.stderr)
Exemplo n.º 6
0
 def test_add_member_globally_banned_by_pattern(self):
     # Addresses matching global regexp ban patterns cannot subscribe.
     IBanManager(None).ban('^.*@example.com')
     self.assertRaises(
         MembershipIsBannedError, add_member, self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
Exemplo n.º 7
0
 def test_add_posting_address(self):
     # Test that we can't add the list posting address.
     self.assertRaises(
         InvalidEmailAddressError,
         add_member, self._mlist,
         RequestRecord(self._mlist.posting_address, 'The List',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
Exemplo n.º 8
0
 def test_add_member_globally_banned(self):
     # Test that members who are banned by specific address cannot
     # subscribe to the mailing list.
     IBanManager(None).ban('*****@*****.**')
     self.assertRaises(
         MembershipIsBannedError, add_member, self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
Exemplo n.º 9
0
 def test_add_member_twice(self):
     # Adding a member with the same role twice causes an
     # AlreadySubscribedError to be raised.
     add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.member)
     with self.assertRaises(AlreadySubscribedError) as cm:
         add_member(
             self._mlist,
             RequestRecord('*****@*****.**', 'Anne Person',
                           DeliveryMode.regular,
                           system_preferences.preferred_language),
             MemberRole.member)
     self.assertEqual(cm.exception.fqdn_listname, '*****@*****.**')
     self.assertEqual(cm.exception.email, '*****@*****.**')
     self.assertEqual(cm.exception.role, MemberRole.member)
Exemplo n.º 10
0
 def test_add_posting_address_nonmember(self):
     # Test that we can add the list posting address as a nonmember.
     request_record = RequestRecord(self._mlist.posting_address,
                                    'The List',
                                    DeliveryMode.regular,
                                    system_preferences.preferred_language)
     member = add_member(self._mlist, request_record, MemberRole.nonmember)
     self.assertEqual(member.address.email, self._mlist.posting_address)
     self.assertEqual(member.list_id, 'test.example.com')
     self.assertEqual(member.role, MemberRole.nonmember)
Exemplo n.º 11
0
 def test_add_member_banned_from_different_list_by_pattern(self):
     # Addresses matching regexp ban patterns on one list can still
     # subscribe to other mailing lists.
     sample_list = create_list('*****@*****.**')
     IBanManager(sample_list).ban('^.*@example.com')
     member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
     self.assertEqual(member.address.email, '*****@*****.**')
Exemplo n.º 12
0
 def test_add_member_with_different_roles(self):
     # Adding a member twice with different roles is okay.
     member_1 = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.member)
     member_2 = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.owner)
     self.assertEqual(member_1.list_id, member_2.list_id)
     self.assertEqual(member_1.address, member_2.address)
     self.assertEqual(member_1.user, member_2.user)
     self.assertNotEqual(member_1.member_id, member_2.member_id)
     self.assertEqual(member_1.role, MemberRole.member)
     self.assertEqual(member_2.role, MemberRole.owner)
Exemplo n.º 13
0
 def test_add_member_moderator(self):
     # Test adding a moderator to a mailing list.
     member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language),
         MemberRole.moderator)
     self.assertEqual(member.address.email, '*****@*****.**')
     self.assertEqual(member.list_id, 'test.example.com')
     self.assertEqual(member.role, MemberRole.moderator)
Exemplo n.º 14
0
 def test_add_member_banned_from_different_list(self):
     # Test that members who are banned by on a different list can still be
     # subscribed to other mlists.
     sample_list = create_list('*****@*****.**')
     IBanManager(sample_list).ban('*****@*****.**')
     member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
     self.assertEqual(member.address.email, '*****@*****.**')
Exemplo n.º 15
0
 def test_add_member_new_user(self):
     # Test subscribing a user to a mailing list when the email address has
     # not yet been associated with a user.
     member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
     self.assertEqual(member.address.email, '*****@*****.**')
     self.assertEqual(member.list_id, 'test.example.com')
     self.assertEqual(member.role, MemberRole.member)
Exemplo n.º 16
0
 def test_add_member_existing_user(self):
     # Test subscribing a user to a mailing list when the email address has
     # already been associated with a user.
     user_manager = getUtility(IUserManager)
     user_manager.create_user('*****@*****.**', 'Anne Person')
     member = add_member(
         self._mlist,
         RequestRecord('*****@*****.**', 'Anne Person',
                       DeliveryMode.regular,
                       system_preferences.preferred_language))
     self.assertEqual(member.address.email, '*****@*****.**')
     self.assertEqual(member.list_id, 'test.example.com')
Exemplo n.º 17
0
 def test_add_member_banned(self):
     # Test that members who are banned by specific address cannot
     # subscribe to the mailing list.
     IBanManager(self._mlist).ban('*****@*****.**')
     with self.assertRaises(MembershipIsBannedError) as cm:
         add_member(
             self._mlist,
             RequestRecord('*****@*****.**', 'Anne Person',
                           DeliveryMode.regular,
                           system_preferences.preferred_language))
     self.assertEqual(
         str(cm.exception),
         '[email protected] is not allowed to subscribe to [email protected]')
Exemplo n.º 18
0
def add_members(mlist, infp):
    for line in infp:
        # Ignore blank lines and lines that start with a '#'.
        if line.startswith('#') or len(line.strip()) == 0:
            continue
        # Parse the line and ensure that the values are unicodes.
        display_name, email = parseaddr(line)
        try:
            add_member(mlist,
                       RequestRecord(email, display_name,
                                     DeliveryMode.regular,
                                     mlist.preferred_language.code))
        except AlreadySubscribedError:
            # It's okay if the address is already subscribed, just print a
            # warning and continue.
            if not display_name:
                print(_('Already subscribed (skipping): $email'))
            else:
                print(_('Already subscribed (skipping): '
                        '$display_name <$email>'))
Exemplo n.º 19
0
 def on_post(self, request, response):
     """Create a new member."""
     try:
         validator = Validator(list_id=str,
                               subscriber=subscriber_validator(self.api),
                               display_name=str,
                               delivery_mode=enum_validator(DeliveryMode),
                               role=enum_validator(MemberRole),
                               pre_verified=bool,
                               pre_confirmed=bool,
                               pre_approved=bool,
                               _optional=('delivery_mode', 'display_name',
                                          'role', 'pre_verified',
                                          'pre_confirmed', 'pre_approved'))
         arguments = validator(request)
     except ValueError as error:
         bad_request(response, str(error))
         return
     # Dig the mailing list out of the arguments.
     list_id = arguments.pop('list_id')
     mlist = getUtility(IListManager).get_by_list_id(list_id)
     if mlist is None:
         bad_request(response, b'No such list')
         return
     # Figure out what kind of subscriber is being registered.  Either it's
     # a user via their preferred email address or it's an explicit address.
     # If it's a UUID, then it must be associated with an existing user.
     subscriber = arguments.pop('subscriber')
     user_manager = getUtility(IUserManager)
     # We use the display name if there is one.
     display_name = arguments.pop('display_name', '')
     if isinstance(subscriber, UUID):
         user = user_manager.get_user_by_id(subscriber)
         if user is None:
             bad_request(response, b'No such user')
             return
         subscriber = user
     else:
         # This must be an email address.  See if there's an existing
         # address object associated with this email.
         address = user_manager.get_address(subscriber)
         if address is None:
             # Create a new address, which of course will not be validated.
             address = user_manager.create_address(subscriber, display_name)
         subscriber = address
     # What role are we subscribing?  Regular members go through the
     # subscription policy workflow while owners, moderators, and
     # nonmembers go through the legacy API for now.
     role = arguments.pop('role', MemberRole.member)
     if role is MemberRole.member:
         # Get the pre_ flags for the subscription workflow.
         pre_verified = arguments.pop('pre_verified', False)
         pre_confirmed = arguments.pop('pre_confirmed', False)
         pre_approved = arguments.pop('pre_approved', False)
         # Now we can run the registration process until either the
         # subscriber is subscribed, or the workflow is paused for
         # verification, confirmation, or approval.
         registrar = ISubscriptionManager(mlist)
         try:
             token, token_owner, member = registrar.register(
                 subscriber,
                 pre_verified=pre_verified,
                 pre_confirmed=pre_confirmed,
                 pre_approved=pre_approved)
         except AlreadySubscribedError:
             conflict(response, b'Member already subscribed')
             return
         except MissingPreferredAddressError:
             bad_request(response, b'User has no preferred address')
             return
         except MembershipIsBannedError:
             bad_request(response, b'Membership is banned')
             return
         except SubscriptionPendingError:
             conflict(response, b'Subscription request already pending')
             return
         if token is None:
             assert token_owner is TokenOwner.no_one, token_owner
             # The subscription completed.  Let's get the resulting member
             # and return the location to the new member.  Member ids are
             # UUIDs and need to be converted to URLs because JSON doesn't
             # directly support UUIDs.
             member_id = self.api.from_uuid(member.member_id)
             location = self.api.path_to('members/{}'.format(member_id))
             created(response, location)
             return
         # The member could not be directly subscribed because there are
         # some out-of-band steps that need to be completed.  E.g. the user
         # must confirm their subscription or the moderator must approve
         # it.  In this case, an HTTP 202 Accepted is exactly the code that
         # we should use, and we'll return both the confirmation token and
         # the "token owner" so the client knows who should confirm it.
         assert token is not None, token
         assert token_owner is not TokenOwner.no_one, token_owner
         assert member is None, member
         content = dict(token=token, token_owner=token_owner.name)
         accepted(response, etag(content))
         return
     # 2015-04-15 BAW: We're subscribing some role other than a regular
     # member.  Use the legacy API for this for now.
     assert role in (MemberRole.owner, MemberRole.moderator,
                     MemberRole.nonmember)
     # 2015-04-15 BAW: We're limited to using an email address with this
     # legacy API, so if the subscriber is a user, the user must have a
     # preferred address, which we'll use, even though it will subscribe
     # the explicit address.  It is an error if the user does not have a
     # preferred address.
     #
     # If the subscriber is an address object, just use that.
     if IUser.providedBy(subscriber):
         if subscriber.preferred_address is None:
             bad_request(response, b'User without preferred address')
             return
         email = subscriber.preferred_address.email
     else:
         assert IAddress.providedBy(subscriber)
         email = subscriber.email
     delivery_mode = arguments.pop('delivery_mode', DeliveryMode.regular)
     record = RequestRecord(email, display_name, delivery_mode)
     try:
         member = add_member(mlist, record, role)
     except MembershipIsBannedError:
         bad_request(response, b'Membership is banned')
         return
     except AlreadySubscribedError:
         bad_request(
             response,
             '{} is already an {} of {}'.format(email, role.name,
                                                mlist.fqdn_listname))
         return
     # The subscription completed.  Let's get the resulting member
     # and return the location to the new member.  Member ids are
     # UUIDs and need to be converted to URLs because JSON doesn't
     # directly support UUIDs.
     member_id = self.api.from_uuid(member.member_id)
     location = self.api.path_to('members/{}'.format(member_id))
     created(response, location)
Exemplo n.º 20
0
 def add(self, email):
     """Add email to mailinglist."""
     add_member(
         self.list,
         RequestRecord(email, '', DeliveryMode.regular,
                       self.list.preferred_language.code))