def test_member_is_user_and_has_no_display_name(self): user = getUtility(IUserManager).create_user("*****@*****.**") set_preferred(user) self._mlist.subscribe(user) items = get_queue_messages("virgin", expected_count=1) message = items[0].msg self.assertEqual(message["to"], "*****@*****.**")
def test_banned_address_linked_to_user(self): # Anne is subscribed to a mailing list as a user with her preferred # address. She also has a secondary address which is banned and which # she uses to post to the mailing list. Both the MemberModeration and # NonmemberModeration rules miss because the posting address is # banned. user_manager = getUtility(IUserManager) anne = user_manager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne, MemberRole.member) anne.link(user_manager.create_address('*****@*****.**')) IBanManager(self._mlist).ban('*****@*****.**') msg = mfs("""\ From: [email protected] To: [email protected] Subject: A test message Message-ID: <ant> MIME-Version: 1.0 A message body. """) rule = moderation.MemberModeration() result = rule.check(self._mlist, msg, {}) self.assertFalse(result) rule = moderation.NonmemberModeration() result = rule.check(self._mlist, msg, {}) self.assertFalse(result)
def test_absorb_duplicates(self): # Duplicate memberships, where the list-id and role match, are # ignored. Here we subscribe Anne to the test list as a member, and # Bart as both a member and an owner. Anne's member membership # remains unchanged, but she gains an owner membership. with transaction(): bart = self._manager.create_user('*****@*****.**') set_preferred(bart) self._mlist.subscribe(self._anne, MemberRole.member) self._mlist.subscribe(bart, MemberRole.member) self._mlist.subscribe(bart, MemberRole.owner) # There are now three memberships. all_members = list(self._manager.members) self.assertEqual(len(all_members), 3, all_members) # Do the absorption. self._anne.absorb(bart) # There are now only 2 memberships, both owned by Anne. all_members = list(self._manager.members) self.assertEqual(len(all_members), 2, all_members) memberships = set([ (member.list_id, member.role, member.address.email) for member in all_members ]) self.assertEqual(memberships, set([ ('test.example.com', MemberRole.member, '*****@*****.**'), ('test.example.com', MemberRole.owner, '*****@*****.**'), ]))
def test_member_is_user_and_has_no_display_name(self): user = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(user) self._mlist.subscribe(user) items = get_queue_messages('virgin', expected_count=1) message = items[0].msg self.assertEqual(message['to'], '*****@*****.**')
def test_member_changes_preferred_address(self): with transaction(): anne = self._usermanager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne) # Take a look at Anne's current membership. json, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com') # Anne registers a new address and makes it her preferred address. # There are no changes to her membership. with transaction(): new_preferred = anne.register('*****@*****.**') new_preferred.verified_on = now() anne.preferred_address = new_preferred # Take another look at Anne's current membership. json, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com')
def setUp(self): self._ant = create_list('*****@*****.**') self._bee = create_list('*****@*****.**') user_manager = getUtility(IUserManager) self._anne = user_manager.make_user( '*****@*****.**', 'Anne Person') set_preferred(self._anne)
def test_member_changes_preferred_address(self): with transaction(): anne = self._usermanager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne) # Take a look at Anne's current membership. content, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com') # Anne registers a new address and makes it her preferred address. # There are no changes to her membership. with transaction(): new_preferred = anne.register('*****@*****.**') new_preferred.verified_on = now() anne.preferred_address = new_preferred # Take another look at Anne's current membership. content, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com')
def test_find_members_user_and_secondary_address(self): # A user has two subscriptions: the user itself and one of its # secondary addresses. anne = self._user_manager.create_user('*****@*****.**') set_preferred(anne) # Create a secondary address. address = self._user_manager.create_address('*****@*****.**') address.user = anne # Subscribe the user and the secondary address. self._mlist.subscribe(anne) self._mlist.subscribe(address) # Search for the user-based subscription. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0]._user, anne) # The address-id is None because the user is the subscriber. self.assertIsNone(members[0].address_id) # Search for the address-based subscription. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0]._address, address) # The user-id is None because the address is the subscriber. self.assertIsNone(members[0].user_id) # Search by user-id. In this case because the address is linked to # the user, we should get two results. members = self._service.find_members(anne.user_id) self.assertEqual(len(members), 2)
def test_leave(self): with transaction(): self._mlist.unsubscription_policy = SubscriptionPolicy.confirm anne = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne.preferred_address) msg = mfs("""\ From: [email protected] To: [email protected] leave """) self._commandq.enqueue( msg, dict(listid='test.example.com', subaddress='leave')) self._runner.run() # Two messages have been sent, both to [email protected]. The first # asks for her confirmation of her unsubscription event. The second # is the results of her email command. items = get_queue_messages('virgin', sort_on='subject', expected_count=2) if items[0].msg['from'] == '*****@*****.**': results = items[0].msg confirmation = items[1].msg else: results = items[1].msg confirmation = items[0].msg self.assertTrue(str(confirmation['subject']).startswith('confirm')) line = confirmation_line(results) # The confirmation line should name Anne's email address. self.assertIn('*****@*****.**', line)
def setUp(self): self._bestlist = create_list('*****@*****.**') self._mlist = create_list('*****@*****.**') self._mlist.bounce_score_threshold = 5 self._mlist.bounce_you_are_disabled_warnings = 2 self._mlist.bounce_you_are_disabled_warnings_interval = timedelta( days=2) self._bestlist.bounce_score_threshold = 3 self._bestlist.bounce_you_are_disabled_warnings = 1 self._bestlist.bounce_you_are_disabled_warnings_interval = timedelta( days=3) self._usermanager = getUtility(IUserManager) self._mmanager = MembershipManager() anne = self._usermanager.create_user('*****@*****.**') bart = self._usermanager.create_user('*****@*****.**') set_preferred(anne) set_preferred(bart) self.anne_member = self._mlist.subscribe(anne) self.bart_member = self._mlist.subscribe(bart) self.anne_member_best = self._bestlist.subscribe(anne) self.bart_member_best = self._bestlist.subscribe(bart)
def test_absorb_duplicates(self): # Duplicate memberships, where the list-id and role match, are # ignored. Here we subscribe Anne to the test list as a member, and # Bart as both a member and an owner. Anne's member membership # remains unchanged, but she gains an owner membership. with transaction(): bart = self._manager.create_user('*****@*****.**') set_preferred(bart) self._mlist.subscribe(self._anne, MemberRole.member) self._mlist.subscribe(bart, MemberRole.member) self._mlist.subscribe(bart, MemberRole.owner) # There are now three memberships. all_members = list(self._manager.members) self.assertEqual(len(all_members), 3, all_members) # Do the absorption. self._anne.absorb(bart) # There are now only 2 memberships, both owned by Anne. all_members = list(self._manager.members) self.assertEqual(len(all_members), 2, all_members) memberships = set([(member.list_id, member.role, member.address.email) for member in all_members]) self.assertEqual( memberships, set([ ('test.example.com', MemberRole.member, '*****@*****.**'), ('test.example.com', MemberRole.owner, '*****@*****.**'), ]))
def test_absorb_memberships(self): # When a user is absorbed, all of their user-subscribed memberships # are relinked to the absorbing user. mlist2 = create_list('*****@*****.**') mlist3 = create_list('*****@*****.**') with transaction(): # This has to happen in a transaction so that both the user and # the preferences objects get valid ids. bart = self._manager.create_user('*****@*****.**', 'Bart Person') set_preferred(bart) # Subscribe both users to self._mlist. self._mlist.subscribe(self._anne, MemberRole.member) self._mlist.subscribe(bart, MemberRole.moderator) # Subscribe only Bart to mlist2. mlist2.subscribe(bart, MemberRole.owner) # Subscribe only Bart's address to mlist3. mlist3.subscribe(bart.preferred_address, MemberRole.moderator) # There are now 4 memberships, one with Anne two with Bart's user and # one with Bart's address. all_members = list(self._manager.members) self.assertEqual(len(all_members), 4, all_members) # Do the absorption. self._anne.absorb(bart) # The Bart user has been deleted, leaving only the Anne user in the # user manager. all_users = list(self._manager.users) self.assertEqual(len(all_users), 1) self.assertEqual(all_users[0], self._anne) # There are no leftover memberships for user Bart. Anne owns all the # memberships. all_members = list(self._manager.members) self.assertEqual(len(all_members), 4, all_members) self.assertEqual(self._anne.memberships.member_count, 4) memberships = {(member.list_id, member.role): member for member in self._anne.memberships.members} # Note that Anne is now both a member and moderator of the test list. self.assertEqual( set(memberships), set([ ('test.example.com', MemberRole.member), ('test.example.com', MemberRole.moderator), ('test2.example.com', MemberRole.owner), ('test3.example.com', MemberRole.moderator), ])) # Both of Bart's previous user subscriptions are now transferred to # the Anne user. self.assertEqual( memberships[('test.example.com', MemberRole.moderator)].address, self._anne.preferred_address) self.assertEqual( memberships[('test2.example.com', MemberRole.owner)].address, self._anne.preferred_address) # Bart's address was subscribed; it must not have been changed. Of # course, Anne now controls [email protected]. key = ('test3.example.com', MemberRole.moderator) self.assertEqual(memberships[key].address.email, '*****@*****.**') self.assertEqual(self._manager.get_user('*****@*****.**'), self._anne)
def setUp(self): with transaction(): self._mlist = create_list('*****@*****.**') self._registrar = ISubscriptionManager(self._mlist) manager = getUtility(IUserManager) self._anne = manager.create_address('*****@*****.**', 'Anne Person') self._bart = manager.make_user('*****@*****.**', 'Bart Person') set_preferred(self._bart)
def test_find_member_user(self): # Find user-based memberships by address. user = self._user_manager.create_user('*****@*****.**', 'Anne User') set_preferred(user) # Subscribe the user. self._mlist.subscribe(user) members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0].user, user)
def test_absorb_memberships(self): # When a user is absorbed, all of their user-subscribed memberships # are relinked to the absorbing user. mlist2 = create_list('*****@*****.**') mlist3 = create_list('*****@*****.**') with transaction(): # This has to happen in a transaction so that both the user and # the preferences objects get valid ids. bart = self._manager.create_user('*****@*****.**', 'Bart Person') set_preferred(bart) # Subscribe both users to self._mlist. self._mlist.subscribe(self._anne, MemberRole.member) self._mlist.subscribe(bart, MemberRole.moderator) # Subscribe only Bart to mlist2. mlist2.subscribe(bart, MemberRole.owner) # Subscribe only Bart's address to mlist3. mlist3.subscribe(bart.preferred_address, MemberRole.moderator) # There are now 4 memberships, one with Anne two with Bart's user and # one with Bart's address. all_members = list(self._manager.members) self.assertEqual(len(all_members), 4, all_members) # Do the absorption. self._anne.absorb(bart) # The Bart user has been deleted, leaving only the Anne user in the # user manager. all_users = list(self._manager.users) self.assertEqual(len(all_users), 1) self.assertEqual(all_users[0], self._anne) # There are no leftover memberships for user Bart. Anne owns all the # memberships. all_members = list(self._manager.members) self.assertEqual(len(all_members), 4, all_members) self.assertEqual(self._anne.memberships.member_count, 4) memberships = {(member.list_id, member.role): member for member in self._anne.memberships.members} # Note that Anne is now both a member and moderator of the test list. self.assertEqual(set(memberships), set([ ('test.example.com', MemberRole.member), ('test.example.com', MemberRole.moderator), ('test2.example.com', MemberRole.owner), ('test3.example.com', MemberRole.moderator), ])) # Both of Bart's previous user subscriptions are now transferred to # the Anne user. self.assertEqual( memberships[('test.example.com', MemberRole.moderator)].address, self._anne.preferred_address) self.assertEqual( memberships[('test2.example.com', MemberRole.owner)].address, self._anne.preferred_address) # Bart's address was subscribed; it must not have been changed. Of # course, Anne now controls [email protected]. key = ('test3.example.com', MemberRole.moderator) self.assertEqual(memberships[key].address.email, '*****@*****.**') self.assertEqual(self._manager.get_user('*****@*****.**'), self._anne)
def test_find_member_user(self): # Find user-based memberships by address. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') set_preferred(user) # Subscribe the user. self._mlist.subscribe(user) members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0].user, user)
def setUp(self): with transaction(): self._mlist = create_list('*****@*****.**') self._registrar = IRegistrar(self._mlist) manager = getUtility(IUserManager) self._anne = manager.create_address( '*****@*****.**', 'Anne Person') self._bart = manager.make_user( '*****@*****.**', 'Bart Person') set_preferred(self._bart)
def test_member_has_address_and_user_display_name(self): user = getUtility(IUserManager).create_user("*****@*****.**", "Anne Person") set_preferred(user) address = getUtility(IUserManager).create_address("*****@*****.**", "Anne X Person") address.verified_on = now() user.link(address) self._mlist.subscribe(address) items = get_queue_messages("virgin", expected_count=1) message = items[0].msg self.assertEqual(message["to"], "Anne X Person <*****@*****.**>")
def test_member_has_no_linked_display_name(self): user = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(user) address = getUtility(IUserManager).create_address('*****@*****.**') address.verified_on = now() user.link(address) self._mlist.subscribe(address) items = get_queue_messages('virgin', expected_count=1) message = items[0].msg self.assertEqual(message['to'], '*****@*****.**')
def test_cannot_set_address_with_preferred_address_subscription(self): # A user is subscribed to a mailing list with their preferred address. # You cannot set the `address` attribute on such IMembers. anne = self._usermanager.create_user('*****@*****.**') set_preferred(anne) # Subscribe with the IUser object, not the address. This makes Anne a # member via her preferred address. member = self._mlist.subscribe(anne) new_address = anne.register('*****@*****.**') new_address.verified_on = now() self.assertRaises(MembershipError, setattr, member, 'address', new_address)
def test_is_subscribed(self): manager = getUtility(IUserManager) user = manager.create_user('*****@*****.**', 'Anne Person') set_preferred(user) self.assertEqual(False, self._mlist.is_subscribed(user)) self._mlist.subscribe(user) self.assertEqual(True, self._mlist.is_subscribed(user)) address = manager.create_address('*****@*****.**', 'Anne Person') address.verfied_on = now() self.assertEqual(False, self._mlist.is_subscribed(address)) self._mlist.subscribe(address) self.assertEqual(True, self._mlist.is_subscribed(address))
def test_subscriptin_mode(self): # Test subscription mode reflects if a user is subscribed or an address # is. addr = self._usermanager.create_address('*****@*****.**') addr.verified_on = now() self._mlist.subscribe(addr) member = self._mlist.members.get_member('*****@*****.**') self.assertEqual(member.subscription_mode, SubscriptionMode.as_address) auser = self._usermanager.create_user('*****@*****.**') set_preferred(auser) amember = self._mlist.subscribe(auser, MemberRole.member) self.assertEqual(amember.subscription_mode, SubscriptionMode.as_user)
def test_wont_find_member_user_secondary_address(self): # Finding user-based memberships using a secondary address is not # supported; the subscription is not returned. user = self._user_manager.create_user('*****@*****.**', 'Anne User') set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address('*****@*****.**', 'Anne User 2') address_2.user = user # Subscribe the user. self._mlist.subscribe(user) # Search for the secondary address. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 0)
def test_wont_find_member_user_secondary_address(self): # Finding user-based memberships using a secondary address is not # supported; the subscription is not returned. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address( '*****@*****.**', 'Anne User 2') address_2.user = user # Subscribe the user. self._mlist.subscribe(user) # Search for the secondary address. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 0)
def test_unsubscribe_members_with_duplicate_failures(self): ant = create_list('*****@*****.**') ant.admin_immed_notify = False anne = self._user_manager.create_user('*****@*****.**') set_preferred(anne) ant.subscribe(anne, MemberRole.member) # Now we try to unsubscribe a nonmember twice in the same call. # That's okay because duplicates are ignored. success, fail = self._service.unsubscribe_members( ant.list_id, [ '*****@*****.**', '*****@*****.**', ]) self.assertEqual(success, set()) self.assertEqual(fail, set(['*****@*****.**']))
def test_confirm_leave_not_a_member(self): self._mlist.unsubscription_policy = SubscriptionPolicy.confirm # Try to unsubscribe someone who is not a member. Anne is a real # user, with a validated address, but she is not a member of the # mailing list. anne = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(anne) # Initiate an unsubscription. msg = Message() msg['From'] = '*****@*****.**' results = Results() self._command.process(self._mlist, msg, {}, (), results) self.assertEqual( str(results).splitlines()[-1], 'leave: [email protected] is not a member of [email protected]')
def test_create_new_owner_by_hex(self): with transaction(): user = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(user) # Subscribe the user to the mailing list by hex UUID. response, headers = call_api( 'http://localhost:9001/3.1/members', { 'list_id': 'ant.example.com', 'subscriber': '00000000000000000000000000000001', 'role': 'owner', }) self.assertEqual(headers.status, 201) self.assertEqual( headers['location'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001' )
def test_unsubscribe_defer(self): # When unsubscriptions must be approved by the moderator, but the # moderator defers this decision. user_manager = getUtility(IUserManager) anne = user_manager.create_address('*****@*****.**', 'Anne Person') token, token_owner, member = self._manager.register( anne, pre_verified=True, pre_confirmed=True, pre_approved=True) self.assertIsNone(token) self.assertEqual(member.address.email, '*****@*****.**') bart = user_manager.create_user('*****@*****.**', 'Bart User') address = set_preferred(bart) self._mlist.subscribe(address, MemberRole.moderator) # Now hold and handle an unsubscription request. token = hold_unsubscription(self._mlist, '*****@*****.**') handle_unsubscription(self._mlist, token, Action.defer) items = get_queue_messages('virgin', expected_count=2) # Find the moderator message. for item in items: if item.msg['to'] == '*****@*****.**': break else: raise AssertionError('No moderator email found') self.assertEqual( item.msgdata['recipients'], {'*****@*****.**'}) self.assertEqual( item.msg['subject'], 'New unsubscription request from Test by [email protected]')
def test_create_new_owner_by_hex(self): with transaction(): user = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(user) # Subscribe the user to the mailing list by hex UUID. json, response = call_api( 'http://localhost:9001/3.1/members', { 'list_id': 'ant.example.com', 'subscriber': '00000000000000000000000000000001', 'role': 'owner', }) self.assertEqual(response.status_code, 201) self.assertEqual( response.headers['location'], 'http://localhost:9001/3.1/members/00000000000000000000000000000001' )
def test_wont_find_member_secondary_address(self): # A user is subscribed with one of their address, and a search is # performed on another of their addresses. This is not supported; the # subscription is not returned. user = self._user_manager.create_user('*****@*****.**', 'Anne User') set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address('*****@*****.**', 'Anne User 2') address_2.verified_on = now() address_2.user = user # Subscribe the secondary address. self._mlist.subscribe(address_2) # Search for the primary address. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 0)
def test_hold_chain_charset(self): # Issue #144 - UnicodeEncodeError in the hold chain. self._mlist.admin_immed_notify = True self._mlist.respond_to_post_requests = False bart = self._user_manager.create_user('*****@*****.**', 'Bart User') address = set_preferred(bart) self._mlist.subscribe(address, MemberRole.moderator) path = resource_filename('mailman.chains.tests', 'issue144.eml') with open(path, 'rb') as fp: msg = mfb(fp.read()) msg.sender = '*****@*****.**' process_chain(self._mlist, msg, {}, start_chain='hold') # The postauth.txt message is now in the virgin queue awaiting # delivery to the moderators. items = get_queue_messages('virgin', expected_count=1) msgdata = items[0].msgdata # Should get sent to -owner address. self.assertEqual(msgdata['recipients'], {'*****@*****.**'}) # Ensure that the subject looks correct in the postauth.txt. msg = items[0].msg value = None for line in msg.get_payload(0).get_payload().splitlines(): if line.strip().startswith('Subject:'): header, colon, value = line.partition(':') break self.assertEqual(value.lstrip(), 'Vi?enamjenski pi?tolj za vodu 8/1') self.assertEqual( msg['Subject'], '[email protected] post from [email protected] requires approval')
def test_find_members_with_display_name(self): # Test that we can search members through the display_name of either # the attached user or the address. anne = self._user_manager.create_address( '*****@*****.**', display_name='Anita') bart = self._user_manager.create_user( '*****@*****.**', display_name='Bob') set_preferred(bart) self._mlist.subscribe(anne) self._mlist.subscribe(bart) # Search for Anne's name. members = self._service.find_members('*Ani*') self.assertEqual(len(members), 1) # Search for Bob's name. members = self._service.find_members('*Bo*') self.assertEqual(len(members), 1)
def test_join_pending(self): self._mlist.subscription_policy = SubscriptionPolicy.confirm # Try to subscribe someone who already has a subscription pending. # Anne is a real user, with a validated address, who already has a # pending subscription for this mailing list. anne = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(anne) # Initiate a subscription. ISubscriptionManager(self._mlist).register(anne) # And try to subscribe. msg = Message() msg['From'] = '*****@*****.**' results = Results() self._command.process(self._mlist, msg, {}, (), results) self.assertEqual( str(results).splitlines()[-1], '[email protected] has a pending subscription for [email protected]')
def test_cannot_create_new_membership_by_int(self): with transaction(): user = getUtility(IUserManager).create_user('*****@*****.**') set_preferred(user) # We can't use the int representation of the UUID with API 3.1. with self.assertRaises(HTTPError) as cm: call_api('http://localhost:9001/3.1/members', { 'list_id': 'ant.example.com', 'subscriber': '1', 'pre_verified': True, 'pre_confirmed': True, 'pre_approved': True, }) # This is a bad request because the `subscriber` value isn't something # that's known to the system, in API 3.1. It's not technically a 404 # because that's reserved for URL lookups. self.assertEqual(cm.exception.code, 400)
def test_do_confirm_verify_user(self): # A confirmation step is necessary when a user subscribes with their # preferred address, and we are not pre-confirming. anne = self._user_manager.create_user(self._anne) set_preferred(anne) # Run the workflow to model the confirmation step. There is no # subscriber attribute yet. workflow = SubscriptionWorkflow(self._mlist, anne) list(workflow) self.assertEqual(workflow.subscriber, anne) # Do a confirmation workflow, which should now set the subscriber. confirm_workflow = SubscriptionWorkflow(self._mlist) confirm_workflow.token = workflow.token confirm_workflow.restore() confirm_workflow.run_thru('do_confirm_verify') # The address is now verified. self.assertEqual(confirm_workflow.subscriber, anne)
def test_wont_find_member_secondary_address(self): # A user is subscribed with one of their address, and a search is # performed on another of their addresses. This is not supported; the # subscription is not returned. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address( '*****@*****.**', 'Anne User 2') address_2.verified_on = now() address_2.user = user # Subscribe the secondary address. self._mlist.subscribe(address_2) # Search for the primary address. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 0)
def test_find_members_user_and_primary_address(self): # A user has two subscriptions: 1) where the user itself is the # subscriber, 2) the address which happens to be the user's preferred # address is the subscriber. Remember that in the model, this # represents two separate subscriptions because the user can always # change their preferred address. anne = self._user_manager.create_user('*****@*****.**') set_preferred(anne) # Subscribe the user and their preferred address. self._mlist.subscribe(anne) self._mlist.subscribe(anne.preferred_address) # Search for the user's address. members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 2) # Search for the user. members = self._service.find_members(anne.user_id) self.assertEqual(len(members), 2)
def test_no_banned_sender(self): # Simple case where the sender is not banned. user_manager = getUtility(IUserManager) anne = user_manager.create_user('*****@*****.**') set_preferred(anne) msg = mfs("""\ From: [email protected] To: [email protected] Subject: A test message Message-ID: <ant> MIME-Version: 1.0 A message body. """) rule = banned_address.BannedAddress() result = rule.check(self._mlist, msg, {}) self.assertFalse(result)
def test_join_as_user_with_preferred_address(self): with transaction(): anne = self._usermanager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne) json, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com') self.assertEqual(entry_0['list_id'], 'test.example.com')
def test_find_member_address_with_user(self): # Find address-based memberships when a user is linked to the address. user = self._user_manager.create_user('*****@*****.**', 'Anne User') address = set_preferred(user) # Subscribe the address. self._mlist.subscribe(address) members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0].user, user)
def test_join_as_user_with_preferred_address(self): with transaction(): anne = self._usermanager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne) content, response = call_api('http://*****:*****@example.com') self.assertEqual( entry_0['address'], 'http://*****:*****@example.com') self.assertEqual(entry_0['list_id'], 'test.example.com')
def setUp(self): self._mlist = create_list('*****@*****.**') user_manager = getUtility(IUserManager) self._anne = user_manager.create_user('*****@*****.**') self._bart = user_manager.create_user('*****@*****.**') self._cris = user_manager.create_user('*****@*****.**') self._dave = user_manager.create_user('*****@*****.**') set_preferred(self._anne) set_preferred(self._bart) set_preferred(self._cris) set_preferred(self._dave)
def test_find_member_address_with_user(self): # Find address-based memberships when a user is linked to the address. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') address = set_preferred(user) # Subscribe the address. self._mlist.subscribe(address) members = self._service.find_members('*****@*****.**') self.assertEqual(len(members), 1) self.assertEqual(members[0].user, user)
def test_find_member_user_id_controlled_addresses(self): # Find address-based memberships by user_id when a secondary address is # subscribed. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address( '*****@*****.**', 'Anne User 2') address_2.verified_on = now() address_2.user = user # Create a third address. address_3 = self._user_manager.create_address( '*****@*****.**', 'Anne User 3') address_3.verified_on = now() address_3.user = user # Subscribe the secondary address only. self._mlist.subscribe(address_2) members = self._service.find_members(user.user_id) self.assertEqual(len(members), 1) self.assertEqual(members[0].address, address_2)
def test_sanity_checks_user_with_preferred_address(self): # Ensure that the sanity check phase, when given an IUser with a # preferred address, ends up with an address. anne = self._user_manager.make_user(self._anne) address = set_preferred(anne) workflow = SubscriptionWorkflow(self._mlist, anne) # The constructor sets workflow.address because the user has a # preferred address. self.assertEqual(workflow.address, address) self.assertEqual(workflow.user, anne) workflow.run_thru('sanity_checks') self.assertEqual(workflow.address, address) self.assertEqual(workflow.user, anne)
def test_linked_address_nonmembermoderation_misses(self): # Anne subscribes to a mailing list as a user with her preferred # address. She also has a secondary linked address, and she uses this # to post to the mailing list. The NonmemberModeration rule misses # because Anne is not a nonmember. user_manager = getUtility(IUserManager) anne = user_manager.create_user('*****@*****.**') set_preferred(anne) self._mlist.subscribe(anne, MemberRole.member) anne.link(user_manager.create_address('*****@*****.**')) rule = moderation.NonmemberModeration() msg = mfs("""\ From: [email protected] To: [email protected] Subject: A test message Message-ID: <ant> MIME-Version: 1.0 A message body. """) result = rule.check(self._mlist, msg, {}) self.assertFalse(result)
def test_find_members_issue_227(self): # A user is subscribed to a list with their preferred address. They # have a different secondary linked address which is not subscribed. # ISubscriptionService.find_members() should find the first, but not # the second 'subscriber'. # # https://gitlab.com/mailman/mailman/issues/227 anne = self._user_manager.create_user('*****@*****.**') set_preferred(anne) # Create a secondary address. address = self._user_manager.create_address('*****@*****.**') address.user = anne # Subscribe Anne's user record. self._mlist.subscribe(anne) # Each of these searches should return only a single member, the one # that has Anne's user record as its subscriber. call_arguments = [ # Search by mailing list id. dict(list_id=self._mlist.list_id), # Search by user id. dict(subscriber=anne.user_id), # Search by Anne's preferred address. dict(subscriber='*****@*****.**'), # Fuzzy search by address. dict(subscriber='anne*'), ] for arguments in call_arguments: members = self._service.find_members(**arguments) # We check the lengths twice to ensure that the two "views" of the # results match expectations. len() implicitly calls the query's # .count() method which according to the SQLAlchemy documentation # does *not* de-duplicate the rows. In the second case, we turn # the result set into a concrete list, which works by iterating # over the result. In both cases, we expect only a single match. self.assertEqual(len(members), 1) self.assertEqual(len(list(members)), 1) self.assertEqual(members[0].user, anne)
def test_no_duplicate_subscriptions(self): # A user is not allowed to subscribe more than once to the mailing # list with the same role. anne = getUtility(IUserManager).create_user('*****@*****.**') # Give the user a preferred address. preferred = set_preferred(anne) # Subscribe Anne to the mailing list as a regular member. member = self._mlist.subscribe(anne) self.assertEqual(member.address, preferred) self.assertEqual(member.role, MemberRole.member) # A second subscription with the same role will fail. with self.assertRaises(AlreadySubscribedError) as cm: self._mlist.subscribe(anne) self.assertEqual(cm.exception.fqdn_listname, '*****@*****.**') self.assertEqual(cm.exception.email, '*****@*****.**') self.assertEqual(cm.exception.role, MemberRole.member)
def test_default_moderation_action(self): # Owners and moderators have their posts accepted, members and # nonmembers default to the mailing list's action for their type. anne = self._usermanager.create_user('*****@*****.**') bart = self._usermanager.create_user('*****@*****.**') cris = self._usermanager.create_user('*****@*****.**') dana = self._usermanager.create_user('*****@*****.**') set_preferred(anne) set_preferred(bart) set_preferred(cris) set_preferred(dana) anne_member = self._mlist.subscribe(anne, MemberRole.owner) bart_member = self._mlist.subscribe(bart, MemberRole.moderator) cris_member = self._mlist.subscribe(cris, MemberRole.member) dana_member = self._mlist.subscribe(dana, MemberRole.nonmember) self.assertEqual(anne_member.moderation_action, Action.accept) self.assertEqual(bart_member.moderation_action, Action.accept) self.assertIsNone(cris_member.moderation_action) self.assertIsNone(dana_member.moderation_action)
def test_unsubscribe_members(self): # Check that memberships are properly unsubscribed. # # Start by creating the mailing lists we'll use. Make sure that # subscriptions don't send any notifications. ant = create_list('*****@*****.**') ant.admin_immed_notify = False bee = create_list('*****@*****.**') bee.admin_immed_notify = False # Anne is a user with a preferred address and several linked # secondary addresses. anne = self._user_manager.create_user('*****@*****.**') anne_0 = set_preferred(anne) anne_1 = self._user_manager.create_address('*****@*****.**') anne_1.verified_on = now() anne_1.user = anne anne_2 = self._user_manager.create_address('*****@*****.**') anne_2.verified_on = now() anne_2.user = anne # These folks will subscribe with addresses only. bart = self._user_manager.create_address('*****@*****.**') bart.verified_on = now() cris = self._user_manager.create_address('*****@*****.**') cris.verified_on = now() dave = self._user_manager.create_address('*****@*****.**') dave.verified_on = now() # Elle is another user with a preferred address and a linked # secondary address. elle = self._user_manager.create_user('*****@*****.**') elle_0 = set_preferred(elle) elle_1 = self._user_manager.create_address('*****@*****.**') elle_1.verified_on = now() # Fred will also subscribe with just his address. fred = self._user_manager.create_address('*****@*****.**') # Gwen will only be subscribed to the second mailing list. gwen = self._user_manager.create_address('*****@*****.**') # Now we're going to create some subscriptions, with various # combinations of user or address subscribers, and various # roles. ant.subscribe(anne, MemberRole.member) ant.subscribe(anne, MemberRole.moderator) ant.subscribe(anne, MemberRole.owner) bee.subscribe(anne, MemberRole.member) bee.subscribe(anne, MemberRole.moderator) ant.subscribe(anne_0, MemberRole.member) bee.subscribe(anne_0, MemberRole.member) bee.subscribe(anne_0, MemberRole.moderator) ant.subscribe(anne_1, MemberRole.member) ant.subscribe(anne_1, MemberRole.moderator) bee.subscribe(anne_1, MemberRole.member) bee.subscribe(anne_1, MemberRole.owner) ant.subscribe(anne_2, MemberRole.member) # Now for Bart. ant.subscribe(bart, MemberRole.member) bee.subscribe(bart, MemberRole.member) # And Cris. ant.subscribe(cris, MemberRole.member) ant.subscribe(cris, MemberRole.moderator) bee.subscribe(cris, MemberRole.member) # Now Dave. ant.subscribe(dave, MemberRole.member) bee.subscribe(dave, MemberRole.member) bee.subscribe(dave, MemberRole.moderator) # Elle-the-user. ant.subscribe(elle, MemberRole.member) # Elle-the-address. bee.subscribe(elle_0, MemberRole.member) # Fred and Gwen. ant.subscribe(fred, MemberRole.member) bee.subscribe(gwen, MemberRole.member) # Now it's time to do the mass unsubscribe from the ant mailing # list. We choose a set of addresses that have multiple # memberships across both lists, with various roles. We're only # going to unsubscribe those addresses which are subscribed to # the ant mailing list with the role of member. Throw in a few # bogus or not-subscribed addresses. success, fail = self._service.unsubscribe_members( ant.list_id, set([ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ])) # We should have successfully unsubscribed these addresses, # which were subscribed in various ways to the ant mailing list # as members. self.assertEqual(success, set([ '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ])) # These two addresses were failed, in one case because it's not # a valid email address, and in the other because it's not # subscribed to the mailing list. self.assertEqual(fail, set([ '*****@*****.**', '*****@*****.**', ])) # Now obtain various rosters and ensure that they have the # memberships we expect, after the mass unsubscribe. ant_members = ant.get_roster(MemberRole.member) self.assertEqual( [address.email for address in ant_members.addresses], ['*****@*****.**', '*****@*****.**', ]) bee_members = bee.get_roster(MemberRole.member) # anne_0 is in the list twice, once because she's subscribed # with her preferred address, and again because she's subscribed # with her explicit address. self.assertEqual( [address.email for address in bee_members.addresses], ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**', ]) ant_moderators = ant.get_roster(MemberRole.moderator) self.assertEqual( [address.email for address in ant_moderators.addresses], ['*****@*****.**', '*****@*****.**', '*****@*****.**', ]) bee_moderators = bee.get_roster(MemberRole.moderator) # As above, anne_0 shows up the moderators twice. self.assertEqual( [address.email for address in bee_moderators.addresses], ['*****@*****.**', '*****@*****.**', '*****@*****.**', ]) ant_owners = ant.get_roster(MemberRole.owner) self.assertEqual( [address.email for address in ant_owners.addresses], ['*****@*****.**']) bee_owners = bee.get_roster(MemberRole.owner) self.assertEqual( [address.email for address in bee_owners.addresses], ['*****@*****.**'])
def setUp(self): self._manager = getUtility(IUserManager) self._mlist = create_list('*****@*****.**') self._anne = self._manager.create_user( '*****@*****.**', 'Anne Person') set_preferred(self._anne)
def test_find_member_sorting(self): # Check that the memberships are properly sorted. user = self._user_manager.create_user( '*****@*****.**', 'Anne User') address = set_preferred(user) # Create a secondary address. address_2 = self._user_manager.create_address( '*****@*****.**', 'Anne User 2') address_2.verified_on = now() address_2.user = user # Create a third address. address_3 = self._user_manager.create_address( '*****@*****.**', 'Anne User 3') address_3.verified_on = now() address_3.user = user # Create three lists. mlist1 = create_list('*****@*****.**') mlist1.admin_immed_notify = False mlist2 = create_list('*****@*****.**') mlist2.admin_immed_notify = False mlist3 = create_list('*****@*****.**') mlist3.admin_immed_notify = False # Subscribe the addresses in random order # https://www.xkcd.com/221/ mlist3.subscribe(address_3, MemberRole.moderator) mlist3.subscribe(address_3, MemberRole.owner) mlist3.subscribe(address_3, MemberRole.member) mlist3.subscribe(address_2, MemberRole.member) mlist3.subscribe(address_2, MemberRole.owner) mlist3.subscribe(address_2, MemberRole.moderator) mlist3.subscribe(address, MemberRole.owner) mlist3.subscribe(address, MemberRole.member) mlist3.subscribe(address, MemberRole.moderator) mlist2.subscribe(address_2, MemberRole.moderator) mlist2.subscribe(address_2, MemberRole.member) mlist2.subscribe(address_2, MemberRole.owner) mlist2.subscribe(address_3, MemberRole.moderator) mlist2.subscribe(address_3, MemberRole.member) mlist2.subscribe(address_3, MemberRole.owner) mlist2.subscribe(address, MemberRole.owner) mlist2.subscribe(address, MemberRole.moderator) mlist2.subscribe(address, MemberRole.member) mlist1.subscribe(address_2, MemberRole.moderator) mlist1.subscribe(address, MemberRole.member) mlist1.subscribe(address_3, MemberRole.owner) # The results should be sorted first by list id, then by address, then # by member role. members = self._service.find_members(user.user_id) self.assertEqual(len(members), 21) self.assertListEqual( [(m.list_id.partition('.')[0], m.address.email.partition('@')[0], m.role) for m in members], [('test1', 'anne1', MemberRole.member), ('test1', 'anne2', MemberRole.moderator), ('test1', 'anne3', MemberRole.owner), ('test2', 'anne1', MemberRole.member), ('test2', 'anne1', MemberRole.owner), ('test2', 'anne1', MemberRole.moderator), ('test2', 'anne2', MemberRole.member), ('test2', 'anne2', MemberRole.owner), ('test2', 'anne2', MemberRole.moderator), ('test2', 'anne3', MemberRole.member), ('test2', 'anne3', MemberRole.owner), ('test2', 'anne3', MemberRole.moderator), ('test3', 'anne1', MemberRole.member), ('test3', 'anne1', MemberRole.owner), ('test3', 'anne1', MemberRole.moderator), ('test3', 'anne2', MemberRole.member), ('test3', 'anne2', MemberRole.owner), ('test3', 'anne2', MemberRole.moderator), ('test3', 'anne3', MemberRole.member), ('test3', 'anne3', MemberRole.owner), ('test3', 'anne3', MemberRole.moderator), ])