From f5c2d6acf1d04984ce91f7132915966bca527f64 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: May 21 2026 08:57:04 +0000 Subject: [PATCH 1/3] Verify permissions on session-based logged-in users using the API Signed-off-by: Aurélien Bompard --- diff --git a/pagure/api/plugins.py b/pagure/api/plugins.py index 51aa916..8ec010a 100644 --- a/pagure/api/plugins.py +++ b/pagure/api/plugins.py @@ -25,7 +25,12 @@ from pagure.api import ( api_login_required, api_method, ) -from pagure.api.utils import _check_plugin, _check_token, _get_repo +from pagure.api.utils import ( + _check_plugin, + _check_token, + _get_repo, + check_repo_permissions, +) _log = logging.getLogger(__name__) @@ -58,6 +63,7 @@ def _filter_fields(plugin): "/fork////settings//install", methods=["POST"], ) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_install_plugin(repo, plugin, username=None, namespace=None): @@ -165,6 +171,7 @@ def api_install_plugin(repo, plugin, username=None, namespace=None): "/fork////settings//remove", methods=["POST"], ) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_remove_plugin(repo, plugin, username=None, namespace=None): diff --git a/pagure/api/project.py b/pagure/api/project.py index 78ffa4f..769e56a 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -40,7 +40,12 @@ from pagure.api import ( get_per_page, get_request_data, ) -from pagure.api.utils import _check_token, _get_project_tag, _get_repo +from pagure.api.utils import ( + _check_token, + _get_project_tag, + _get_repo, + check_repo_permissions, +) from pagure.config import config as pagure_config _log = logging.getLogger(__name__) @@ -153,6 +158,7 @@ def api_project_tag_view(repo, tag, username=None, namespace=None): @API.route("///tags/new", methods=["POST"]) @API.route("/fork///tags/new", methods=["POST"]) @API.route("/fork////tags/new", methods=["POST"]) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_project_tags_new(repo, username=None, namespace=None): @@ -236,6 +242,7 @@ def api_project_tags_new(repo, username=None, namespace=None): @API.route("///tag/", methods=["DELETE"]) @API.route("/fork///tag/", methods=["DELETE"]) @API.route("/fork////tag/", methods=["DELETE"]) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_project_tag_delete(repo, tag, username=None, namespace=None): @@ -354,6 +361,7 @@ def api_git_tags(repo, username=None, namespace=None): @API.route("///git/tags", methods=["POST"]) @API.route("/fork///git/tags", methods=["POST"]) @API.route("/fork////git/tags", methods=["POST"]) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project", "tag_project"]) @api_method def api_new_git_tags(repo, username=None, namespace=None): @@ -710,6 +718,7 @@ def api_git_branches(repo, username=None, namespace=None): @API.route( "/fork////git/branches", methods=["POST"] ) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_set_git_default_branch(repo, username=None, namespace=None): @@ -1790,6 +1799,7 @@ def api_fork_project(): @API.route("///git/branch", methods=["POST"]) @API.route("/fork///git/branch", methods=["POST"]) @API.route("/fork////git/branch", methods=["POST"]) +@check_repo_permissions("committer") @api_login_required(acls=["create_branch"]) @api_method def api_new_branch(repo, username=None, namespace=None): @@ -1879,6 +1889,7 @@ def api_new_branch(repo, username=None, namespace=None): @API.route( "/fork////git/alias/drop", methods=["POST"] ) +@check_repo_permissions("admin") @api_login_required( acls=["delete_git_alias", "modify_git_alias", "modify_project"] ) @@ -1968,6 +1979,7 @@ def api_drop_git_alias(repo, username=None, namespace=None): @API.route( "/fork////git/alias/new", methods=["POST"] ) +@check_repo_permissions("admin") @api_login_required( acls=["create_git_alias", "modify_git_alias", "modify_project"] ) @@ -2758,6 +2770,7 @@ def api_modify_acls(repo, namespace=None, username=None): @API.route("///options", methods=["GET"]) @API.route("/fork///options", methods=["GET"]) @API.route("/fork////options", methods=["GET"]) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_get_project_options(repo, username=None, namespace=None): @@ -2961,6 +2974,7 @@ def _check_value(value): @API.route( "/fork////options/update", methods=["POST"] ) +@check_repo_permissions("admin") @api_login_required(acls=["modify_project"]) @api_method def api_modify_project_options(repo, username=None, namespace=None): diff --git a/pagure/api/utils.py b/pagure/api/utils.py index 924f03e..4eca3f4 100644 --- a/pagure/api/utils.py +++ b/pagure/api/utils.py @@ -11,6 +11,7 @@ from __future__ import absolute_import, print_function, unicode_literals import logging +from functools import wraps import flask @@ -18,7 +19,13 @@ import pagure.exceptions from pagure.api import APIERROR, get_authorized_api_project from pagure.config import config as pagure_config from pagure.lib import plugins -from pagure.utils import api_authenticated, is_repo_committer, is_repo_user +from pagure.utils import ( + api_authenticated, + authenticated, + is_repo_admin, + is_repo_committer, + is_repo_user, +) _log = logging.getLogger(__name__) @@ -60,6 +67,66 @@ def _check_token(repo, project_token=True): ) +def check_repo_permissions(permission, is_api=True): + """Check that the logged-in user has sufficient permissions.""" + + def _decorator(function): + @wraps(function) + def _wrapper(*args, **kwargs): + # return function(*args, **kwargs) # abompard TESTING + # print(authenticated(), getattr(flask.g, "fas_user", None)) + if not authenticated(): + return function(*args, **kwargs) + if is_api: + # Check if there is a `repo` and an `username` + repo_name = flask.request.view_args.get("repo") + username = flask.request.view_args.get("username") + namespace = flask.request.view_args.get("namespace") + if not repo_name: + raise TypeError( + "This decorator can only be set on repo-based views" + ) + # This sets flask.g.repo, and we use it below + get_authorized_api_project( + flask.g.session, + repo_name, + user=username, + namespace=namespace, + ) + if permission == "committer": + checking_func = is_repo_committer + elif permission == "admin": + checking_func = is_repo_admin + else: + raise ValueError(f"unknown permission: {permission}") + if not flask.g.repo or checking_func( + flask.g.repo, flask.g.fas_user.username + ): + return function(*args, **kwargs) + if is_api: + return ( + flask.jsonify( + { + "error": APIERROR.ENOTHIGHENOUGH.value, + "error_code": APIERROR.ENOTHIGHENOUGH.name, + } + ), + 403, + ) + else: + flask.abort( + 403, + description=( + "You don't have sufficient permissions " + "on this project" + ), + ) + + return _wrapper + + return _decorator + + def _get_issue(repo, issueid, issueuid=None): """Get issue and check permissions :param repo: repository name diff --git a/tests/__init__.py b/tests/__init__.py index 24fd97e..22e0af9 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -254,6 +254,21 @@ def create_user(session, username, fullname, emails): item = pagure.lib.model.UserEmail(user_id=user.id, email=email) session.add(item) session.commit() + return user + + +def add_user_to_project(session, repo, access): + project = pagure.lib.query._get_project(session, repo) + username = f"{access}_user" + create_user(session, username, username, [f"{username}@example.com"]) + pagure.lib.query.add_user_to_project( + session, + project, + username, + "pingou", + access=access, + ) + return FakeUser(username=username) def _populate_db(session): diff --git a/tests/test_pagure_flask_api_fork_update.py b/tests/test_pagure_flask_api_fork_update.py index 77c57f4..24e0143 100644 --- a/tests/test_pagure_flask_api_fork_update.py +++ b/tests/test_pagure_flask_api_fork_update.py @@ -980,22 +980,24 @@ class PagureFlaskApiForkUpdateNoCommitterTests(tests.SimplePagureTest): def test_api_pull_request_not_updated_by_other_user(self): """No repo committers or PR owners are allowed to update PR.""" - headers = {"Authorization": "token aaabbbcccddd"} - data = { "title": "edited test PR", "initial_comment": "Edited initial comment", } - tests.create_user(self.session, "other", "Another User", ["au@rh.com"]) - user = tests.FakeUser() - user.username = "other" - with tests.user_set(self.app.application, user): - output = self.app.post( - "/api/0/test/pull-request/1", data=data, headers=headers - ) + user = tests.create_user( + self.session, "other", "Another User", ["au@rh.com"] + ) + tests.create_tokens(self.session, user_id=user.id, suffix="-other") + token_other = "aaabbbcccddd-other" + tests.create_tokens_acl(self.session, token_id=token_other) + headers = {"Authorization": f"token {token_other}"} - self.assertEqual(output.status_code, 403) + output = self.app.post( + "/api/0/test/pull-request/1", data=data, headers=headers + ) + + self.assertEqual(output.status_code, 403) if __name__ == "__main__": diff --git a/tests/test_pagure_flask_api_plugins_install.py b/tests/test_pagure_flask_api_plugins_install.py index 836bf92..3f14799 100644 --- a/tests/test_pagure_flask_api_plugins_install.py +++ b/tests/test_pagure_flask_api_plugins_install.py @@ -184,6 +184,26 @@ class PagureFlaskApiPluginInstalltests(tests.Modeltests): ) self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"]) + @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) + def test_install_plugin_cookie_login_no_access(self): + """Test installing a new plugin on a project with a logged-in user.""" + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.post( + "/api/0/test/settings/Mail/install", + data={"mail_to": "serg@wh40k.com"}, + ) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/tests/test_pagure_flask_api_plugins_remove.py b/tests/test_pagure_flask_api_plugins_remove.py index 9064c3a..9a42be2 100644 --- a/tests/test_pagure_flask_api_plugins_remove.py +++ b/tests/test_pagure_flask_api_plugins_remove.py @@ -184,6 +184,25 @@ class PagureFlaskApiPluginRemovetests(tests.Modeltests): ) self.assertEqual(pagure.api.APIERROR.EINVALIDTOK.value, data["error"]) + @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) + def test_remove_plugin_project_cookie_login_no_access(self): + """Test removing a plugin from a project with a regular + project-specific token. + """ + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.post("/api/0/test/settings/Mail/remove") + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + if __name__ == "__main__": unittest.main(verbosity=2) diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 47e6026..118edc3 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -2626,6 +2626,32 @@ class PagureFlaskApiProjecttests(tests.Modeltests): self.assertEqual(data, expected_output) self.assertIn("test123", repo_obj.listall_branches()) + def test_api_new_git_branch_cookie_login_no_access(self): + """Test the api_new_branch method of the flask api""" + tests.create_projects(self.session) + repo_path = os.path.join(self.path, "repos") + tests.create_projects_git(repo_path, bare=True) + tests.add_content_git_repo(os.path.join(repo_path, "test.git")) + + user = tests.add_user_to_project(self.session, "test", "ticket") + with tests.user_set(self.app.application, user): + output = self.app.post( + "/api/0/test/git/branch", data={"branch": "test123"} + ) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + git_path = os.path.join(self.path, "repos", "test.git") + repo_obj = pygit2.Repository(git_path) + self.assertNotIn("test123", repo_obj.listall_branches()) + class PagureFlaskApiProjectFlagtests(tests.Modeltests): """Tests for the flask API of pagure for flagging commit in project""" @@ -4131,6 +4157,23 @@ class PagureFlaskApiProjectOptionsTests(tests.Modeltests): }, ) + def test_api_get_project_options_cookie_login_no_access(self): + """Test accessing api_get_project_options as a logged-in user.""" + + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.get("/api/0/test/options") + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + def test_api_get_project_options_w_header(self): """Test accessing api_get_project_options w/ auth header.""" @@ -4427,6 +4470,35 @@ class PagureFlaskApiProjectOptionsTests(tests.Modeltests): before["settings"]["issue_tracker"] = False self.assertEqual(after, before) + def test_api_modify_project_options_cookie_login_no_access(self): + """Test accessing api_modify_project_options w/ auth header.""" + # check before + admin_headers = {"Authorization": "token aaabbbcccddd"} + output = self.app.get("/api/0/test/options", headers=admin_headers) + self.assertEqual(output.status_code, 200) + before = json.loads(output.get_data(as_text=True)) + + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + data = {"issues_default_to_private": True} + output = self.app.post("/api/0/test/options/update", data=data) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + + # check after + output = self.app.get("/api/0/test/options", headers=admin_headers) + self.assertEqual(output.status_code, 200) + after = json.loads(output.get_data(as_text=True)) + self.assertEqual(after, before) + class PagureFlaskApiProjectCreateAPITokenTests(tests.Modeltests): """Tests for the flask API of pagure for creating user project API token""" @@ -5145,6 +5217,25 @@ class PagureFlaskApiProjectGitBranchestests(tests.Modeltests): }, ) + def test_api_set_git_default_branch_cookie_login(self): + """Test the api_git_branches method of the flask api when logged in.""" + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.post( + "/api/0/test/git/branches", + data={"branch_name": "pats-win-49"}, + ) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + class PagureFlaskApiProjectCreateProjectTests(tests.Modeltests): """Tests for the flask API of pagure for git branches""" diff --git a/tests/test_pagure_flask_api_project_git_alias.py b/tests/test_pagure_flask_api_project_git_alias.py index 43f1b3e..c812890 100644 --- a/tests/test_pagure_flask_api_project_git_alias.py +++ b/tests/test_pagure_flask_api_project_git_alias.py @@ -176,6 +176,28 @@ class PagureFlaskApiProjectGitAliastests(tests.SimplePagureTest): }, ) + def test_api_new_git_alias_cookie_login_no_access(self): + user = tests.add_user_to_project(self.session, "test", "commit") + data = json.dumps({"alias_from": "main", "alias_to": "master"}) + headers = { + "Content-Type": "application/json", + } + with tests.user_set(self.app.application, user): + output = self.app.post( + "/api/0/test/git/alias/new", headers=headers, data=data + ) + + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + def test_api_new_git_alias(self): data = json.dumps({"alias_from": "main", "alias_to": "master"}) headers = { @@ -270,6 +292,27 @@ class PagureFlaskApiProjectGitAliastests(tests.SimplePagureTest): }, ) + def test_api_drop_git_alias_cookie_login_no_access(self): + user = tests.add_user_to_project(self.session, "test", "commit") + data = json.dumps({"alias_from": "main", "alias_to": "master"}) + headers = { + "Content-Type": "application/json", + } + with tests.user_set(self.app.application, user): + output = self.app.post( + "/api/0/test/git/alias/drop", headers=headers, data=data + ) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + def test_api_drop_git_alias(self): data = json.dumps({"alias_from": "main", "alias_to": "master"}) headers = { diff --git a/tests/test_pagure_flask_api_project_git_tags.py b/tests/test_pagure_flask_api_project_git_tags.py index b7c3a17..d61dcfa 100644 --- a/tests/test_pagure_flask_api_project_git_tags.py +++ b/tests/test_pagure_flask_api_project_git_tags.py @@ -363,3 +363,26 @@ class PagureFlaskApiProjectGitTagstests(tests.Modeltests): ) self.assertEqual(data["total_tags"], 1) self.assertEqual(data["tag_created"], True) + + def test_api_new_git_tag_user_no_access_cookie_login(self): + """Test the api_new_git_tags function.""" + user = tests.add_user_to_project(self.session, "test", "commit") + repo = pygit2.Repository(os.path.join(self.path, "repos", "test.git")) + latest_commit = repo.revparse_single("HEAD") + data = { + "tagname": "test-tag-no-message", + "commit_hash": latest_commit.oid.hex, + "message": "test message", + } + with tests.user_set(self.app.application, user): + output = self.app.post("/api/0/test/git/tags", data=data) + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) diff --git a/tests/test_pagure_flask_api_project_tags.py b/tests/test_pagure_flask_api_project_tags.py index 64a4a9d..252afa6 100644 --- a/tests/test_pagure_flask_api_project_tags.py +++ b/tests/test_pagure_flask_api_project_tags.py @@ -126,6 +126,25 @@ class PagureFlaskApiProjectTagstests(tests.Modeltests): data = json.loads(output.get_data(as_text=True)) self.assertDictEqual(data, expected_rv) + def test_api_project_tags_new_cookie_login_no_access(self): + """Test the api_tags_new method of the flask api.""" + tests.create_projects(self.session) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session, acl_name="create_project") + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.post("/api/0/test/tags/new") + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + def test_api_project_tags_new_no_input(self): """Test the api_tags_new method of the flask api.""" tests.create_projects(self.session) @@ -237,6 +256,25 @@ class PagureFlaskApiProjectTagstests(tests.Modeltests): data = json.loads(output.get_data(as_text=True)) self.assertDictEqual(data, expected_rv) + def test_api_project_tag_delete_cookie_login_no_access(self): + """Test the api_project_tag_delete method of flask api.""" + tests.create_projects(self.session) + tests.create_tokens(self.session) + tests.create_tokens_acl(self.session) + user = tests.add_user_to_project(self.session, "test", "commit") + with tests.user_set(self.app.application, user): + output = self.app.delete("/api/0/test/tag/blue") + print(output.get_data(as_text=True)) + self.assertEqual(output.status_code, 403) + data = json.loads(output.get_data(as_text=True)) + self.assertDictEqual( + data, + { + "error": "You do not have sufficient permissions to perform this action", + "error_code": "ENOTHIGHENOUGH", + }, + ) + def test_api_project_tag_delete_wrong_project(self): """Test the api_project_tag_delete method of flask api.""" tests.create_projects(self.session) From 27ecb1a02a4c760ea3b6e14f9b3ad196d8472ae0 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: May 21 2026 08:58:10 +0000 Subject: [PATCH 2/3] Specify the version of python in hooks This is useful when `/usr/bin/python` does not exist or is not a link to `python3`. Signed-off-by: Aurélien Bompard --- diff --git a/pagure/hooks/files/git_multimail_upstream.py b/pagure/hooks/files/git_multimail_upstream.py index 14b8911..0baf3b2 100755 --- a/pagure/hooks/files/git_multimail_upstream.py +++ b/pagure/hooks/files/git_multimail_upstream.py @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 __version__ = "1.4.0" diff --git a/pagure/hooks/files/hookrunner b/pagure/hooks/files/hookrunner index e1690d0..248e9c8 100755 --- a/pagure/hooks/files/hookrunner +++ b/pagure/hooks/files/hookrunner @@ -1,4 +1,4 @@ -#!/usr/bin/env python +#!/usr/bin/env python3 # -*- coding: utf-8 -*- """ From 8e4ae758f83483c26b78a66633e04cd4494ccf04 Mon Sep 17 00:00:00 2001 From: Aurélien Bompard Date: May 21 2026 08:58:49 +0000 Subject: [PATCH 3/3] Minor formatting changes Signed-off-by: Aurélien Bompard --- diff --git a/pagure/api/plugins.py b/pagure/api/plugins.py index 8ec010a..5c2be24 100644 --- a/pagure/api/plugins.py +++ b/pagure/api/plugins.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """ - (c) 2019 - Copyright Red Hat Inc +(c) 2019 - Copyright Red Hat Inc - Authors: - Michal Konecny +Authors: + Michal Konecny """ diff --git a/pagure/api/project.py b/pagure/api/project.py index 769e56a..8cce4cd 100644 --- a/pagure/api/project.py +++ b/pagure/api/project.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """ - (c) 2015-2019 - Copyright Red Hat Inc +(c) 2015-2019 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ diff --git a/pagure/api/utils.py b/pagure/api/utils.py index 4eca3f4..2ebd9c6 100644 --- a/pagure/api/utils.py +++ b/pagure/api/utils.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """ - (c) 2015-2019 - Copyright Red Hat Inc +(c) 2015-2019 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ diff --git a/pagure/utils.py b/pagure/utils.py index 31a5bef..15eabfc 100644 --- a/pagure/utils.py +++ b/pagure/utils.py @@ -1,10 +1,10 @@ # -*- coding: utf-8 -*- """ - (c) 2017-2020 - Copyright Red Hat Inc +(c) 2017-2020 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ @@ -912,7 +912,7 @@ def parse_path(path): # objid is the item after objtype, we need all items up to it items = items[: items.index(objtype) + 2] # now strip the repo, objtype and objid off the end - (repo, objtype, objid) = items[-3:] + repo, objtype, objid = items[-3:] items = items[:-3] except (IndexError, ValueError): raise PagureException( @@ -941,7 +941,7 @@ def parse_path(path): def check_user_required_groups(user_obj, path, required_groups=None): - """Check if a user's groups are in the required groups for the specified path.""" + """Check if a user's groups are in the required groups for the path.""" if not required_groups: return for key in required_groups: diff --git a/tests/__init__.py b/tests/__init__.py index 22e0af9..76ef983 100644 --- a/tests/__init__.py +++ b/tests/__init__.py @@ -1,14 +1,14 @@ # -*- coding: utf-8 -*- """ - (c) 2015-2018 - Copyright Red Hat Inc +(c) 2015-2018 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import importlib import json @@ -22,28 +22,23 @@ import sys import tempfile import time import unittest -from io import open, StringIO +from io import StringIO, open logging.basicConfig(stream=sys.stderr) -from bs4 import BeautifulSoup from contextlib import contextmanager -from datetime import date -from datetime import datetime -from datetime import timedelta +from datetime import date, datetime, timedelta from functools import wraps -from six.moves.urllib.parse import urlparse, parse_qs import mock import pygit2 import redis import six - from bs4 import BeautifulSoup from celery.app.task import EagerResult +from six.moves.urllib.parse import parse_qs, urlparse from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.orm import scoped_session +from sqlalchemy.orm import scoped_session, sessionmaker if six.PY2: # Always enable performance counting for tests @@ -55,7 +50,6 @@ sys.path.insert( import pagure import pagure.api -from pagure.api.ci import jenkins import pagure.flask_app import pagure.lib.git import pagure.lib.login @@ -63,7 +57,9 @@ import pagure.lib.model import pagure.lib.query import pagure.lib.tasks_mirror import pagure.perfrepo as perfrepo -from pagure.config import config as pagure_config, reload_config +from pagure.api.ci import jenkins +from pagure.config import config as pagure_config +from pagure.config import reload_config from pagure.lib.repo import PagureRepo HERE = os.path.join(os.path.dirname(os.path.abspath(__file__))) diff --git a/tests/test_pagure_flask_api_fork.py b/tests/test_pagure_flask_api_fork.py index 456942d..caa0f3c 100644 --- a/tests/test_pagure_flask_api_fork.py +++ b/tests/test_pagure_flask_api_fork.py @@ -1,30 +1,30 @@ # -*- coding: utf-8 -*- """ - (c) 2015 - Copyright Red Hat Inc +(c) 2015 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import datetime -import unittest +import json +import os import shutil import sys -import os +import unittest -import json -from mock import patch, MagicMock +from mock import MagicMock, patch sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") ) -import pagure.lib.query import pagure.default_config +import pagure.lib.query import tests @@ -2619,7 +2619,8 @@ class PagureFlaskApiForktests(tests.Modeltests): with tests.user_set(self.app.application, user): data = {"status": True} output = self.app.post( - "/api/0/test/pull-request/1/subscribe", data=data + "/api/0/test/pull-request/1/subscribe", + data=data, ) self.assertEqual(output.status_code, 200) data = json.loads(output.get_data(as_text=True)) diff --git a/tests/test_pagure_flask_api_fork_update.py b/tests/test_pagure_flask_api_fork_update.py index 24e0143..deefc47 100644 --- a/tests/test_pagure_flask_api_fork_update.py +++ b/tests/test_pagure_flask_api_fork_update.py @@ -1,28 +1,28 @@ # -*- coding: utf-8 -*- """ - (c) 2019 - Copyright Red Hat Inc +(c) 2019 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals -import arrow import copy import datetime -import unittest +import json +import os import shutil import sys import time -import os +import unittest +import arrow import flask -import json import munch -from mock import patch, MagicMock +from mock import MagicMock, patch from sqlalchemy.exc import SQLAlchemyError sys.path.insert( diff --git a/tests/test_pagure_flask_api_issue.py b/tests/test_pagure_flask_api_issue.py index 5ee8c46..af10736 100644 --- a/tests/test_pagure_flask_api_issue.py +++ b/tests/test_pagure_flask_api_issue.py @@ -1,31 +1,30 @@ # -*- coding: utf-8 -*- """ - (c) 2015 - Copyright Red Hat Inc +(c) 2015 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals -import arrow import copy import datetime -import unittest +import json +import os import shutil import sys import time -import os +import unittest +import arrow import flask -import pagure_messages -import json import munch - +import pagure_messages from fedora_messaging import api, testing -from mock import ANY, patch, MagicMock +from mock import ANY, MagicMock, patch from sqlalchemy.exc import SQLAlchemyError sys.path.insert( diff --git a/tests/test_pagure_flask_api_plugins_install.py b/tests/test_pagure_flask_api_plugins_install.py index 3f14799..92cb8f4 100644 --- a/tests/test_pagure_flask_api_plugins_install.py +++ b/tests/test_pagure_flask_api_plugins_install.py @@ -1,22 +1,22 @@ # -*- coding: utf-8 -*- """ - (c) 2019 - Copyright Red Hat Inc +(c) 2019 - Copyright Red Hat Inc - Authors: - Michal Konecny +Authors: + Michal Konecny """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import datetime -import unittest -import sys -import os import json +import os +import sys +import unittest -from mock import patch, MagicMock +from mock import MagicMock, patch sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") diff --git a/tests/test_pagure_flask_api_plugins_remove.py b/tests/test_pagure_flask_api_plugins_remove.py index 9a42be2..31fa01d 100644 --- a/tests/test_pagure_flask_api_plugins_remove.py +++ b/tests/test_pagure_flask_api_plugins_remove.py @@ -1,22 +1,22 @@ # -*- coding: utf-8 -*- """ - (c) 2019 - Copyright Red Hat Inc +(c) 2019 - Copyright Red Hat Inc - Authors: - Michal Konecny +Authors: + Michal Konecny """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import datetime -import unittest -import sys -import os import json +import os +import sys +import unittest -from mock import patch, MagicMock +from mock import MagicMock, patch sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py index 118edc3..41dc8dd 100644 --- a/tests/test_pagure_flask_api_project.py +++ b/tests/test_pagure_flask_api_project.py @@ -1,29 +1,29 @@ # -*- coding: utf-8 -*- """ - (c) 2015-2018 - Copyright Red Hat Inc +(c) 2015-2018 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon - Karsten Hopp +Authors: + Pierre-Yves Chibon + Karsten Hopp """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import datetime import json -import unittest -import pagure_messages +import os import shutil import sys import tempfile -import os +import unittest +import pagure_messages import pygit2 from celery.result import EagerResult from fedora_messaging import api, testing -from mock import ANY, patch, Mock +from mock import ANY, Mock, patch sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") diff --git a/tests/test_pagure_flask_api_project_git_alias.py b/tests/test_pagure_flask_api_project_git_alias.py index c812890..b9d9489 100644 --- a/tests/test_pagure_flask_api_project_git_alias.py +++ b/tests/test_pagure_flask_api_project_git_alias.py @@ -1,23 +1,23 @@ # -*- coding: utf-8 -*- """ - (c) 2020 - Copyright Red Hat Inc +(c) 2020 - Copyright Red Hat Inc - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals -import unittest +import json +import os import shutil import sys -import os +import unittest -import json import pygit2 -from mock import patch, MagicMock +from mock import MagicMock, patch sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") diff --git a/tests/test_pagure_flask_api_project_git_tags.py b/tests/test_pagure_flask_api_project_git_tags.py index d61dcfa..fb70fa0 100644 --- a/tests/test_pagure_flask_api_project_git_tags.py +++ b/tests/test_pagure_flask_api_project_git_tags.py @@ -1,15 +1,15 @@ # -*- coding: utf-8 -*- """ - Authors: - Pierre-Yves Chibon +Authors: + Pierre-Yves Chibon """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import json -import sys import os +import sys import pygit2 @@ -17,8 +17,8 @@ sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") ) -import tests import pagure.lib.query +import tests class PagureFlaskApiProjectGitTagstests(tests.Modeltests): diff --git a/tests/test_pagure_flask_api_project_tags.py b/tests/test_pagure_flask_api_project_tags.py index 252afa6..f704439 100644 --- a/tests/test_pagure_flask_api_project_tags.py +++ b/tests/test_pagure_flask_api_project_tags.py @@ -1,22 +1,22 @@ # -*- coding: utf-8 -*- """ - Authors: - Julen Landa Alustiza +Authors: + Julen Landa Alustiza """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import json -import sys import os +import sys sys.path.insert( 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") ) -import tests import pagure.lib.query +import tests class PagureFlaskApiProjectTagstests(tests.Modeltests): diff --git a/tests/test_style.py b/tests/test_style.py index b9e780e..c6157d4 100644 --- a/tests/test_style.py +++ b/tests/test_style.py @@ -11,7 +11,7 @@ Tests for flake8 compliance of the code """ -from __future__ import unicode_literals, absolute_import +from __future__ import absolute_import, unicode_literals import os import subprocess