From 9e14c88820be66b1c53d07721fa164aeb4bd7660 Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Jun 18 2018 14:12:16 +0000 Subject: [PATCH 1/2] Only display SSH URL for repo if SSH key is uploaded and gitolite config is compiled --- diff --git a/pagure/default_config.py b/pagure/default_config.py index ba22e33..24db249 100644 --- a/pagure/default_config.py +++ b/pagure/default_config.py @@ -89,6 +89,10 @@ SHOW_PROJECTS_INDEX = ['repos', 'myrepos', 'myforks'] GIT_URL_SSH = 'ssh://git@localhost.localdomain/' GIT_URL_GIT = 'git://localhost.localdomain/' +# Set to True if git ssh URLs should be displayed even if user +# doesn't have SSH key uploaded +ALWAYS_RENDER_SSH_CLONE_URL = False + # Default queue names for the different services WEBHOOK_CELERY_QUEUE = 'pagure_webhook' LOGCOM_CELERY_QUEUE = 'pagure_logcom' diff --git a/pagure/flask_app.py b/pagure/flask_app.py index ef29267..f83c266 100644 --- a/pagure/flask_app.py +++ b/pagure/flask_app.py @@ -111,6 +111,22 @@ def create_app(config=None): os.path.join(app.root_path, 'static'), ] + @app.context_processor + def context_processor(): + def user_can_clone_ssh(username): + ssh_keys = '' + if flask.g.authenticated: + ssh_keys = pagure.lib.search_user( + flask.g.session, + username=flask.g.fas_user.username + ).public_ssh_key or '' + if not (pagure_config.get('ALWAYS_RENDER_SSH_CLONE_URL') + or ssh_keys.strip()): + return False + return True + + return {'user_can_clone_ssh': user_can_clone_ssh} + auth = pagure_config.get('PAGURE_AUTH', None) if auth in ['fas', 'openid']: # Only import and set flask_fas_openid if it is needed diff --git a/pagure/templates/repo_master.html b/pagure/templates/repo_master.html index e817f5f..64516c4 100644 --- a/pagure/templates/repo_master.html +++ b/pagure/templates/repo_master.html @@ -1,5 +1,24 @@ {% extends "master.html" %} +{% macro print_ssh_url(repo, git_url_ssh, current_user) %} + {% if not user_can_clone_ssh(current_user) %} + + You need to upload SSH key to be able to clone over SSH + + {% elif repo.read_only %} + The permissions on this repository are being updated. + Cloning over SSH is disabled. + {% else %} +
+
+
SSH
+ +
+
+ {% endif %} +{% endmacro %} + {% block title %}{{ repo.namespace + '/' if repo.namespace }}{{ repo.name }}{% endblock %} {% set tag = "home" %} @@ -154,13 +173,7 @@
Source Code
{% if g.authenticated and g.repo_committer %} -
-
-
SSH
- -
-
+ {{ print_ssh_url(repo, git_url_ssh, g.fas_user.username) }} {% endif %}
@@ -175,13 +188,7 @@ and repo.settings.get('project_documentation', True) %}
Documentation
{% if g.authenticated and g.repo_committer %} -
-
-
SSH
- -
-
+ {{ print_ssh_url(repo, git_url_ssh + "docs/", g.fas_user.username) }} {% endif %}
@@ -195,22 +202,10 @@ {% if config.get('ENABLE_TICKETS', True) and repo.settings.get('issue_tracker', True) %}
Issues
-
-
-
SSH
- -
-
+ {{ print_ssh_url(repo, git_url_ssh + "tickets/", g.fas_user.username) }} {% endif %}
Pull Requests
-
-
-
SSH
- -
-
+ {{ print_ssh_url(repo, git_url_ssh + "requests/", g.fas_user.username) }} {% endif %}
diff --git a/tests/test_pagure_flask_ui_issues.py b/tests/test_pagure_flask_ui_issues.py index 2abb585..6622c5e 100644 --- a/tests/test_pagure_flask_ui_issues.py +++ b/tests/test_pagure_flask_ui_issues.py @@ -3294,6 +3294,11 @@ class PagureFlaskIssuestests(tests.Modeltests): user = tests.FakeUser() user.username = 'pingou' + + repo = pagure.lib._get_project(self.session, 'test') + pagure.lib.update_read_only_mode(self.session, repo, read_only=False) + pagure.lib.get_user(self.session, 'pingou').public_ssh_key = 'foo' + self.session.commit() with tests.user_set(self.app.application, user): # Check that the git issue URL is present output = self.app.get('/test') diff --git a/tests/test_pagure_flask_ui_repo.py b/tests/test_pagure_flask_ui_repo.py index 455189b..85a7ffd 100644 --- a/tests/test_pagure_flask_ui_repo.py +++ b/tests/test_pagure_flask_ui_repo.py @@ -1519,6 +1519,10 @@ class PagureFlaskRepotests(tests.Modeltests): tests.create_projects(self.session) tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True) + pagure.lib.get_user(self.session, 'pingou').public_ssh_key = 'foo' + repo = pagure.lib._get_project(self.session, 'test') + pagure.lib.update_read_only_mode(self.session, repo, read_only=False) + self.session.commit() user = tests.FakeUser(username='pingou') with tests.user_set(self.app.application, user): output = self.app.get('/test') @@ -1562,6 +1566,40 @@ class PagureFlaskRepotests(tests.Modeltests): self.perfMaxWalks(0, 0) self.perfReset() + def test_view_repo_ssh_key_not_uploaded_no_ssh_url(self): + """ Test viewing repo when user hasn't uploaded SSH key yet + and thus should see a message instead of url for SSH cloning. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True) + user = tests.FakeUser(username='pingou') + + with tests.user_set(self.app.application, user): + output = self.app.get('/test') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'You need to upload SSH key to be able to clone over SSH', + output_text) + + def test_view_repo_read_only_no_ssh_url(self): + """ Test viewing repo that is still readonly and thus user + should see a message instead of url for SSH cloning. """ + tests.create_projects(self.session) + tests.create_projects_git(os.path.join(self.path, 'repos'), bare=True) + repo = pagure.lib._get_project(self.session, 'test') + pagure.lib.update_read_only_mode(self.session, repo, read_only=True) + pagure.lib.get_user(self.session, 'pingou').public_ssh_key = 'foo' + self.session.commit() + user = tests.FakeUser(username='pingou') + + with tests.user_set(self.app.application, user): + output = self.app.get('/test') + self.assertEqual(output.status_code, 200) + output_text = output.get_data(as_text=True) + self.assertIn( + 'Cloning over SSH is disabled.', + output_text) + def test_view_repo(self): """ Test the view_repo endpoint. """ From 4194aa6ecdf8f7211e70d8b19b45cf05adde757e Mon Sep 17 00:00:00 2001 From: Slavek Kabrda Date: Jun 18 2018 14:12:16 +0000 Subject: [PATCH 2/2] Inject git_url_ssh to all templates rendered, since a lot templates are using it Fixes: #3332 --- diff --git a/pagure/flask_app.py b/pagure/flask_app.py index f83c266..377fe02 100644 --- a/pagure/flask_app.py +++ b/pagure/flask_app.py @@ -125,7 +125,21 @@ def create_app(config=None): return False return True - return {'user_can_clone_ssh': user_can_clone_ssh} + def get_git_url_ssh(): + """ Return the GIT SSH URL to be displayed in the UI based on the + content of the configuration file. + """ + git_url_ssh = pagure_config.get('GIT_URL_SSH') + if flask.g.authenticated and git_url_ssh: + try: + git_url_ssh = git_url_ssh.format( + username=flask.g.fas_user.username) + except (KeyError, IndexError): + pass + return git_url_ssh + + return {'user_can_clone_ssh': user_can_clone_ssh, + 'git_url_ssh': get_git_url_ssh()} auth = pagure_config.get('PAGURE_AUTH', None) if auth in ['fas', 'openid']: diff --git a/pagure/ui/repo.py b/pagure/ui/repo.py index 86fc5f0..06099df 100644 --- a/pagure/ui/repo.py +++ b/pagure/ui/repo.py @@ -57,7 +57,6 @@ from pagure.lib import encoding_utils from pagure.ui import UI_NS from pagure.utils import ( __get_file_in_tree, - authenticated, login_required, is_true, stream_template, @@ -70,20 +69,6 @@ from pagure.decorators import ( _log = logging.getLogger(__name__) -def get_git_url_ssh(): - """ Return the GIT SSH URL to be displayed in the UI based on the - content of the configuration file. - """ - git_url_ssh = pagure_config.get('GIT_URL_SSH') - if authenticated() and git_url_ssh: - try: - git_url_ssh = git_url_ssh.format( - username=flask.g.fas_user.username) - except (KeyError, IndexError): - pass - return git_url_ssh - - def get_preferred_readme(tree): """ Establish some order about which README gets displayed if there are several in the repository. If none of the listed @@ -180,7 +165,6 @@ def view_repo(repo, username=None, namespace=None): branchname=branchname, last_commits=last_commits, tree=tree, - git_url_ssh=get_git_url_ssh(), ) @@ -276,7 +260,6 @@ def view_repo_branch(repo, branchname, username=None, namespace=None): safe=safe, readme=readme, diff_commits=diff_commits, - git_url_ssh=get_git_url_ssh(), ) """