[PATCH 2/3] xmlrpc: Allow a project to restrict submitter state changes
Daniel Axtens
dja at axtens.net
Tue Aug 3 01:27:28 AEST 2021
As with the UI.
Signed-off-by: Daniel Axtens <dja at axtens.net>
---
patchwork/tests/test_xmlrpc.py | 90 ++++++++++++++++++++++++++++++++++
patchwork/views/xmlrpc.py | 4 ++
2 files changed, 94 insertions(+)
diff --git a/patchwork/tests/test_xmlrpc.py b/patchwork/tests/test_xmlrpc.py
index 4726fdffa5d5..eea0b4eaf560 100644
--- a/patchwork/tests/test_xmlrpc.py
+++ b/patchwork/tests/test_xmlrpc.py
@@ -10,6 +10,9 @@ from django.conf import settings
from django.test import LiveServerTestCase
from django.urls import reverse
+from patchwork.models import Person
+from patchwork.models import Project
+from patchwork.models import State
from patchwork.tests import utils
@@ -81,6 +84,93 @@ class XMLRPCAuthenticatedTest(LiveServerTestCase):
self.assertTrue(result['archived'])
+ at unittest.skipUnless(settings.ENABLE_XMLRPC,
+ 'requires xmlrpc interface (use the ENABLE_XMLRPC '
+ 'setting)')
+class XMLRPCStateSettingTest(LiveServerTestCase):
+
+ def url_for_user(self, user):
+ return ('http://%s:%s@' + self.url[7:]) % \
+ (user.username, user.username)
+
+ def setUp(self):
+ self.url = self.live_server_url + reverse('xmlrpc')
+ # url is of the form http://localhost:PORT/PATH
+ # strip the http and replace it with the username/passwd of a user.
+ self.projects = {}
+ self.maintainers = {}
+ self.delegates = {}
+ self.submitters = {}
+ self.patches = {}
+ self.rpcs = {}
+
+ for project_type in (Project.SUBMITTER_NO_STATE_CHANGES,
+ Project.SUBMITTER_ALL_STATE_CHANGES):
+ project = utils.create_project(
+ submitter_state_change_rules=project_type)
+ self.projects[project_type] = project
+ self.maintainers[project_type] = utils.create_maintainer(project)
+ submitter = utils.create_user(project)
+ self.submitters[project_type] = submitter
+ delegate = utils.create_user(project)
+ self.delegates[project_type] = delegate
+
+ self.rpcs[project_type] = {
+ 'maintainer': ServerProxy(self.url_for_user(
+ self.maintainers[project_type])),
+ 'delegate': ServerProxy(self.url_for_user(delegate)),
+ 'submitter': ServerProxy(self.url_for_user(submitter)),
+ }
+
+ patch = utils.create_patch(project=project,
+ submitter=Person.objects.get(
+ user=submitter),
+ delegate=delegate)
+ self.patches[project_type] = patch
+
+ utils.create_state(name="New")
+ utils.create_state(name="RFC")
+
+ def tearDown(self):
+ for project_type in self.rpcs:
+ rpc_dict = self.rpcs[project_type]
+ for user in rpc_dict:
+ rpc_dict[user].close()
+
+ def can_set_state(self, patch, rpc):
+ new_state = State.objects.get(name="New")
+ rfc_state = State.objects.get(name="RFC")
+ patch.state = new_state
+ patch.save()
+
+ result = rpc.patch_get(patch.id)
+ self.assertEqual(result['state_id'], new_state.id)
+
+ try:
+ rpc.patch_set(patch.id, {'state': rfc_state.id})
+ except xmlrpc_client.Fault:
+ return False
+
+ # reload the patch
+ result = rpc.patch_get(patch.id)
+ self.assertEqual(result['state_id'], rfc_state.id)
+ return True
+
+ def test_allset(self):
+ rpc_dict = self.rpcs[Project.SUBMITTER_ALL_STATE_CHANGES]
+ patch = self.patches[Project.SUBMITTER_ALL_STATE_CHANGES]
+ self.assertTrue(self.can_set_state(patch, rpc_dict['maintainer']))
+ self.assertTrue(self.can_set_state(patch, rpc_dict['delegate']))
+ self.assertTrue(self.can_set_state(patch, rpc_dict['submitter']))
+
+ def test_noset(self):
+ rpc_dict = self.rpcs[Project.SUBMITTER_NO_STATE_CHANGES]
+ patch = self.patches[Project.SUBMITTER_NO_STATE_CHANGES]
+ self.assertTrue(self.can_set_state(patch, rpc_dict['maintainer']))
+ self.assertTrue(self.can_set_state(patch, rpc_dict['delegate']))
+ self.assertFalse(self.can_set_state(patch, rpc_dict['submitter']))
+
+
class XMLRPCModelTestMixin(object):
def create_multiple(self, count):
diff --git a/patchwork/views/xmlrpc.py b/patchwork/views/xmlrpc.py
index 6701bf20f386..d73cfa7a8441 100644
--- a/patchwork/views/xmlrpc.py
+++ b/patchwork/views/xmlrpc.py
@@ -713,6 +713,10 @@ def patch_set(user, patch_id, params):
if not patch.is_editable(user):
raise Exception('No permissions to edit this patch')
+ if 'state' in params:
+ if not patch.can_set_state(user):
+ raise Exception('No permissions to set patch state')
+
for (k, v) in params.items():
if k not in ok_params:
continue
--
2.30.2
More information about the Patchwork
mailing list