diff options
| author | Mark Sapiro | 2016-10-22 17:33:07 -0700 |
|---|---|---|
| committer | Mark Sapiro | 2016-10-22 17:33:07 -0700 |
| commit | 2e1bc9aa297d108315fe588f2c1831d38a8963e5 (patch) | |
| tree | 6249ed9012ac40268738a6f187c95ae59236ebb0 | |
| parent | cbb0847d59fb8b77f634a7209b0dc8170023b6f5 (diff) | |
| download | mailman-2e1bc9aa297d108315fe588f2c1831d38a8963e5.tar.gz mailman-2e1bc9aa297d108315fe588f2c1831d38a8963e5.tar.zst mailman-2e1bc9aa297d108315fe588f2c1831d38a8963e5.zip | |
| -rw-r--r-- | src/mailman/docs/NEWS.rst | 2 | ||||
| -rw-r--r-- | src/mailman/rest/domains.py | 23 | ||||
| -rw-r--r-- | src/mailman/rest/tests/test_domains.py | 50 |
3 files changed, 60 insertions, 15 deletions
diff --git a/src/mailman/docs/NEWS.rst b/src/mailman/docs/NEWS.rst index ee8e1c09b..ea75e0f4d 100644 --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -90,6 +90,8 @@ Bugs Aurélien Bompard. (Closes: #273) * Allow MailingList.info to be set using the REST API. Given by Aurélien Bompard. + * Allow REST API to PATCH some domain attributes. Enables Postorius domain + edit to work. (Closes: #290) Configuration ------------- diff --git a/src/mailman/rest/domains.py b/src/mailman/rest/domains.py index 931b34775..c6b8daa7c 100644 --- a/src/mailman/rest/domains.py +++ b/src/mailman/rest/domains.py @@ -21,11 +21,11 @@ from mailman import public from mailman.interfaces.domain import ( BadDomainSpecificationError, IDomainManager) from mailman.rest.helpers import ( - BadRequest, CollectionMixin, NotFound, bad_request, child, created, etag, - no_content, not_found, okay) + BadRequest, CollectionMixin, GetterSetter, NotFound, bad_request, child, + created, etag, no_content, not_found, okay) from mailman.rest.lists import ListsForDomain from mailman.rest.uris import ADomainURI, AllDomainURIs -from mailman.rest.users import OwnersForDomain +from mailman.rest.users import ListOfDomainOwners, OwnersForDomain from mailman.rest.validator import Validator, list_of_strings_validator from zope.component import getUtility @@ -75,25 +75,18 @@ class ADomain(_DomainBase): domain = getUtility(IDomainManager).get(self._domain) if domain is None: not_found(response) - kws = {'mail_host': str, - 'description': str, - 'owner': list_of_strings_validator, - 'mailing_lists': list_of_strings_validator} + kws = dict( + description=GetterSetter(str), + owner=ListOfDomainOwners(list_of_strings_validator), + ) if is_optional: # For a PATCH, all attributes are optional. kws['_optional'] = kws.keys() try: - validator = Validator(**kws) - values = validator(request) + Validator(**kws).update(domain, request) except ValueError as error: bad_request(response, str(error)) - if ('email_host' in values and - values['email_host'] != domain.email_host): - reason = "PATCH/PUT can't change email_host" - bad_request(response, reason.encode('utf-8')) else: - for k, v in values.items(): - setattr(domain, k, v) no_content(response) def on_put(self, request, response): diff --git a/src/mailman/rest/tests/test_domains.py b/src/mailman/rest/tests/test_domains.py index c707eaadb..5daa1ccf7 100644 --- a/src/mailman/rest/tests/test_domains.py +++ b/src/mailman/rest/tests/test_domains.py @@ -48,6 +48,56 @@ class TestDomains(unittest.TestCase): 'http://localhost:9001/3.0/domains', data, method="POST") self.assertEqual(response.status, 201) + def test_patch_domain_description(self): + # Patch the example.com description. + data = {'description': 'Patched example domain'} + content, response = call_api( + 'http://localhost:9001/3.0/domains/example.com', + data, + method='PATCH') + self.assertEqual(response.status, 204) + # Check the result. + domain = getUtility(IDomainManager).get('example.com') + self.assertEqual(domain.description, 'Patched example domain') + + def test_patch_domain_owner(self): + # Patch the example.com owner. + data = {'owner': 'anne@example.com'} + content, response = call_api( + 'http://localhost:9001/3.0/domains/example.com', + data, + method='PATCH') + self.assertEqual(response.status, 204) + # Check the result. + domain = getUtility(IDomainManager).get('example.com') + self.assertEqual( + [list(owner.addresses)[0].email for owner in domain.owners], + ['anne@example.com']) + + def test_patch_domain_two_owners(self): + # Patch the example.com owner. + data = {'owner': ['anne@example.com', 'other@example.net']} + content, response = call_api( + 'http://localhost:9001/3.0/domains/example.com', + data, + method='PATCH') + self.assertEqual(response.status, 204) + # Check the result. + domain = getUtility(IDomainManager).get('example.com') + self.assertEqual( + [list(owner.addresses)[0].email for owner in domain.owners], + ['anne@example.com', 'other@example.net']) + + def test_patch_domain_readonly(self): + # Attempt to patch mail_host. + data = {'mail_host': 'example.net'} + with self.assertRaises(HTTPError) as cm: + call_api( + 'http://localhost:9001/3.0/domains/example.com', + data, + method='PATCH') + self.assertEqual(cm.exception.code, 400) + def test_domain_create_with_single_owner(self): # Creating domain with single owner should not raise InvalidEmailError. content, response = call_api( |
