Skip to content
Snippets Groups Projects
Commit 4c68254d authored by Georges Racinet's avatar Georges Racinet
Browse files

check_write: a hook to check write permission

This will be a major ingredient of SSH push support in Heptapod.
Thanks to the factorizing effort we've done in `hooks.perm`,
the implementation is almost trivial.
parent 5f58ee03
No related branches found
No related tags found
1 merge request!6New hook to check write permissions outside of HTTP contexts
Pipeline #
......@@ -85,6 +85,30 @@
return False
def check_write(repo, *args, **kwargs):
"""Check that remote user has write privileges.
In this hook, the very fact to be called serves as detection that a
write operation will happen.
Therefore the implementation is very straightforward.
"""
validate_hook_type('pretxnopen', **kwargs)
remote_user = get_remote_user(repo)
if remote_user is not None:
repo.ui.debug(
'check_write detected push from user: %r\n' % remote_user)
if allowed(repo, remote_user, 'web', 'allow-push'):
return 0
msg = 'user %r does not have write permission' % remote_user
repo.ui.note(msg)
repo.ui.status(msg)
return 1
def check_publish(repo, *args, **kwargs):
validate_hook_type('pretxnclose', **kwargs)
remoteuser = get_remote_user(repo)
......
from __future__ import absolute_import
import pytest
from mercurial import (
error,
)
from heptapod.testhelpers import (
LocalRepoWrapper,
)
from .utils import switch_user
def init_repo(basedir):
return LocalRepoWrapper.init(
basedir,
config=dict(
hooks={'pretxnopen.check_write':
'python:heptapod.hooks.perm.check_write'
},
web={'allow-push': 'developer',
},
))
def test_write_empty_repo(tmpdir):
wrapper = init_repo(tmpdir)
with pytest.raises(error.HookAbort) as exc_info:
wrapper.write_commit('foo', content='Foo', return_ctx=True)
assert 'pretxnopen.check_write' in exc_info.value.args[0]
switch_user(wrapper, 'developer')
ctx = wrapper.write_commit('foo', message='developer is accepted',
return_ctx=True)
assert ctx.description() == 'developer is accepted'
def test_phase_change(tmpdir):
wrapper = init_repo(tmpdir)
switch_user(wrapper, 'developer')
ctx = wrapper.write_commit('foo', content='Foo', return_ctx=True)
switch_user(wrapper, 'guest')
with pytest.raises(error.HookAbort) as exc_info:
wrapper.set_phase('public', [ctx.hex()])
assert 'pretxnopen.check_write' in exc_info.value.args[0]
def test_wrong_hook(tmpdir):
wrapper = init_repo(tmpdir)
ui = wrapper.repo.ui
pretxn = 'pretxnopen.check_write'
hookdef = ui.config('hooks', pretxn)
ui.setconfig('hooks', pretxn, '')
ui.setconfig('hooks', 'precommit.check_write', hookdef)
# precommit because that one does not swallow exceptions other
# than abort
with pytest.raises(error.ProgrammingError) as exc_info:
wrapper.write_commit('foo')
assert 'precommit' in exc_info.value.args[0]
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment