summaryrefslogtreecommitdiff
path: root/src/mailman/rest
diff options
context:
space:
mode:
Diffstat (limited to 'src/mailman/rest')
-rw-r--r--src/mailman/rest/addresses.py26
-rw-r--r--src/mailman/rest/tests/test_addresses.py19
2 files changed, 39 insertions, 6 deletions
diff --git a/src/mailman/rest/addresses.py b/src/mailman/rest/addresses.py
index 4624db379..8fc6871b5 100644
--- a/src/mailman/rest/addresses.py
+++ b/src/mailman/rest/addresses.py
@@ -192,30 +192,44 @@ class UserAddresses(_AddressBase):
user_manager = getUtility(IUserManager)
validator = Validator(email=str,
display_name=str,
- _optional=('display_name',))
+ force_existing=bool,
+ _optional=('display_name', 'force_existing'))
try:
- address = user_manager.create_address(**validator(request))
+ data = validator(request)
except ValueError as error:
bad_request(response, str(error))
+ return
+ force_existing = data.pop('force_existing', False)
+ try:
+ address = user_manager.create_address(**data)
except InvalidEmailAddressError:
bad_request(response, b'Invalid email address')
+ return
except ExistingAddressError:
# Check if the address is not linked to any user, link it to the
# current user and return it. Since we're linking to an existing
# address, ignore any given display_name attribute.
- address = user_manager.get_address(validator(request)['email'])
+ address = user_manager.get_address(data['email'])
if address.user is None:
address.user = self._user
location = self.api.path_to(
'addresses/{}'.format(address.email))
created(response, location)
+ return
else:
- bad_request(response, 'Address belongs to other user.')
+ if not force_existing:
+ bad_request(response, 'Address belongs to other user.')
+ return
+ else:
+ # The address exists and is linked but we can merge the
+ # users.
+ address = user_manager.get_address(data['email'])
+ self._user.absorb(address.user)
else:
# Link the address to the current user and return it.
address.user = self._user
- location = self.api.path_to('addresses/{}'.format(address.email))
- created(response, location)
+ location = self.api.path_to('addresses/{}'.format(address.email))
+ created(response, location)
def membership_key(member):
diff --git a/src/mailman/rest/tests/test_addresses.py b/src/mailman/rest/tests/test_addresses.py
index edcfdfa86..c75641ea9 100644
--- a/src/mailman/rest/tests/test_addresses.py
+++ b/src/mailman/rest/tests/test_addresses.py
@@ -212,6 +212,25 @@ class TestAddresses(unittest.TestCase):
anne_person = user_manager.get_address('anne@example.com')
self.assertEqual(anne_person.display_name, '')
+ def test_existing_address_absorb(self):
+ # Trying to add an existing address causes a merge if the
+ # 'force_existing' flag is present.
+ user_manager = getUtility(IUserManager)
+ with transaction():
+ anne = user_manager.create_user('anne@example.com')
+ bill = user_manager.create_user('bill@example.com')
+ response, content = call_api(
+ 'http://localhost:9001/3.0/users/anne@example.com/addresses', {
+ 'email': 'bill@example.com',
+ 'force_existing': '1',
+ })
+ self.assertIn('bill@example.com',
+ [addr.email for addr in anne.addresses])
+ self.assertEqual(content['status'], '201')
+ self.assertEqual(
+ content['location'],
+ 'http://localhost:9001/3.0/addresses/bill@example.com')
+
def test_invalid_address_bad_request(self):
# Trying to add an invalid address string returns 400.
with transaction():