diff --git a/0001-Display-real-line-numbers-on-pull-request-s-diff-vie.patch b/0001-Display-real-line-numbers-on-pull-request-s-diff-vie.patch deleted file mode 100644 index 6123262..0000000 --- a/0001-Display-real-line-numbers-on-pull-request-s-diff-vie.patch +++ /dev/null @@ -1,194 +0,0 @@ -From f48278682d9552670b7d5cb9e99a7e0a74bdd689 Mon Sep 17 00:00:00 2001 -From: Julen Landa Alustiza -Date: Fri, 7 Aug 2020 12:35:32 +0200 -Subject: [PATCH 1/9] Display real line numbers on pull request's diff view - Fixes #724 - ---- - pagure/templates/_repo_renderdiff.html | 1 - - pagure/ui/filters.py | 101 ++++++++++--------------- - tests/test_pagure_flask_ui_fork.py | 24 +++++- - 3 files changed, 64 insertions(+), 62 deletions(-) - -diff --git a/pagure/templates/_repo_renderdiff.html b/pagure/templates/_repo_renderdiff.html -index a0922169..aa9a062e 100644 ---- a/pagure/templates/_repo_renderdiff.html -+++ b/pagure/templates/_repo_renderdiff.html -@@ -164,7 +164,6 @@ - commit=patchstats["new_id"], - prequest=pull_request, - index=loop.index, -- isprdiff=True, - tree_id=diff_commits[0].tree.id)}} - - {% endautoescape %} -diff --git a/pagure/ui/filters.py b/pagure/ui/filters.py -index 73799ed7..98b2741f 100644 ---- a/pagure/ui/filters.py -+++ b/pagure/ui/filters.py -@@ -149,38 +149,33 @@ def format_loc( - for key in comments: - comments[key] = sorted(comments[key], key=lambda obj: obj.date_created) - -- if not index: -- index = "" -+ if isinstance(filename, str) and six.PY2: -+ filename = filename.decode("UTF-8") - - cnt = 1 - for line in loc.split("\n"): -- if filename and commit: -- if isinstance(filename, str) and six.PY2: -- filename = filename.decode("UTF-8") -- -- if isprdiff and ( -- line.startswith("@@") -- or line.startswith("+") -- or line.startswith("-") -- ): -- if line.startswith("@@"): -- output.append( -- '' -- % ({"cnt_lbl": cnt, "commit": commit}) -- ) -- elif line.startswith("+"): -- output.append( -- '' -- % ({"cnt_lbl": cnt, "commit": commit}) -- ) -- elif line.startswith("-"): -- output.append( -- '' -- % ({"cnt_lbl": cnt, "commit": commit}) -- ) -+ if line.startswith("@@"): -+ output.append( -+ '' -+ % ({"cnt_lbl": cnt, "commit": commit}) -+ ) -+ output.append( -+ '' -+ ) -+ else: -+ if line.startswith("+"): -+ output.append( -+ '' -+ % ({"cnt_lbl": cnt, "commit": commit}) -+ ) -+ elif line.startswith("-"): -+ output.append( -+ '' -+ % ({"cnt_lbl": cnt, "commit": commit}) -+ ) - else: - output.append( - '' -@@ -211,13 +206,6 @@ def format_loc( - } - ) - ) -- else: -- output.append( -- '' -- '' -- % ({"cnt": "%s_%s" % (index, cnt), "cnt_lbl": cnt}) -- ) - - cnt += 1 - if not line: -@@ -254,29 +242,24 @@ def format_loc( - + 'title="Open changed file">' - ) - -- if isprdiff and ( -- line.startswith("@@") -- or line.startswith("+") -- or line.startswith("-") -- ): -- if line.startswith("@@"): -- output.append( -- '\ --
%s
' -- % line -- ) -- elif line.startswith("+"): -- output.append( -- '\ --
%s
' -- % escape(line) -- ) -- elif line.startswith("-"): -- output.append( -- '\ --
%s
' -- % escape(line) -- ) -+ if line.startswith("@@"): -+ output.append( -+ '\ -+
%s
' -+ % line -+ ) -+ elif line.startswith("+"): -+ output.append( -+ '\ -+
%s
' -+ % escape(line) -+ ) -+ elif line.startswith("-"): -+ output.append( -+ '\ -+
%s
' -+ % escape(line) -+ ) - else: - output.append( - '
%s
' -diff --git a/tests/test_pagure_flask_ui_fork.py b/tests/test_pagure_flask_ui_fork.py -index 21ecd7df..8e8dce1c 100644 ---- a/tests/test_pagure_flask_ui_fork.py -+++ b/tests/test_pagure_flask_ui_fork.py -@@ -302,11 +302,31 @@ class PagureFlaskForktests(tests.Modeltests): - ) - - self.assertIn( -- '+3', -+ '+3', - output_text, - ) - self.assertIn( -- '-1', -+ '-1', -+ output_text, -+ ) -+ -+ # Test if hunk headline is rendered without line numbers -+ self.assertIn( -+ '\n
@@ -1,2 +1,4 @@',
-+            output_text,
-+        )
-+        # Tests if line number 1 is displayed
-+        self.assertNotIn(
-+            '',
-+            output_text,
-+        )
-+        # Test if line number 2 is displayed
-+        self.assertIn(
-+            '',
-             output_text,
-         )
- 
--- 
-2.26.2
-
diff --git a/0001-api-project-Fix-handling-of-false.patch b/0001-api-project-Fix-handling-of-false.patch
deleted file mode 100644
index be64790..0000000
--- a/0001-api-project-Fix-handling-of-false.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From d4f6cdfad2572dd6493f404a4a02db40c4a91ea0 Mon Sep 17 00:00:00 2001
-From: "Bernhard M. Wiedemann" 
-Date: Wed, 2 Dec 2020 20:36:14 +0100
-Subject: [PATCH] api/project: Fix handling of "false"
-
----
- pagure/api/project.py | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/pagure/api/project.py b/pagure/api/project.py
-index 654c008a..64f413b7 100644
---- a/pagure/api/project.py
-+++ b/pagure/api/project.py
-@@ -2828,7 +2828,7 @@ def _check_value(value):
-     if str(value).lower() in ["true"]:
-         value = True
-     elif str(value).lower() in ["false"]:
--        value = True
-+        value = False
-     elif str(value).isdigit():
-         value = int(value)
-     return value
--- 
-2.28.0
-
diff --git a/0002-Show-the-assignee-s-avatar-on-the-board.patch b/0002-Show-the-assignee-s-avatar-on-the-board.patch
deleted file mode 100644
index b870b13..0000000
--- a/0002-Show-the-assignee-s-avatar-on-the-board.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From d3fb1c32746580bb109ac21ff349a655a01c46f0 Mon Sep 17 00:00:00 2001
-From: Pierre-Yves Chibon 
-Date: Wed, 12 Aug 2020 20:47:22 +0200
-Subject: [PATCH 2/9] Show the assignee's avatar on the board
-
-If the ticket shown in the board is assigned to someone, show this
-person's avatar. This helps not only seeing what is in progress or
-blocked but also who is working on what or being blocked.
-
-Fixes https://pagure.io/pagure/issue/4959
-
-Signed-off-by: Pierre-Yves Chibon 
----
- pagure/templates/board.html | 3 +++
- 1 file changed, 3 insertions(+)
-
-diff --git a/pagure/templates/board.html b/pagure/templates/board.html
-index 26509ae0..46a7eb65 100644
---- a/pagure/templates/board.html
-+++ b/pagure/templates/board.html
-@@ -65,6 +65,9 @@
-             {% elif bissue.issue.status == 'Closed' %}
-               
-               #{{ bissue.issue.id }}
-+            {% endif %}
-+            {% if bissue.issue.assignee %}
-+            - {{ bissue.issue.assignee.username | avatar(size=20) | safe}}
-             {% endif %}
-               - {{ bissue.issue.title | truncate(80, False, '...') }}
-               
--- 
-2.26.2
-
diff --git a/0003-Allow-setting-a-status-as-closing-even-if-the-projec.patch b/0003-Allow-setting-a-status-as-closing-even-if-the-projec.patch
deleted file mode 100644
index 6d2ab2e..0000000
--- a/0003-Allow-setting-a-status-as-closing-even-if-the-projec.patch
+++ /dev/null
@@ -1,128 +0,0 @@
-From 9fd32d4d948fc4231eee68e8044b844060db140c Mon Sep 17 00:00:00 2001
-From: Pierre-Yves Chibon 
-Date: Wed, 12 Aug 2020 20:56:18 +0200
-Subject: [PATCH 3/9] Allow setting a status as closing even if the project has
- no close_status
-
-When determining if a status "closes" tickets or not, we should first
-check if it was set to and only if it wasn't then check if there was a
-close_status set for it. Otherwise the logic wasn't correctly interpreted.
-
-Fixes https://pagure.io/pagure/issue/4958
-
-Signed-off-by: Pierre-Yves Chibon 
----
- pagure/api/boards.py                  |  4 +-
- tests/test_pagure_flask_api_boards.py | 81 +++++++++++++++++++++++++++
- 2 files changed, 84 insertions(+), 1 deletion(-)
-
-diff --git a/pagure/api/boards.py b/pagure/api/boards.py
-index e42f7cb6..669fd457 100644
---- a/pagure/api/boards.py
-+++ b/pagure/api/boards.py
-@@ -510,7 +510,9 @@ def api_board_status(repo, board_name, username=None, namespace=None):
- 
-         try:
-             close_status = data[name].get("close_status") or None
--            close = data[name].get("close") or True if close_status else False
-+            close = data[name].get("close") or (
-+                True if close_status else False
-+            )
-             if close_status not in repo.close_status:
-                 close_status = None
- 
-diff --git a/tests/test_pagure_flask_api_boards.py b/tests/test_pagure_flask_api_boards.py
-index ef125878..67199703 100644
---- a/tests/test_pagure_flask_api_boards.py
-+++ b/tests/test_pagure_flask_api_boards.py
-@@ -801,6 +801,87 @@ class PagureFlaskApiBoardsWithBoardtests(tests.SimplePagureTest):
-             },
-         )
- 
-+    def test_api_board_api_board_status_no_close_status(self):
-+        headers = {
-+            "Authorization": "token aaabbbcccddd",
-+            "Content-Type": "application/json",
-+        }
-+
-+        data = json.dumps(
-+            {
-+                "Backlog": {
-+                    "close": False,
-+                    "close_status": None,
-+                    "bg_color": "#FFB300",
-+                    "default": True,
-+                    "rank": 1,
-+                },
-+                "Triaged": {
-+                    "close": False,
-+                    "close_status": None,
-+                    "bg_color": "#ca0dcd",
-+                    "default": False,
-+                    "rank": 2,
-+                },
-+                "Done": {
-+                    "close": True,
-+                    "close_status": None,
-+                    "bg_color": "#34d240",
-+                    "default": False,
-+                    "rank": 4,
-+                },
-+                "  ": {
-+                    "close": True,
-+                    "close_status": None,
-+                    "bg_color": "#34d240",
-+                    "default": False,
-+                    "rank": 5,
-+                },
-+            }
-+        )
-+        output = self.app.post(
-+            "/api/0/test/boards/dev/status", headers=headers, data=data
-+        )
-+        self.assertEqual(output.status_code, 200)
-+        data = json.loads(output.get_data(as_text=True))
-+        self.assertDictEqual(
-+            data,
-+            {
-+                "board": {
-+                    "active": True,
-+                    "name": "dev",
-+                    "status": [
-+                        {
-+                            "bg_color": "#FFB300",
-+                            "close": False,
-+                            "close_status": None,
-+                            "default": True,
-+                            "name": "Backlog",
-+                        },
-+                        {
-+                            "bg_color": "#ca0dcd",
-+                            "close": False,
-+                            "close_status": None,
-+                            "default": False,
-+                            "name": "Triaged",
-+                        },
-+                        {
-+                            "name": "Done",
-+                            "close": True,
-+                            "close_status": None,
-+                            "default": False,
-+                            "bg_color": "#34d240",
-+                        },
-+                    ],
-+                    "tag": {
-+                        "tag": "dev",
-+                        "tag_color": "DeepBlueSky",
-+                        "tag_description": "",
-+                    },
-+                }
-+            },
-+        )
-+
-     def test_api_board_api_board_status_adding_removing(self):
-         headers = {
-             "Authorization": "token aaabbbcccddd",
--- 
-2.26.2
-
diff --git a/0004-Include-the-assignee-in-the-list-of-people-notified-.patch b/0004-Include-the-assignee-in-the-list-of-people-notified-.patch
deleted file mode 100644
index e3803c8..0000000
--- a/0004-Include-the-assignee-in-the-list-of-people-notified-.patch
+++ /dev/null
@@ -1,36 +0,0 @@
-From 1e129038cf63f619fd5b69f92057cb29c53a83d3 Mon Sep 17 00:00:00 2001
-From: Pierre-Yves Chibon 
-Date: Wed, 12 Aug 2020 21:19:22 +0200
-Subject: [PATCH 4/9] Include the assignee in the list of people notified on a
- ticket/PR
-
-We always include the assignee in the notifications (even on private
-tickets), but so far we did not show them in the list of subscriber.
-
-With this commit, this oversight is now fixed.
-
-Fixes https://pagure.io/pagure/issue/4957
-
-Signed-off-by: Pierre-Yves Chibon 
----
- pagure/lib/query.py | 4 ++++
- 1 file changed, 4 insertions(+)
-
-diff --git a/pagure/lib/query.py b/pagure/lib/query.py
-index 8ee4df6c..498148df 100644
---- a/pagure/lib/query.py
-+++ b/pagure/lib/query.py
-@@ -4957,6 +4957,10 @@ def get_watch_list(session, obj):
-     # Add the user of the project
-     users.add(obj.project.user.username)
- 
-+    # Add the assignee if there is one
-+    if obj.assignee:
-+        users.add(obj.assignee.username)
-+
-     # Add the regular contributors
-     for contributor in obj.project.users:
-         users.add(contributor.username)
--- 
-2.26.2
-
diff --git a/0005-Introduce-the-collaborator_project_groups-mapping.patch b/0005-Introduce-the-collaborator_project_groups-mapping.patch
deleted file mode 100644
index 67da894..0000000
--- a/0005-Introduce-the-collaborator_project_groups-mapping.patch
+++ /dev/null
@@ -1,104 +0,0 @@
-From d91182e9bd01582c3ba1671a758038819943fb9b Mon Sep 17 00:00:00 2001
-From: Pierre-Yves Chibon 
-Date: Tue, 18 Aug 2020 13:33:21 +0200
-Subject: [PATCH 5/9] Introduce the collaborator_project_groups mapping
-
-We need two mappings on a regular basis. One linking a project to its
-group of collaborator and pointing to the PagureGroup objects directly.
-This is used for example to retrieve the list of collaborator groups.
-The one mapping is between a project and the corresponding ProjectGroup
-for collaborators which is where the "branches" that the group is
-restricted to is stored.
-
-So we now have both mappings available and we need to be careful to use
-the proper one, but pagure will quickly indicate (ie: crash) if one
-uses the wrong one and tries to access either the group name or the
-branches attribute.
-
-Fixes https://pagure.io/fedora-infrastructure/issue/9247
-
-Signed-off-by: Pierre-Yves Chibon 
----
- pagure/lib/model.py                    | 10 ++++++++++
- pagure/utils.py                        |  2 +-
- tests/test_pagure_flask_api_project.py | 23 ++++++++++++++++++++++-
- 3 files changed, 33 insertions(+), 2 deletions(-)
-
-diff --git a/pagure/lib/model.py b/pagure/lib/model.py
-index 325a5452..4eea9f58 100644
---- a/pagure/lib/model.py
-+++ b/pagure/lib/model.py
-@@ -487,6 +487,16 @@ class Project(BASE):
-     )
- 
-     collaborator_groups = relation(
-+        "PagureGroup",
-+        secondary="projects_groups",
-+        primaryjoin="projects.c.id==projects_groups.c.project_id",
-+        secondaryjoin="and_(pagure_group.c.id==projects_groups.c.group_id,\
-+                projects_groups.c.access=='collaborator')",
-+        order_by="PagureGroup.group_name.asc()",
-+        viewonly=True,
-+    )
-+
-+    collaborator_project_groups = relation(
-         "ProjectGroup",
-         primaryjoin="and_(projects.c.id==projects_groups.c.project_id,\
-                     projects_groups.c.access=='collaborator')",
-diff --git a/pagure/utils.py b/pagure/utils.py
-index 24a0ce4d..915ba499 100644
---- a/pagure/utils.py
-+++ b/pagure/utils.py
-@@ -311,7 +311,7 @@ def is_repo_collaborator(repo_obj, refname, username=None, session=None):
-                     return True
- 
-     # If they are in a group that has commit access -> maybe
--    for project_group in repo_obj.collaborator_groups:
-+    for project_group in repo_obj.collaborator_project_groups:
-         if project_group.group.group_name in usergroups:
-             # if branch is None when the user tries to read,
-             # so we'll allow that
-diff --git a/tests/test_pagure_flask_api_project.py b/tests/test_pagure_flask_api_project.py
-index 3c364be2..51dd8e9f 100644
---- a/tests/test_pagure_flask_api_project.py
-+++ b/tests/test_pagure_flask_api_project.py
-@@ -1010,6 +1010,27 @@ class PagureFlaskApiProjecttests(tests.Modeltests):
-         )
-         self.session.commit()
- 
-+        # Add a collaborator group
-+        msg = pagure.lib.query.add_group(
-+            self.session,
-+            group_name="some_group",
-+            display_name="Some Group",
-+            description=None,
-+            group_type="bar",
-+            user="pingou",
-+            is_admin=False,
-+            blacklist=[],
-+        )
-+        pagure.lib.query.add_group_to_project(
-+            session=self.session,
-+            project=project,
-+            new_group="some_group",
-+            user="pingou",
-+            access="collaborator",
-+            branches="features/*",
-+        )
-+        self.session.commit()
-+
-         # Existing project
-         output = self.app.get("/api/0/test")
-         self.assertEqual(output.status_code, 200)
-@@ -1019,7 +1040,7 @@ class PagureFlaskApiProjecttests(tests.Modeltests):
-         expected_data = {
-             "access_groups": {
-                 "admin": [],
--                "collaborator": [],
-+                "collaborator": ["some_group"],
-                 "commit": [],
-                 "ticket": [],
-             },
--- 
-2.26.2
-
diff --git a/0006-When-a-file-a-detected-as-a-binary-file-return-the-r.patch b/0006-When-a-file-a-detected-as-a-binary-file-return-the-r.patch
deleted file mode 100644
index fc7290c..0000000
--- a/0006-When-a-file-a-detected-as-a-binary-file-return-the-r.patch
+++ /dev/null
@@ -1,219 +0,0 @@
-From 3f65d123faa3a1fcd0b93921e5d42fe659b79fa7 Mon Sep 17 00:00:00 2001
-From: Pierre-Yves Chibon 
-Date: Wed, 12 Aug 2020 21:33:07 +0200
-Subject: [PATCH 6/9] When a file a detected as a binary file, return the raw
- file
-
-Basically, with the code until now, if an user was trying to view
-a binary file in the UI, it was then prompted to download the file
-(as pagure doesn't know how to display binary file), but the file
-the users were downloading wasn't the raw file but rather the html
-page that would contain the file.
-Not ideal.
-
-So with this commit we're now just saying: if the file is binary and
-we can't render it, just return the raw file to the user and let
-them deal with it.
-
-Fixes https://pagure.io/pagure/issue/4907
-
-Signed-off-by: Pierre-Yves Chibon 
----
- pagure/ui/repo.py                            |  8 +++-
- tests/test_pagure_flask_ui_fork.py           | 18 ++-------
- tests/test_pagure_flask_ui_repo.py           | 25 ++++---------
- tests/test_pagure_flask_ui_repo_view_file.py | 39 +++++++++-----------
- 4 files changed, 35 insertions(+), 55 deletions(-)
-
-diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py
-index b6aacc8e..06afb71d 100644
---- a/pagure/ui/repo.py
-+++ b/pagure/ui/repo.py
-@@ -639,7 +639,13 @@ def view_file(repo, identifier, filename, username=None, namespace=None):
-         output_type = "tree"
- 
-     if output_type == "binary":
--        headers[str("Content-Disposition")] = "attachment"
-+        return view_raw_file(
-+            repo,
-+            identifier,
-+            filename=filename,
-+            username=username,
-+            namespace=namespace,
-+        )
- 
-     return flask.Response(
-         flask.stream_with_context(
-diff --git a/tests/test_pagure_flask_ui_fork.py b/tests/test_pagure_flask_ui_fork.py
-index 8e8dce1c..1bff134f 100644
---- a/tests/test_pagure_flask_ui_fork.py
-+++ b/tests/test_pagure_flask_ui_fork.py
-@@ -4676,10 +4676,7 @@ More information
-             # Check fork-edit doesn't show for binary files
-             output = self.app.get("/test/blob/master/f/test.jpg")
-             self.assertEqual(output.status_code, 200)
--            self.assertNotIn(
--                "Fork and Edit\n                    \n",
--                output.get_data(as_text=True),
--            )
-+            self.assertNotIn(b"
-             )
-             self.assertEqual(output.status_code, 400)
-             self.assertIn(
--                "

Cannot edit binary files

", -- output.get_data(as_text=True), -+ b"

Cannot edit binary files

", output.data, - ) - - # Check fork-edit shows when user is not logged in -@@ -4764,10 +4760,7 @@ More information - # Check fork-edit doesn't show for binary - output = self.app.get("/test/blob/master/f/test.jpg") - self.assertEqual(output.status_code, 200) -- self.assertNotIn( -- "Edit in your fork\n \n", -- output.get_data(as_text=True), -- ) -+ self.assertNotIn(b" - "/somenamespace/test3/blob/master/f/test.jpg" - ) - self.assertEqual(output.status_code, 200) -- self.assertNotIn( -- "Fork and Edit\n \n", -- output.get_data(as_text=True), -- ) -+ self.assertNotIn(b"", output_text) -- self.assertIn( -- 'view the raw version', -- output_text, -- ) -+ self.assertNotIn(b"", output_text) -- self.assertIn('/f/test.jpg">view the raw version', output_text) -+ self.assertNotIn(b"", output_text) -- self.assertIn('/f/test.jpg">view the raw version', output_text) -+ self.assertNotIn(b"view the raw version', output_text) -- self.assertIn("Binary files cannot be rendered.
", output_text) -+ self.assertNotIn(b"", output_text) -+ self.assertEqual("foo\n bar", output_text) - - def test_view_raw_file(self): - """ Test the view_raw_file endpoint. """ -diff --git a/tests/test_pagure_flask_ui_repo_view_file.py b/tests/test_pagure_flask_ui_repo_view_file.py -index 16a1ce18..effa06b6 100644 ---- a/tests/test_pagure_flask_ui_repo_view_file.py -+++ b/tests/test_pagure_flask_ui_repo_view_file.py -@@ -135,12 +135,7 @@ class PagureFlaskRepoViewFiletests(LocalBasetests): - # View what's supposed to be an image - output = self.app.get("/test/blob/master/f/test.jpg") - self.assertEqual(output.status_code, 200) -- output_text = output.get_data(as_text=True) -- self.assertIn("Binary files cannot be rendered.
", output_text) -- self.assertIn( -- '
view the raw version', -- output_text, -- ) -+ self.assertNotIn(b"", output_text) -- self.assertIn('/f/test.jpg">view the raw version', output_text) -+ self.assertNotIn(b"", output_text) -- self.assertIn('/f/test.jpg">view the raw version', output_text) -+ self.assertEqual(output.status_code, 404) - -- def test_view_file_binary_file2(self): -+ def test_view_file_invalid_branch2(self): - """ Test the view_file with a binary file (2). """ -- -- # View binary file - output = self.app.get("/test/blob/sources/f/test_binary") -+ self.assertEqual(output.status_code, 404) -+ -+ def test_view_file_invalid_branch(self): -+ """ Test the view_file via a image name. """ -+ output = self.app.get("/test/blob/master/f/test.jpg") - self.assertEqual(output.status_code, 200) -- output_text = output.get_data(as_text=True) -- self.assertIn('/f/test_binary">view the raw version', output_text) -- self.assertTrue("Binary files cannot be rendered.
" in output_text) -+ self.assertNotIn(b" -Date: Thu, 3 Sep 2020 16:44:20 +0200 -Subject: [PATCH 7/9] Remove fenced code block when checking mention - -Fix bug #4978 - -We have to remove code using the '~~~~' markup since -this result in incorrect trigger, especially on private -ticket. ---- - pagure/lib/notify.py | 6 +++++- - tests/test_pagure_lib_notify.py | 26 ++++++++++++++++++++++++++ - 2 files changed, 31 insertions(+), 1 deletion(-) - -diff --git a/pagure/lib/notify.py b/pagure/lib/notify.py -index 0c124db9..02c277c0 100644 ---- a/pagure/lib/notify.py -+++ b/pagure/lib/notify.py -@@ -35,6 +35,7 @@ import pagure.lib.query - import pagure.lib.tasks_services - from pagure.config import config as pagure_config - from pagure.pfmarkdown import MENTION_RE -+from markdown.extensions.fenced_code import FencedBlockPreprocessor - - - _log = logging.getLogger(__name__) -@@ -234,7 +235,10 @@ def _add_mentioned_users(emails, comment): - """ Check the comment to see if an user is mentioned in it and if - so add this user to the list of people to notify. - """ -- for username in re.findall(MENTION_RE, comment): -+ filtered_comment = re.sub( -+ FencedBlockPreprocessor.FENCED_BLOCK_RE, "", comment -+ ) -+ for username in re.findall(MENTION_RE, filtered_comment): - user = pagure.lib.query.search_user(flask.g.session, username=username) - if user: - emails.add(user.default_email) -diff --git a/tests/test_pagure_lib_notify.py b/tests/test_pagure_lib_notify.py -index 8d31cb70..78af57af 100644 ---- a/tests/test_pagure_lib_notify.py -+++ b/tests/test_pagure_lib_notify.py -@@ -25,6 +25,7 @@ import pagure.lib.model - import pagure.lib.notify - import pagure.lib.query - import tests -+import munch - - - class PagureLibNotifytests(tests.Modeltests): -@@ -543,6 +544,31 @@ RW1haWwgY29udGVudA== - """ - self.assertEqual(email.as_string(), exp) - -+ def test_notification_mention(self): -+ g = munch.Munch() -+ g.session = self.session -+ with patch("flask.g", g): -+ -+ def _check_mention(comment, exp): -+ emails = set([]) -+ emails = pagure.lib.notify._add_mentioned_users( -+ emails, comment -+ ) -+ -+ self.assertEqual(emails, exp) -+ -+ exp = set(["bar@pingou.com"]) -+ comment = "I think we should ask @pingou how to pronounce pagure" -+ _check_mention(comment, exp) -+ -+ exp = set([]) -+ comment = """Let me quote him: -+~~~~ -+ @pingou> Pagure is pronounced 'pa-gure', not 'pagu-re' -+~~~~ -+""" -+ _check_mention(comment, exp) -+ - - if __name__ == "__main__": - unittest.main(verbosity=2) --- -2.26.2 - diff --git a/0008-Add-support-for-using-cchardet-to-detect-files-encod.patch b/0008-Add-support-for-using-cchardet-to-detect-files-encod.patch deleted file mode 100644 index 0bdd52f..0000000 --- a/0008-Add-support-for-using-cchardet-to-detect-files-encod.patch +++ /dev/null @@ -1,284 +0,0 @@ -From a8b2e001d6f4d2e4683aa65d6331b971f8e2ce33 Mon Sep 17 00:00:00 2001 -From: Pierre-Yves Chibon -Date: Mon, 14 Sep 2020 16:03:31 +0200 -Subject: [PATCH 8/9] Add support for using cchardet to detect files' encoding - -cchardet is a much faster version of the chardet library that can -be used to automatically detect the encoding of a file. - -Since this library is only available on python3, we're making it -an optional dependency for now. - -Fixes https://pagure.io/pagure/issue/4977 - -Signed-off-by: Pierre-Yves Chibon ---- - pagure/lib/encoding_utils.py | 12 ++++- - tests/test_pagure_flask_ui_repo.py | 58 ++++++++++++++++++++----- - tests/test_pagure_lib_encoding_utils.py | 40 ++++++++++++----- - tests/test_pagure_lib_mimetype.py | 28 ++++++++++-- - 4 files changed, 111 insertions(+), 27 deletions(-) - -diff --git a/pagure/lib/encoding_utils.py b/pagure/lib/encoding_utils.py -index 66f7dced..304e7d84 100644 ---- a/pagure/lib/encoding_utils.py -+++ b/pagure/lib/encoding_utils.py -@@ -15,7 +15,12 @@ from __future__ import unicode_literals, division, absolute_import - from collections import namedtuple - import logging - --from chardet import universaldetector, __version__ as ch_version -+try: -+ import cchardet -+ from cchardet import __version__ as ch_version -+except ImportError: -+ cchardet = None -+ from chardet import universaldetector, __version__ as ch_version - - from pagure.exceptions import PagureEncodingException - -@@ -44,7 +49,10 @@ def detect_encodings(data): - - # We can't use ``chardet.detect`` because we want to dig in the internals - # of the detector to bias the utf-8 result. -- detector = universaldetector.UniversalDetector() -+ if cchardet is not None: -+ detector = cchardet.UniversalDetector() -+ else: -+ detector = universaldetector.UniversalDetector() - detector.reset() - detector.feed(data) - result = detector.close() -diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py -index b4322e7d..e816e7f7 100644 ---- a/tests/test_pagure_flask_ui_repo.py -+++ b/tests/test_pagure_flask_ui_repo.py -@@ -20,6 +20,12 @@ import tempfile - import time - import os - -+cchardet = None -+try: -+ import cchardet -+except ImportError: -+ pass -+ - import pygit2 - import six - from mock import ANY, patch, MagicMock -@@ -2763,9 +2769,16 @@ class PagureFlaskRepotests(tests.Modeltests): - output = self.app.get("/test/raw/master") - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) -- self.assertEqual( -- output.headers["Content-Type"].lower(), "text/plain; charset=ascii" -- ) -+ if cchardet is not None: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=utf-8", -+ ) -+ else: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=ascii", -+ ) - self.assertIn(":Author: Pierre-Yves Chibon", output_text) - - # Add some more content to the repo -@@ -2784,9 +2797,16 @@ class PagureFlaskRepotests(tests.Modeltests): - - # View in a branch - output = self.app.get("/test/raw/master/f/sources") -- self.assertEqual( -- output.headers["Content-Type"].lower(), "text/plain; charset=ascii" -- ) -+ if cchardet is not None: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=utf-8", -+ ) -+ else: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=ascii", -+ ) - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) - self.assertIn("foo\n bar", output_text) -@@ -2837,9 +2857,16 @@ class PagureFlaskRepotests(tests.Modeltests): - output = self.app.get("/test/raw/master") - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) -- self.assertEqual( -- output.headers["Content-Type"].lower(), "text/plain; charset=ascii" -- ) -+ if cchardet is not None: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=utf-8", -+ ) -+ else: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=ascii", -+ ) - self.assertTrue( - output_text.startswith("diff --git a/test_binary b/test_binary\n") - ) -@@ -2877,9 +2904,16 @@ class PagureFlaskRepotests(tests.Modeltests): - output = self.app.get("/fork/pingou/test3/raw/master/f/sources") - self.assertEqual(output.status_code, 200) - output_text = output.get_data(as_text=True) -- self.assertEqual( -- output.headers["Content-Type"].lower(), "text/plain; charset=ascii" -- ) -+ if cchardet is not None: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=utf-8", -+ ) -+ else: -+ self.assertEqual( -+ output.headers["Content-Type"].lower(), -+ "text/plain; charset=ascii", -+ ) - self.assertIn("foo\n bar", output_text) - - def test_view_commit(self): -diff --git a/tests/test_pagure_lib_encoding_utils.py b/tests/test_pagure_lib_encoding_utils.py -index ccc8825f..aff7d8ba 100644 ---- a/tests/test_pagure_lib_encoding_utils.py -+++ b/tests/test_pagure_lib_encoding_utils.py -@@ -5,11 +5,18 @@ Tests for :module:`pagure.lib.encoding_utils`. - - from __future__ import unicode_literals, absolute_import - --import chardet - import os - import unittest - import sys - -+cchardet = None -+try: -+ import cchardet -+except ImportError: -+ pass -+ -+import chardet -+ - sys.path.insert( - 0, os.path.join(os.path.dirname(os.path.abspath(__file__)), "..") - ) -@@ -24,7 +31,10 @@ class TestGuessEncoding(unittest.TestCase): - """ - data = "Twas bryllyg, and the slythy toves did gyre and gymble" - result = encoding_utils.guess_encoding(data.encode("ascii")) -- self.assertEqual(result, "ascii") -+ if cchardet is not None: -+ self.assertEqual(result, "utf-8") -+ else: -+ self.assertEqual(result, "ascii") - - def test_guess_encoding_favor_utf_8(self): - """ -@@ -56,17 +66,24 @@ class TestGuessEncodings(unittest.TestCase): - chardet_result = chardet.detect(data) - if chardet.__version__[0] == "3": - # The first three have different confidence values -+ if cchardet is not None: -+ expexted_list = ["utf-8"] -+ # The last one in the list (which apparently has only one) -+ self.assertEqual(result[-1].encoding, "utf-8") -+ else: -+ expexted_list = ["utf-8", "ISO-8859-9", "ISO-8859-1"] -+ # This is the one with the least confidence -+ self.assertEqual(result[-1].encoding, "windows-1255") - self.assertListEqual( -- [encoding.encoding for encoding in result][:3], -- ["utf-8", "ISO-8859-9", "ISO-8859-1"], -+ [encoding.encoding for encoding in result][:3], expexted_list - ) -- # This is the one with the least confidence -- self.assertEqual(result[-1].encoding, "windows-1255") -+ - # The values in the middle of the list all have the same confidence - # value and can't be sorted reliably: use sets. -- self.assertEqual( -- set([encoding.encoding for encoding in result]), -- set( -+ if cchardet is not None: -+ expected_list = sorted(["utf-8"]) -+ else: -+ expected_list = sorted( - [ - "utf-8", - "ISO-8859-9", -@@ -89,7 +106,10 @@ class TestGuessEncodings(unittest.TestCase): - "windows-1251", - "windows-1255", - ] -- ), -+ ) -+ self.assertListEqual( -+ sorted(set([encoding.encoding for encoding in result])), -+ expected_list, - ) - self.assertEqual(chardet_result["encoding"], "ISO-8859-9") - else: -diff --git a/tests/test_pagure_lib_mimetype.py b/tests/test_pagure_lib_mimetype.py -index d5947bee..8c2f4a31 100644 ---- a/tests/test_pagure_lib_mimetype.py -+++ b/tests/test_pagure_lib_mimetype.py -@@ -9,6 +9,12 @@ import os - import unittest - import sys - -+cchardet = None -+try: -+ import cchardet -+except ImportError: -+ pass -+ - from pagure.lib import mimetype - - sys.path.insert( -@@ -20,8 +26,18 @@ class TestMIMEType(unittest.TestCase): - def test_guess_type(self): - dataset = [ - ("hello.html", None, "text/html", None), -- ("hello.html", b"#!", "text/html", "ascii"), -- ("hello", b"#!", "text/plain", "ascii"), -+ ( -+ "hello.html", -+ b"#!", -+ "text/html", -+ "ascii" if cchardet is None else "utf-8", -+ ), -+ ( -+ "hello", -+ b"#!", -+ "text/plain", -+ "ascii" if cchardet is None else "utf-8", -+ ), - ("hello.jpg", None, "image/jpeg", None), - ("hello.jpg", b"#!", "image/jpeg", None), - ("hello.jpg", b"\0", "image/jpeg", None), -@@ -49,7 +65,13 @@ class TestMIMEType(unittest.TestCase): - - def test_get_normal_headers(self): - dataset = [ -- ("hello", b"#!", "text/plain; charset=ascii"), -+ ( -+ "hello", -+ b"#!", -+ "text/plain; charset=ascii" -+ if cchardet is None -+ else "text/plain; charset=utf-8", -+ ), - ("hello.jpg", None, "image/jpeg"), - ("hello.jpg", b"#!", "image/jpeg"), - ("hello.jpg", b"\0", "image/jpeg"), --- -2.26.2 - diff --git a/0009-Add-support-for-disabling-user-registration.patch b/0009-Add-support-for-disabling-user-registration.patch deleted file mode 100644 index fb67cf7..0000000 --- a/0009-Add-support-for-disabling-user-registration.patch +++ /dev/null @@ -1,134 +0,0 @@ -From 8e23c79fb64d4dd4e6f17f809d7e629840f7e91c Mon Sep 17 00:00:00 2001 -From: Neal Gompa -Date: Thu, 24 Sep 2020 06:40:06 -0400 -Subject: [PATCH 9/9] Add support for disabling user registration - -For public/private Pagure instances where it is intended to be used -by a single user, having the ability to turn off user registration -prevents confusion and closes an avenue of potential denial of service -attacks. - -Signed-off-by: Neal Gompa ---- - doc/configuration.rst | 13 +++++++++++++ - pagure/default_config.py | 3 +++ - pagure/templates/login/login.html | 2 ++ - pagure/ui/login.py | 3 +++ - tests/test_pagure_flask_ui_login.py | 24 ++++++++++++++++++++++++ - 5 files changed, 45 insertions(+) - -diff --git a/doc/configuration.rst b/doc/configuration.rst -index 735e378c..2ea7a66d 100644 ---- a/doc/configuration.rst -+++ b/doc/configuration.rst -@@ -1117,6 +1117,7 @@ Valid options are ``fas``, ``openid``, ``oidc``, or ``local``. - the configuration options starting with ``OIDC_`` (see below) to be provided. - - * ``local`` causes pagure to use the local pagure database for user management. -+ User registration can be disabled with the ALLOW_USER_REGISTRATION configuration key. - - Defaults to: ``local``. - -@@ -1784,6 +1785,18 @@ If turned off, users are managed outside of pagure. - Defaults to: ``True`` - - -+ALLOW_USER_REGISTRATION -+~~~~~~~~~~~~~~~~~~~~~~~ -+ -+This configuration key can be used to turn on or off user registration -+(that is, the ability for users to create an account) in this pagure instance. -+If turned off, user accounts cannot be created through the UI or API. -+Currently, this key only applies to pagure instances configured with the ``local`` -+authentication backend and has no effect with the other authentication backends. -+ -+Defaults to: ``True`` -+ -+ - SESSION_COOKIE_NAME - ~~~~~~~~~~~~~~~~~~~ - -diff --git a/pagure/default_config.py b/pagure/default_config.py -index 045f2704..df0cd6b0 100644 ---- a/pagure/default_config.py -+++ b/pagure/default_config.py -@@ -78,6 +78,9 @@ ENABLE_GROUP_MNGT = True - # Enables / Disables private projects - PRIVATE_PROJECTS = True - -+# Enable / Disable user registration (local auth only) -+ALLOW_USER_REGISTRATION = True -+ - # Enable / Disable deleting branches in the UI - ALLOW_DELETE_BRANCH = True - -diff --git a/pagure/templates/login/login.html b/pagure/templates/login/login.html -index a65b10ae..e209c400 100644 ---- a/pagure/templates/login/login.html -+++ b/pagure/templates/login/login.html -@@ -18,11 +18,13 @@ - - {{ form.csrf_token }} - -+ {% if config.get('ALLOW_USER_REGISTRATION', True) %} -
-+ {% endif %} - - - -diff --git a/pagure/ui/login.py b/pagure/ui/login.py -index 1a0dbd24..7da94a37 100644 ---- a/pagure/ui/login.py -+++ b/pagure/ui/login.py -@@ -38,6 +38,9 @@ _log = logging.getLogger(__name__) - def new_user(): - """ Create a new user. - """ -+ if not pagure.config.config.get("ALLOW_USER_REGISTRATION", True): -+ flask.flash("User registration is disabled.", "error") -+ return flask.redirect(flask.url_for("auth_login")) - form = forms.NewUserForm() - if form.validate_on_submit(): - -diff --git a/tests/test_pagure_flask_ui_login.py b/tests/test_pagure_flask_ui_login.py -index f11a2b22..8a1d16c7 100644 ---- a/tests/test_pagure_flask_ui_login.py -+++ b/tests/test_pagure_flask_ui_login.py -@@ -149,6 +149,30 @@ class PagureFlaskLogintests(tests.SimplePagureTest): - items = pagure.lib.query.search_user(self.session) - self.assertEqual(3, len(items)) - -+ @patch.dict("pagure.config.config", {"PAGURE_AUTH": "local"}) -+ @patch.dict("pagure.config.config", {"ALLOW_USER_REGISTRATION": False}) -+ @patch("pagure.lib.notify.send_email", MagicMock(return_value=True)) -+ def test_new_user_disabled(self): -+ """ Test the disabling of the new_user endpoint. """ -+ -+ # Check before: -+ items = pagure.lib.query.search_user(self.session) -+ self.assertEqual(2, len(items)) -+ -+ # Attempt to access the new user page -+ output = self.app.get("/user/new", follow_redirects=True) -+ self.assertEqual(output.status_code, 200) -+ self.assertIn( -+ "Login - Pagure", output.get_data(as_text=True) -+ ) -+ self.assertIn( -+ "User registration is disabled.", output.get_data(as_text=True) -+ ) -+ -+ # Check after: -+ items = pagure.lib.query.search_user(self.session) -+ self.assertEqual(2, len(items)) -+ - @patch.dict("pagure.config.config", {"PAGURE_AUTH": "local"}) - @patch.dict("pagure.config.config", {"CHECK_SESSION_IP": False}) - def test_do_login(self): --- -2.26.2 - diff --git a/pagure-5.11.3.tar.gz b/pagure-5.11.3.tar.gz deleted file mode 100644 index 330c688..0000000 --- a/pagure-5.11.3.tar.gz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2f20cccc4aace71456e984e4ccd621b50868189f6de1c8eb76d8801b05d72fea -size 21878121 diff --git a/pagure-5.12.tar.gz b/pagure-5.12.tar.gz new file mode 100644 index 0000000..e60cc67 --- /dev/null +++ b/pagure-5.12.tar.gz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eae219486cf583e667e8494471dea4593a1e1baaa9b81b6f3f3e8edcb214c1e +size 21927677 diff --git a/pagure.changes b/pagure.changes index 895ba14..5cb97d7 100644 --- a/pagure.changes +++ b/pagure.changes @@ -1,3 +1,64 @@ +------------------------------------------------------------------- +Thu Jan 7 11:49:02 UTC 2021 - Neal Gompa + +- Update to 5.12 + + Display real line numbers on pull request's diff view + + Show the assignee's avatar on the board + + Allow setting a status as closing even if the project has no close_status + + Include the assignee in the list of people notified on a ticket/PR + + Add orphaning reason on the dist-git theme + + Adjust the way we generate humanized dates so we provide the humanized date + as well as the actual date when hovering over + + When a file a detected as a binary file, return the raw file + + Allow using the modifyacl API endpoint to remove groups from a project + + Add a note that repo_from* argument are mandatory in some situations when + opening a Pull-Request from the API + + Increase the list of running pagure instances in the documentation + + Remove fenced code block when checking mention + + Add support for using cchardet to detect files' encoding + + Show the default branch in the project overview page + + Send appropriate SMTP status codes and error messages in the milter. + + Report an error if a message ID isn't recognized by the milter. + + Add support for disabling user registration + + Add a way to make the stats view on more than one year (if you know how to) + + Encode the data passed onto the mail hook so it is of bytes type + + Reverse out of order instructions for new repos + + Split the list of branches into two lists active/inactive in dist-git + + Rework the "My PR" page so it does not pull so many info at once + + Include the date of the last mirroring process in the logs + + Forward the username when updating the pull-request + + Add pagination to group API + + When returning the commits flags in the API, returned them by update date + + Change the PR flag API endpoints to use commit flags + + Only show the subscribers list on demand + + Improve the message shown when a new mirrored project is created + + When editing the issue's description sent the html of it to the SSE server + + Add an update-acls action to pagure-admin + + Add support for AAA system sending SSH keys encoded in base64 + + Allow deleting the master branch when it is not the default branch + + Allow people with a fork to have a working drop-down for opening new PRs + + Fix handling "false" when editing project's options via the API + + Ensure a fork project has the same default branch as its parent + + Allow to specify a default branch for all projects hosted on an instance + + Add a notification for when a group is removed from a project + + When checking if messages were sent via a rebase, do not run the git hooks + + Make the API endpoint to update project's options accept JSON + + Add a full_url to the JSON representation of our main objects + + Ensure the author in git commit notifications follow the expected format + + Add support for git branch aliases + + Allow updating the target branch when editing a PR +- Drop upstreamed patches + + Patch: 0001-api-project-Fix-handling-of-false.patch + + Patch: 0001-Display-real-line-numbers-on-pull-request-s-diff-vie.patch + + Patch: 0002-Show-the-assignee-s-avatar-on-the-board.patch + + Patch: 0003-Allow-setting-a-status-as-closing-even-if-the-projec.patch + + Patch: 0004-Include-the-assignee-in-the-list-of-people-notified-.patch + + Patch: 0005-Introduce-the-collaborator_project_groups-mapping.patch + + Patch: 0006-When-a-file-a-detected-as-a-binary-file-return-the-r.patch + + Patch: 0007-Remove-fenced-code-block-when-checking-mention.patch + + Patch: 0008-Add-support-for-using-cchardet-to-detect-files-encod.patch + + Patch: 0009-Add-support-for-disabling-user-registration.patch + ------------------------------------------------------------------- Thu Dec 3 02:36:03 UTC 2020 - Neal Gompa diff --git a/pagure.spec b/pagure.spec index 56bf40a..1922c0a 100644 --- a/pagure.spec +++ b/pagure.spec @@ -23,7 +23,7 @@ Name: pagure -Version: 5.11.3 +Version: 5.12 Release: 0 Summary: A git-centered forge Group: Development/Tools/Version Control @@ -42,15 +42,7 @@ Source10: pagure-README.SUSE # Backports from upstream -Patch0001: 0001-Display-real-line-numbers-on-pull-request-s-diff-vie.patch -Patch0002: 0002-Show-the-assignee-s-avatar-on-the-board.patch -Patch0003: 0003-Allow-setting-a-status-as-closing-even-if-the-projec.patch -Patch0004: 0004-Include-the-assignee-in-the-list-of-people-notified-.patch -Patch0005: 0005-Introduce-the-collaborator_project_groups-mapping.patch -Patch0006: 0006-When-a-file-a-detected-as-a-binary-file-return-the-r.patch -Patch0007: 0007-Remove-fenced-code-block-when-checking-mention.patch -Patch0008: 0008-Add-support-for-using-cchardet-to-detect-files-encod.patch -Patch0009: 0009-Add-support-for-disabling-user-registration.patch + # Fixes proposed upstream ## From: https://pagure.io/pagure/pull-request/5056