diff --git a/pagure/hooks/pagure_ci.py b/pagure/hooks/pagure_ci.py index ee999a8..795a050 100644 --- a/pagure/hooks/pagure_ci.py +++ b/pagure/hooks/pagure_ci.py @@ -46,6 +46,8 @@ class PagureCITable(BASE): ci_type = sa.Column(sa.String(255), nullable=True) ci_url = sa.Column(sa.String(255), nullable=True, unique=False) ci_job = sa.Column(sa.String(255), nullable=True, unique=False) + ci_username = sa.Column(sa.String(255), nullable=True, unique=False) + ci_password = sa.Column(sa.String(255), nullable=True, unique=False) active = sa.Column(sa.Boolean, nullable=False, default=False) active_commit = sa.Column(sa.Boolean, nullable=False, default=False) active_pr = sa.Column(sa.Boolean, nullable=False, default=False) @@ -114,6 +116,16 @@ class PagureCiForm(FlaskForm): ], ) + ci_username = wtforms.StringField( + "Username to authenticate with if needed", + [wtforms.validators.Optional(), wtforms.validators.Length(max=255)], + ) + + ci_password = wtforms.StringField( + "Password to authenticate with if needed", + [wtforms.validators.Optional(), wtforms.validators.Length(max=255)], + ) + ci_job = wtforms.StringField( "Name of the job to trigger", [ diff --git a/pagure/lib/lib_ci.py b/pagure/lib/lib_ci.py index f2a30ec..eba958a 100644 --- a/pagure/lib/lib_ci.py +++ b/pagure/lib/lib_ci.py @@ -42,7 +42,11 @@ def process_jenkins_build(session, project, build_id, iteration=0): # Jenkins Base URL _log.info("Querying jenkins at: %s", project.ci_hook.ci_url) - jenk = jenkins.Jenkins(project.ci_hook.ci_url) + jenk = jenkins.Jenkins( + project.ci_hook.ci_url, + username=project.ci_hook.ci_username or None, + password=project.ci_hook.ci_password or None, + ) jenkins_name = project.ci_hook.ci_job _log.info( "Querying jenkins for project: %s, build: %s", jenkins_name, build_id @@ -130,7 +134,15 @@ def process_jenkins_build(session, project, build_id, iteration=0): def trigger_jenkins_build( - project_path, url, job, token, branch, branch_to, cause + project_path, + url, + job, + token, + branch, + branch_to, + cause, + ci_username=None, + ci_password=None, ): """ Trigger a build on a jenkins instance.""" try: @@ -150,7 +162,9 @@ def trigger_jenkins_build( "BRANCH_TO": branch_to, } - server = jenkins.Jenkins(url) + server = jenkins.Jenkins( + url, username=ci_username or None, password=ci_password or None + ) _log.info( "Pagure-CI: Triggering at: %s for: %s - data: %s", url, job, data ) diff --git a/pagure/lib/tasks_services.py b/pagure/lib/tasks_services.py index 4cef4e9..eb78d0a 100644 --- a/pagure/lib/tasks_services.py +++ b/pagure/lib/tasks_services.py @@ -463,23 +463,20 @@ def trigger_ci_build( if ci_type == "jenkins": + jenk_project = project if project.is_fork: - url = project.parent.ci_hook.ci_url - job = project.parent.ci_hook.ci_job - token = project.parent.ci_hook.pagure_ci_token - else: - url = project.ci_hook.ci_url - job = project.ci_hook.ci_job - token = project.ci_hook.pagure_ci_token + jenk_project = project.parent trigger_jenkins_build( project_path=project.path, - url=url, - job=job, - token=token, + url=jenk_project.ci_hook.ci_url, + job=jenk_project.ci_hook.ci_job, + token=jenk_project.ci_hook.pagure_ci_token, branch=branch, branch_to=branch_to, cause=cause, + ci_username=jenk_project.ci_hook.ci_username, + ci_password=jenk_project.ci_hook.ci_password, ) else: diff --git a/tests/test_pagure_flask_ui_plugins_pagure_ci.py b/tests/test_pagure_flask_ui_plugins_pagure_ci.py index 1604dc2..a32aaa1 100644 --- a/tests/test_pagure_flask_ui_plugins_pagure_ci.py +++ b/tests/test_pagure_flask_ui_plugins_pagure_ci.py @@ -6,6 +6,12 @@ import unittest import sys import os +import mock + +sys.path.insert(0, os.path.join(os.path.dirname( + os.path.abspath(__file__)), '..')) + +import pagure.lib.tasks_services import tests @@ -277,6 +283,101 @@ class PagureFlaskPluginPagureCItests(tests.SimplePagureTest): '
\nhttp://localhost.localdomain/api/0/ci/jenkins/somenamespace/test3/',
output_text)
+ @mock.patch('pagure.lib.tasks_services.trigger_jenkins_build')
+ def test_plugin_pagure_ci_namespaced_auth(self, trigger_jenk):
+ """ Test the pagure ci plugin on/off endpoint. """
+
+ tests.create_projects(self.session)
+ tests.create_projects_git(os.path.join(self.path, 'repos'))
+
+ user = tests.FakeUser(username='pingou')
+ with tests.user_set(self.app.application, user):
+ output = self.app.get('/somenamespace/test3/settings/Pagure CI')
+ self.assertEqual(output.status_code, 200)
+ output_text = output.get_data(as_text=True)
+ self.assertIn(
+ 'Settings Pagure CI - somenamespace/test3 - '
+ 'Pagure ', output_text)
+ self.assertIn(
+ '', output_text)
+ self.assertIn(
+ '', output_text)
+ self.assertIn(
+ '', output_text)
+
+ csrf_token = output_text.split(
+ 'name="csrf_token" type="hidden" value="')[1].split('">')[0]
+
+ # Activate hook
+ data = {
+ 'active_pr': 'y',
+ 'ci_url': 'https://jenkins.fedoraproject.org',
+ 'ci_job': 'test/job',
+ 'ci_type': 'jenkins',
+ 'ci_username': 'jenkins_username',
+ 'ci_password': 'jenkins_password',
+ 'csrf_token': csrf_token,
+ }
+
+ # Activate hook
+ output = self.app.post(
+ '/somenamespace/test3/settings/Pagure CI', data=data, follow_redirects=True)
+ self.assertEqual(output.status_code, 200)
+ output_text = output.get_data(as_text=True)
+ self.assertIn(
+ ''
+ 'Project Settings
\n', output_text)
+ self.assertIn(
+ 'Settings - somenamespace/test3 - Pagure ',
+ output_text)
+ self.assertIn(
+ ''
+ 'Project Settings
\n', output_text)
+ self.assertIn(
+ 'Hook Pagure CI activated',
+ output_text)
+
+ output = self.app.get('/somenamespace/test3/settings/Pagure CI')
+ self.assertEqual(output.status_code, 200)
+ output_text = output.get_data(as_text=True)
+ self.assertIn(
+ 'Settings Pagure CI - somenamespace/test3 - '
+ 'Pagure ', output_text)
+ self.assertIn(
+ '', output_text)
+ self.assertIn(
+ '', output_text)
+ self.assertIn(
+ '', output_text)
+ self.assertIn(
+ '\nhttp://localhost.localdomain/api/0/ci/jenkins/somenamespace/test3/',
+ output_text)
+
+ output = pagure.lib.tasks_services.trigger_ci_build(
+ project_name='somenamespace/test3',
+ cause='PR#ID',
+ branch='feature',
+ branch_to='master',
+ ci_type='jenkins')
+ self.assertIsNone(output)
+ trigger_jenk.assert_called_once_with(
+ branch=u'feature',
+ cause=u'PR#ID',
+ ci_password="jenkins_password",
+ ci_username="jenkins_username",
+ job=u'test/job',
+ project_path=u'somenamespace/test3.git',
+ token=mock.ANY,
+ url=u'https://jenkins.fedoraproject.org',
+ branch_to='master',
+ )
+
if __name__ == '__main__':
unittest.main(verbosity=2)
diff --git a/tests/test_pagure_lib_task_services.py b/tests/test_pagure_lib_task_services.py
index a5063bd..866bbeb 100644
--- a/tests/test_pagure_lib_task_services.py
+++ b/tests/test_pagure_lib_task_services.py
@@ -587,6 +587,8 @@ class PagureLibTaskServicesJenkinsCItests(tests.Modeltests):
trigger_jenk.assert_called_once_with(
branch=u'feature',
cause=u'PR#ID',
+ ci_password=None,
+ ci_username=None,
job=u'pagure',
project_path=u'test.git',
token=u'random_token',
@@ -607,6 +609,118 @@ class PagureLibTaskServicesJenkinsCItests(tests.Modeltests):
trigger_jenk.assert_called_once_with(
branch=u'feature',
cause=u'PR#ID',
+ ci_password=None,
+ ci_username=None,
+ job=u'pagure',
+ project_path=u'forks/foo/test.git',
+ token=u'random_token',
+ url=u'https://ci.server.org/',
+ branch_to='master',
+ )
+
+
+class PagureLibTaskServicesJenkinsCIAuthtests(tests.Modeltests):
+ """ Tests for pagure.lib.task_services """
+
+ maxDiff = None
+
+ def setUp(self):
+ """ Set up the environnment, ran before every tests. """
+ super(PagureLibTaskServicesJenkinsCIAuthtests, self).setUp()
+
+ pagure.config.config['REQUESTS_FOLDER'] = None
+ self.sshkeydir = os.path.join(self.path, 'sshkeys')
+ pagure.config.config['MIRROR_SSHKEYS_FOLDER'] = self.sshkeydir
+
+ tests.create_projects(self.session)
+ project = pagure.lib.query.get_authorized_project(self.session, 'test')
+
+ # Install the plugin at the DB level
+ plugin = pagure.lib.plugins.get_plugin('Pagure CI')
+ dbobj = plugin.db_object()
+ dbobj.ci_url = 'https://ci.server.org/'
+ dbobj.ci_job = 'pagure'
+ dbobj.ci_username = 'jenkins_username'
+ dbobj.ci_password = 'jenkins_password'
+ dbobj.pagure_ci_token = 'random_token'
+ dbobj.project_id = project.id
+ self.session.add(dbobj)
+ self.session.commit()
+
+ # Create a fork of test for foo
+ item = pagure.lib.model.Project(
+ user_id=2, # foo
+ name='test',
+ is_fork=True,
+ parent_id=1,
+ description='test project #1',
+ hook_token='aaabbbccc_foo',
+ )
+ item.close_status = ['Invalid', 'Insufficient data', 'Fixed', 'Duplicate']
+ self.session.add(item)
+ self.session.commit()
+
+ @patch('pagure.lib.tasks_services.trigger_jenkins_build')
+ def test_trigger_ci_build_invalid_ci(self, trigger_jenk):
+ """ Test the trigger_ci_build method. """
+ output = pagure.lib.tasks_services.trigger_ci_build(
+ project_name='test',
+ cause='PR#ID',
+ branch='feature',
+ branch_to='master',
+ ci_type='travis')
+ self.assertIsNone(output)
+ trigger_jenk.assert_not_called()
+
+ @patch('pagure.lib.tasks_services.trigger_jenkins_build')
+ def test_trigger_ci_build_invalid_ci_fork(self, trigger_jenk):
+ """ Test the trigger_ci_build method. """
+ output = pagure.lib.tasks_services.trigger_ci_build(
+ project_name='forks/foo/test',
+ cause='PR#ID',
+ branch='feature',
+ branch_to='master',
+ ci_type='travis')
+ self.assertIsNone(output)
+ trigger_jenk.assert_not_called()
+
+ @patch('pagure.lib.tasks_services.trigger_jenkins_build')
+ def test_trigger_ci_build_valid_project(self, trigger_jenk):
+ """ Test the trigger_ci_build method. """
+ output = pagure.lib.tasks_services.trigger_ci_build(
+ project_name='test',
+ cause='PR#ID',
+ branch='feature',
+ branch_to='master',
+ ci_type='jenkins')
+ self.assertIsNone(output)
+ trigger_jenk.assert_called_once_with(
+ branch=u'feature',
+ cause=u'PR#ID',
+ ci_password="jenkins_password",
+ ci_username="jenkins_username",
+ job=u'pagure',
+ project_path=u'test.git',
+ token=u'random_token',
+ url=u'https://ci.server.org/',
+ branch_to='master',
+ )
+
+ @patch('pagure.lib.tasks_services.trigger_jenkins_build')
+ def test_trigger_ci_build_valid_project_fork(self, trigger_jenk):
+ """ Test the trigger_ci_build method. """
+ output = pagure.lib.tasks_services.trigger_ci_build(
+ project_name='forks/foo/test',
+ cause='PR#ID',
+ branch='feature',
+ branch_to='master',
+ ci_type='jenkins')
+ self.assertIsNone(output)
+ trigger_jenk.assert_called_once_with(
+ branch=u'feature',
+ cause=u'PR#ID',
+ ci_password="jenkins_password",
+ ci_username="jenkins_username",
job=u'pagure',
project_path=u'forks/foo/test.git',
token=u'random_token',