Add support for locking by branch, and document breaking in.
--- a/README Tue Apr 22 09:46:29 2008 +0100
+++ b/README Tue Apr 22 10:13:39 2008 +0100
@@ -132,6 +132,7 @@
user=<globpattern> - user's key
repo=<globpattern> - repo (as the user supplies it)
file=<globpattern> - file in the repo
+branch=<globpattern> - name of the branch
The first rule in the file which has all its conditions satisfied is
used to determine whether an action is allowed.
@@ -145,10 +146,11 @@
FILE CONDITIONS
-The rules file is used to make three decisions:
+The rules file is used to make four decisions:
- Whether to allow a repository to be created
- Whether to allow access to a repository
+- Whether to allow a changeset on a particular branch at all
- Whether to allow a changeset to change a particular file
When the first two of these decisions are being made, nothing is known
@@ -172,6 +174,18 @@
- For similar reasons, don't give "init" rules file conditions.
+LOCKING YOURSELF OUT
+
+If you find yourself "locked out" - that is, that you no longer have
+the permissions needed in hgadmin - you can break back in again if
+you're able to become the "hg" user on the repository host. Once you
+are that user, delete ~hg/.ssh/authorized_keys (to stop any user who
+might have access but shouldn't from using the repository while you
+fix things). Then go into ~hg/repos/hgadmin, do an "hg update", edit
+things to your satisfaction, and commit the change. Finally, run
+~/admin/hg-admin-tools/refresh-auth to regenerate
+~hg/.ssh/authorized_keys.
+
THANKS
Thanks for reading this far. If you use hg-admin-tools, please tell
--- a/access.py Tue Apr 22 09:46:29 2008 +0100
+++ b/access.py Tue Apr 22 10:13:39 2008 +0100
@@ -25,17 +25,28 @@
self.user = os.environ['REMOTE_USER']
self.rules = rules.Ruleset.readfile(os.environ['HG_ACCESS_RULES_FILE'])
- def check(self, node):
+ def allow(self, node):
'''return if access allowed, raise exception if not.'''
- files = self.repo.changectx(node).files()
- for f in files:
- if not self.rules.allow("write", user=self.user, repo=self.repo_path, file=f):
+ ctx = self.repo.changectx(node)
+ branch = ctx.branch()
+ if not self.rules.allow("write", user=self.user, repo=self.repo_path, branch=self.branch, file=None):
+ self.ui.debug(_('%s: user %s not allowed on branch %s\n') %
+ (__name__, self.user, branch))
+ return False
+ for f in ctx.files():
+ if not self.rules.allow("write", user=self.user, repo=self.repo_path, branch=self.branch, file=f):
self.ui.debug(_('%s: user %s not allowed on %s\n') %
- (__name__, self.getuser(), f))
- raise util.Abort(_('%s: access denied for changeset %s') %
- (__name__, short(node)))
+ (__name__, self.user, f))
+ return False
self.ui.debug(_('%s: allowing changeset %s\n') % (__name__, short(node)))
+ return True
+ def check(self, node):
+ if not allow(self, node):
+ raise util.Abort(_('%s: access denied for changeset %s') %
+ (__name__, short(node)))
+
+
def hook(ui, repo, hooktype, node=None, source=None, **kwargs):
if hooktype != 'pretxnchangegroup':
raise util.Abort(_('config error - hook type "%s" cannot stop '
--- a/hg-ssh Tue Apr 22 09:46:29 2008 +0100
+++ b/hg-ssh Tue Apr 22 10:13:39 2008 +0100
@@ -51,12 +51,12 @@
def get_cmd(rules, remoteuser, cmd):
if cmd.startswith('hg -R ') and cmd.endswith(' serve --stdio'):
repo = getpath(cmd[6:-14])
- if rules.allow("read", user=remoteuser, repo=repo, file=None):
+ if rules.allow("read", user=remoteuser, repo=repo, branch=None, file=None):
os.environ["HG_REPO_PATH"] = repo
return ['-R', repo, 'serve', '--stdio']
elif cmd.startswith('hg init '):
repo = getpath(cmd[8:])
- if rules.allow("init", user=remoteuser, repo=repo, file=None):
+ if rules.allow("init", user=remoteuser, repo=repo, branch=None, file=None):
os.environ["HG_REPO_PATH"] = repo
return ['init', repo]
fail("Illegal command %r" % cmd)