summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/mailman/docs/NEWS.rst2
-rw-r--r--src/mailman/rest/domains.py23
-rw-r--r--src/mailman/rest/tests/test_domains.py50
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(