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. """