Barry Warsaw pushed to branch master at mailman / Mailman
Commits: 9c9d0f01 by Aurélien Bompard at 2015-12-08T10:20:22Z Allow a Member's moderation_action to be changed by the REST API. Cleanups by Barry. Closes !67 - - - - - 5 changed files: - src/mailman/docs/NEWS.rst - src/mailman/rest/docs/addresses.rst - src/mailman/rest/docs/membership.rst - src/mailman/rest/members.py - src/mailman/rest/tests/test_membership.py Changes: ===================================== src/mailman/docs/NEWS.rst ===================================== --- a/src/mailman/docs/NEWS.rst +++ b/src/mailman/docs/NEWS.rst @@ -113,6 +113,8 @@ REST * JSON representations for held message now include a ``self_link``. * When ``[devmode]enabled`` is set, the JSON output is sorted. Given by Aurélien Bompard. + * A member's moderation action can be changed via the REST API. Given by + Aurélien Bompard. Other ----- ===================================== src/mailman/rest/docs/addresses.rst ===================================== --- a/src/mailman/rest/docs/addresses.rst +++ b/src/mailman/rest/docs/addresses.rst @@ -379,6 +379,7 @@ Elle can get her memberships for each of her email addresses. http_etag: "..." list_id: ant.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/4 @@ -389,6 +390,7 @@ Elle can get her memberships for each of her email addresses. http_etag: "..." list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/4 @@ -420,6 +422,7 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: ant.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/4 @@ -430,6 +433,7 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/4 @@ -446,6 +450,7 @@ does not show up in the list of memberships for his other address. http_etag: "..." list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/4 ===================================== src/mailman/rest/docs/membership.rst ===================================== --- a/src/mailman/rest/docs/membership.rst +++ b/src/mailman/rest/docs/membership.rst @@ -50,6 +50,7 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -66,6 +67,7 @@ Bart's specific membership can be accessed directly: http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -86,6 +88,7 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -96,6 +99,7 @@ the REST interface. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -119,6 +123,7 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -129,6 +134,7 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -139,6 +145,7 @@ subscribes, she is returned first. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -168,6 +175,7 @@ User ids are different than member ids. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -178,6 +186,7 @@ User ids are different than member ids. http_etag: ... list_id: ant.example.com member_id: 5 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -188,6 +197,7 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -198,6 +208,7 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -208,6 +219,7 @@ User ids are different than member ids. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -226,6 +238,7 @@ We can also get just the members of a single mailing list. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -236,6 +249,7 @@ We can also get just the members of a single mailing list. http_etag: ... list_id: ant.example.com member_id: 5 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -262,6 +276,7 @@ page. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -280,6 +295,7 @@ This works with members of a single list as well as with all members. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -326,6 +342,7 @@ mailing list. http_etag: ... list_id: ant.example.com member_id: 6 + moderation_action: accept role: moderator self_link: http://localhost:9001/3.0/members/6 user: http://localhost:9001/3.0/users/4 @@ -336,6 +353,7 @@ mailing list. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -346,6 +364,7 @@ mailing list. http_etag: ... list_id: ant.example.com member_id: 5 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -356,6 +375,7 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 7 + moderation_action: accept role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 @@ -366,6 +386,7 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -376,6 +397,7 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -386,6 +408,7 @@ mailing list. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -404,6 +427,7 @@ We can access all the owners of a list. http_etag: ... list_id: bee.example.com member_id: 7 + moderation_action: accept role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 @@ -425,6 +449,7 @@ A specific member can always be referenced by their role and address. http_etag: ... list_id: bee.example.com member_id: 7 + moderation_action: accept role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 @@ -442,6 +467,7 @@ example, we can search for all the memberships of a particular address. http_etag: ... list_id: ant.example.com member_id: 4 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/4 user: http://localhost:9001/3.0/users/3 @@ -452,6 +478,7 @@ example, we can search for all the memberships of a particular address. http_etag: ... list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -471,6 +498,7 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 3 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/3 user: http://localhost:9001/3.0/users/3 @@ -481,6 +509,7 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 1 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/1 user: http://localhost:9001/3.0/users/1 @@ -491,6 +520,7 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -501,6 +531,7 @@ Or, we can find all the memberships for a particular mailing list. http_etag: ... list_id: bee.example.com member_id: 7 + moderation_action: accept role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 @@ -522,6 +553,7 @@ list. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -532,6 +564,7 @@ list. http_etag: ... list_id: bee.example.com member_id: 7 + moderation_action: accept role: owner self_link: http://localhost:9001/3.0/members/7 user: http://localhost:9001/3.0/users/2 @@ -552,6 +585,7 @@ Or, we can find all the memberships for an address with a specific role. http_etag: ... list_id: ant.example.com member_id: 5 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/5 user: http://localhost:9001/3.0/users/2 @@ -562,6 +596,7 @@ Or, we can find all the memberships for an address with a specific role. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -583,6 +618,7 @@ Finally, we can search for a specific member given all three criteria. http_etag: ... list_id: bee.example.com member_id: 2 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/2 user: http://localhost:9001/3.0/users/2 @@ -636,6 +672,7 @@ Elly is now a known user, and a member of the mailing list. http_etag: ... list_id: ant.example.com member_id: 8 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/8 user: http://localhost:9001/3.0/users/5 @@ -682,6 +719,7 @@ list with her preferred address. http_etag: "..." list_id: ant.example.com member_id: 9 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/9 user: http://localhost:9001/3.0/users/6 @@ -707,6 +745,7 @@ the new address. http_etag: "..." list_id: ant.example.com member_id: 9 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/9 user: http://localhost:9001/3.0/users/6 @@ -774,6 +813,7 @@ addresses. http_etag: "..." list_id: ant.example.com member_id: 10 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/10 user: http://localhost:9001/3.0/users/7 @@ -785,6 +825,7 @@ addresses. http_etag: "..." list_id: bee.example.com member_id: 11 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/11 user: http://localhost:9001/3.0/users/7 @@ -843,6 +884,7 @@ his membership ids have not changed. http_etag: "..." list_id: ant.example.com member_id: 10 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/10 user: http://localhost:9001/3.0/users/7 @@ -853,9 +895,38 @@ his membership ids have not changed. http_etag: "..." list_id: bee.example.com member_id: 11 + moderation_action: defer role: member self_link: http://localhost:9001/3.0/members/11 user: http://localhost:9001/3.0/users/7 http_etag: "..." start: 0 total_size: 2 + + +Moderating a member +=================== + +The moderation action for a member can be changed by PATCH'ing the +`moderation_action` attribute. +:: + + >>> dump_json('http://localhost:9001/3.0/members/10') + address: http://localhost:9001/3.0/addresses/hper...@example.com + ... + moderation_action: defer + ... + + >>> dump_json('http://localhost:9001/3.0/members/10', { + ... 'moderation_action': 'hold', + ... }, method='PATCH') + content-length: 0 + date: ... + server: ... + status: 204 + + >>> dump_json('http://localhost:9001/3.0/members/10') + address: http://localhost:9001/3.0/addresses/hper...@example.com + ... + moderation_action: hold + ... ===================================== src/mailman/rest/members.py ===================================== --- a/src/mailman/rest/members.py +++ b/src/mailman/rest/members.py @@ -26,6 +26,7 @@ __all__ = [ from mailman.app.membership import add_member, delete_member +from mailman.interfaces.action import Action from mailman.interfaces.address import IAddress, InvalidEmailAddressError from mailman.interfaces.listmanager import IListManager from mailman.interfaces.member import ( @@ -62,13 +63,14 @@ class _MemberBase(CollectionMixin): # URL. member_id = member.member_id.int response = dict( - list_id=member.list_id, - email=member.address.email, - role=role, address=self.path_to('addresses/{}'.format(member.address.email)), - self_link=self.path_to('members/{}'.format(member_id)), delivery_mode=member.delivery_mode, + email=member.address.email, + list_id=member.list_id, member_id=member_id, + moderation_action=member.moderation_action, + role=role, + self_link=self.path_to('members/{}'.format(member_id)), ) # Add the user link if there is one. user = member.user @@ -178,7 +180,9 @@ class AMember(_MemberBase): values = Validator( address=str, delivery_mode=enum_validator(DeliveryMode), - _optional=('address', 'delivery_mode'))(request) + moderation_action=enum_validator(Action), + _optional=('address', 'delivery_mode', 'moderation_action'), + )(request) except ValueError as error: bad_request(response, str(error)) return @@ -195,6 +199,8 @@ class AMember(_MemberBase): return if 'delivery_mode' in values: self._member.preferences.delivery_mode = values['delivery_mode'] + if 'moderation_action' in values: + self._member.moderation_action = values['moderation_action'] no_content(response) ===================================== src/mailman/rest/tests/test_membership.py ===================================== --- a/src/mailman/rest/tests/test_membership.py +++ b/src/mailman/rest/tests/test_membership.py @@ -253,6 +253,19 @@ class TestMembership(unittest.TestCase): call_api('http://localhost:9001/3.0/members/1/all') self.assertEqual(cm.exception.code, 404) + def test_patch_member_invalid_moderation_action(self): + # /members/<id> PATCH with invalid 'moderation_action' returns 400. + with transaction(): + anne = self._usermanager.create_address('a...@example.com') + self._mlist.subscribe(anne) + with self.assertRaises(HTTPError) as cm: + call_api('http://localhost:9001/3.0/members/1', { + 'moderation_action': 'invalid', + }, method='PATCH') + self.assertEqual(cm.exception.code, 400) + self.assertEqual(cm.exception.reason, + b'Cannot convert parameters: moderation_action') + class CustomLayer(ConfigLayer): View it on GitLab: https://gitlab.com/mailman/mailman/commit/9c9d0f01f8f5dff5ec5a83b953be81edf81566be
_______________________________________________ Mailman-checkins mailing list Mailman-checkins@python.org Unsubscribe: https://mail.python.org/mailman/options/mailman-checkins/archive%40jab.org