From 944a202e0fddb11e8bc14e2b7ccdd5d7e9d19c6d Mon Sep 17 00:00:00 2001 From: Georges Racinet Date: Mon, 16 Nov 2020 14:23:30 +0100 Subject: [PATCH] PreReceive GitLab hook: pass over HEPTAPOD_ACCEPT_MR_IID Part of heptapod#368: the Rails app will be able to set this environment variable and we're now sending it back as the `accept_mr_iid` key to the listener for the pre-receive hook, so that the Rails app may apply merge permissions instead of (direct) push permissions. Using the (project-local) iid is better than the id, because the receiving end won't have to check that someone is trying to cheat with a MR on another project and is anyway fast compared to the overall amount of process on its side. --HG-- branch : heptapod-0-16 --- heptapod/gitlab/hooks.py | 7 +++++++ heptapod/gitlab/tests/test_hooks_integration.py | 14 +++++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/heptapod/gitlab/hooks.py b/heptapod/gitlab/hooks.py index 7e53f3f..4154f93 100644 --- a/heptapod/gitlab/hooks.py +++ b/heptapod/gitlab/hooks.py @@ -215,6 +215,8 @@ class Hook(object): if gl_repo is None: raise ValueError("GL_REPOSITORY not available") + mr_iid = base.get(b'HEPTAPOD_ACCEPT_MR_IID') + env = dict(os.environ) env['HG_GIT_SYNC'] = 'yes' env['GL_ID'] = 'user-' + pycompat.sysstr(gl_id) @@ -224,6 +226,8 @@ class Hook(object): # from gitlab-rails/lib/gitlab lib/gitlab) env['GL_PROTOCOL'] = 'web' env['GL_REPOSITORY'] = pycompat.sysstr(gl_repo) + if mr_iid is not None: + env['HEPTAPOD_ACCEPT_MR_IID'] = pycompat.sysstr(mr_iid) return env def gitlab_internal_api_request( @@ -315,6 +319,9 @@ class PreReceive(Hook): ) actor_symb, actor = parse_actor(env['GL_ID']) params[actor_symb] = actor + mr_iid = env.get('HEPTAPOD_ACCEPT_MR_IID') + if mr_iid is not None: + params['accept_mr_iid'] = int(mr_iid) return params def handle_response(self, status_code, as_json): diff --git a/heptapod/gitlab/tests/test_hooks_integration.py b/heptapod/gitlab/tests/test_hooks_integration.py index ec77895..29830fb 100644 --- a/heptapod/gitlab/tests/test_hooks_integration.py +++ b/heptapod/gitlab/tests/test_hooks_integration.py @@ -28,6 +28,8 @@ from .. import prune_reasons ZERO_SHA = b"0" * 20 +parametrize = pytest.mark.parametrize + def make_repo(base_dir, name): secret = base_dir.join('secret') @@ -108,7 +110,10 @@ def test_post_receive_params(tmpdir): assert params['gl_repository'] == 'project-1024' -def test_pre_receive_params(tmpdir): +@parametrize('with_mr', ('with-mr', 'no-mr')) +def test_pre_receive_params(tmpdir, with_mr): + # string value was neat for pytest output, prefering a bool from now on + with_mr = with_mr == 'with-mr' wrapper = make_repo(tmpdir, 'proj.hg') repo = wrapper.repo hook = PreReceive(repo) @@ -118,6 +123,9 @@ def test_pre_receive_params(tmpdir): HEPTAPOD_USERINFO_ID='2', GL_REPOSITORY='project-3145926', ) + if with_mr: + update_environ(repo, HEPTAPOD_ACCEPT_MR_IID='123') + changes = 'prune-reasons-are-ignored', { b'topic/default/with-a-dash': (ZERO_SHA, b"beef1234dead" + b"a" * 8), b'branch/default': (b"23cafe45" + b"0" * 12, b"1234" + b"b" * 16), @@ -130,6 +138,10 @@ def test_pre_receive_params(tmpdir): b'00000000000000000000 beef1234deadaaaaaaaa topic/default/with-a-dash'} assert params['gl_repository'] == 'project-3145926' assert params['project'].encode() == repo.root + if with_mr: + assert params['accept_mr_iid'] == 123 + else: + assert 'accept_mr_iid' not in params def test_post_receive_params_prune(tmpdir): -- GitLab