Barry Warsaw pushed to branch master at mailman / Mailman
Commits:
d1954d17 by Mark Sapiro at 2016-10-20T17:44:25-07:00
First cut at PUT/PATCH for domain.
- - - - -
cbb0847d by Mark Sapiro at 2016-10-22T12:24:00-07:00
Merge gitlab.com:mailman/mailman
- - - - -
2e1bc9aa by Mark Sapiro at 2016-10-22T17:33:07-07:00
Fixed a bunch of things in PATCHing domains and added tests and NEWS.
- - - - -
3a198afc by Mark Sapiro at 2016-10-22T18:18:16-07:00
Merge gitlab.com:mailman/mailman
- - - - -
7c8b75fd by Mark Sapiro at 2016-10-23T18:37:07-07:00
Modify NEWS.rst entry to mention PUT.
- - - - -
3 changed files:
- src/mailman/docs/NEWS.rst
- src/mailman/rest/domains.py
- src/mailman/rest/tests/test_domains.py
Changes:
=====================================
src/mailman/docs/NEWS.rst
=====================================
--- a/src/mailman/docs/NEWS.rst
+++ b/src/mailman/docs/NEWS.rst
@@ -91,6 +91,8 @@ Bugs
* Allow MailingList.info to be set using the REST API. Given by Aurélien
Bompard.
* Extend header filters to also check sub-part headers. (Closes #280)
+ * Allow REST API to PUT and PATCH domain attributes. Allows Postorius domain
+ edit to work. (Closes: #290)
Configuration
-------------
=====================================
src/mailman/rest/domains.py
=====================================
--- 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
@@ -71,6 +71,32 @@ class ADomain(_DomainBase):
else:
no_content(response)
+ def patch_put(self, request, response, is_optional):
+ domain = getUtility(IDomainManager).get(self._domain)
+ if domain is None:
+ not_found(response)
+ 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(**kws).update(domain, request)
+ except ValueError as error:
+ bad_request(response, str(error))
+ else:
+ no_content(response)
+
+ def on_put(self, request, response):
+ """Update all the domain except mail_host"""
+ self.patch_put(request, response, is_optional=False)
+
+ def on_patch(self, request, response):
+ """Patch some domain attributes."""
+ self.patch_put(request, response, is_optional=True)
+
@child()
def lists(self, context, segments):
"""/domains/<domain>/lists"""
=====================================
src/mailman/rest/tests/test_domains.py
=====================================
--- 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': '[email protected]'}
+ 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],
+ ['[email protected]'])
+
+ def test_patch_domain_two_owners(self):
+ # Patch the example.com owner.
+ data = {'owner': ['[email protected]', '[email protected]']}
+ 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],
+ ['[email protected]', '[email protected]'])
+
+ 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(
View it on GitLab:
https://gitlab.com/mailman/mailman/compare/4cd3c3f309bb91d46a7ce55a32216db2321804c1...7c8b75fd1ab364871274397509cd6ce314197138
_______________________________________________
Mailman-checkins mailing list
[email protected]
Unsubscribe:
https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org