From 8ceebf571ff24482c274623ee024eadc4afb5dec Mon Sep 17 00:00:00 2001 From: Pavel Raiskup Date: May 31 2022 18:19:50 +0000 Subject: frontend: restrict the CoprDir names to :custom: Non-"custom" directories are forbidden for now, pull-request directories can be created only by pagure-events.py, and parts (between colons) must be alphanumeric, non-empty strings. Relates: #2175 --- diff --git a/frontend/coprs_frontend/coprs/logic/coprs_logic.py b/frontend/coprs_frontend/coprs/logic/coprs_logic.py index 995d160..4785f22 100644 --- a/frontend/coprs_frontend/coprs/logic/coprs_logic.py +++ b/frontend/coprs_frontend/coprs/logic/coprs_logic.py @@ -567,7 +567,7 @@ class CoprDirsLogic(object): return coprdir @classmethod - def get_or_create(cls, copr, dirname): + def get_or_create(cls, copr, dirname, trusted_caller=False): """ Create a CoprDir on-demand, e.g. before pull-request builds is submitted. We don't create the "main" CoprDirs here (those are created @@ -583,6 +583,17 @@ class CoprDirsLogic(object): copr.name, )) + if not trusted_caller: + if not dirname.startswith(copr.name+":custom:"): + raise exceptions.BadRequest( + f"Please use directory format {copr.name}:custom:" + ) + + if not all(x.isalnum() for x in dirname.split(":")[1:]): + raise exceptions.BadRequest( + f"Wrong directory '{dirname}' specified. Directory name can " + "consist of alpha-numeric strings separated by colons.") + copr_dir = models.CoprDir(name=dirname, copr=copr, main=False) ActionsLogic.send_createrepo(copr, dirnames=[dirname]) db.session.add(copr_dir) diff --git a/frontend/coprs_frontend/pagure_events.py b/frontend/coprs_frontend/pagure_events.py index 06f3b5d..7cc86c6 100755 --- a/frontend/coprs_frontend/pagure_events.py +++ b/frontend/coprs_frontend/pagure_events.py @@ -259,7 +259,8 @@ class build_on_fedmsg_loop(): if event_info.object_type == 'pull-request': dirname = pkg.copr.name + ':pr:' + str(event_info.object_id) - copr_dir = CoprDirsLogic.get_or_create(pkg.copr, dirname) + copr_dir = CoprDirsLogic.get_or_create(pkg.copr, dirname, + trusted_caller=True) update_callback = 'pagure_flag_pull_request' scm_object_url = os.path.join(base_url, event_info.project_url_path, 'c', str(event_info.end_commit)) diff --git a/frontend/coprs_frontend/tests/test_apiv3/test_coprdirs.py b/frontend/coprs_frontend/tests/test_apiv3/test_coprdirs.py index e96b52b..fc6652a 100644 --- a/frontend/coprs_frontend/tests/test_apiv3/test_coprdirs.py +++ b/frontend/coprs_frontend/tests/test_apiv3/test_coprdirs.py @@ -81,3 +81,20 @@ class TestCoprDir(CoprsTestCase): assert latest_build["project_dirname"] == "test" latest_build = packages[1]["builds"]["latest"] assert latest_build["project_dirname"] == "test:custom:subdir" + + + @TransactionDecorator("u1") + @pytest.mark.usefixtures("f_users", "f_users_api", "f_coprs", "f_builds", + "f_mock_chroots", "f_other_distgit", "f_db") + def test_custom_dir_validation(self): + self.web_ui.new_project("test", ["fedora-rawhide-i386"]) + self.web_ui.create_distgit_package("test", "copr-cli") + # succeeds + assert self.api3.rebuild_package("test:custom:subdir", "copr-cli").status_code == 200 + assert self.api3.rebuild_package("test:custom:123", "copr-cli").status_code == 200 + assert self.api3.rebuild_package("test:custom:žluťoučký", "copr-cli").status_code == 200 + assert self.api3.rebuild_package("test:custom:", "copr-cli").status_code == 400 + assert self.api3.rebuild_package("test:custom:.", "copr-cli").status_code == 400 + assert self.api3.rebuild_package("test:custom:@", "copr-cli").status_code == 400 + # This can only be created by pagure-events.py code for now. + assert self.api3.rebuild_package("test:pr:13", "copr-cli").status_code == 400