diff options
Diffstat (limited to 'hgext/acl.py')
-rw-r--r-- | hgext/acl.py | 102 |
1 files changed, 18 insertions, 84 deletions
diff --git a/hgext/acl.py b/hgext/acl.py index 2bf41aa..a50fa72 100644 --- a/hgext/acl.py +++ b/hgext/acl.py @@ -32,7 +32,7 @@ The order in which access checks are performed is: The allow and deny sections take key-value pairs. Branch-based Access Control ---------------------------- +........................... Use the ``acl.deny.branches`` and ``acl.allow.branches`` sections to have branch-based access control. Keys in these sections can be @@ -46,11 +46,8 @@ The corresponding values can be either: - a comma-separated list containing users and groups, or - an asterisk, to match anyone; -You can add the "!" prefix to a user or group name to invert the sense -of the match. - Path-based Access Control -------------------------- +......................... Use the ``acl.deny`` and ``acl.allow`` sections to have path-based access control. Keys in these sections accept a subtree pattern (with @@ -58,7 +55,7 @@ a glob syntax by default). The corresponding values follow the same syntax as the other sections above. Groups ------- +...... Group names must be prefixed with an ``@`` symbol. Specifying a group name has the same effect as specifying all the users in that group. @@ -69,7 +66,7 @@ a Unix-like system, the list of users will be taken from the OS. Otherwise, an exception will be raised. Example Configuration ---------------------- +..................... :: @@ -142,61 +139,19 @@ Example Configuration # under the "images" folder: images/** = jack, @designers - # Everyone (except for "user6" and "@hg-denied" - see acl.deny above) - # will have write access to any file under the "resources" folder - # (except for 1 file. See acl.deny): + # Everyone (except for "user6" - see acl.deny above) will have write + # access to any file under the "resources" folder (except for 1 + # file. See acl.deny): src/main/resources/** = * .hgtags = release_engineer -Examples using the "!" prefix -............................. - -Suppose there's a branch that only a given user (or group) should be able to -push to, and you don't want to restrict access to any other branch that may -be created. - -The "!" prefix allows you to prevent anyone except a given user or group to -push changesets in a given branch or path. - -In the examples below, we will: -1) Deny access to branch "ring" to anyone but user "gollum" -2) Deny access to branch "lake" to anyone but members of the group "hobbit" -3) Deny access to a file to anyone but user "gollum" - -:: - - [acl.allow.branches] - # Empty - - [acl.deny.branches] - - # 1) only 'gollum' can commit to branch 'ring'; - # 'gollum' and anyone else can still commit to any other branch. - ring = !gollum - - # 2) only members of the group 'hobbit' can commit to branch 'lake'; - # 'hobbit' members and anyone else can still commit to any other branch. - lake = !@hobbit - - # You can also deny access based on file paths: - - [acl.allow] - # Empty - - [acl.deny] - # 3) only 'gollum' can change the file below; - # 'gollum' and anyone else can still change any other file. - /misty/mountains/cave/ring = !gollum - ''' from mercurial.i18n import _ from mercurial import util, match import getpass, urllib -testedwith = 'internal' - def _getusers(ui, group): # First, try to use group definition from section [acl.groups] @@ -217,21 +172,7 @@ def _usermatch(ui, user, usersorgroups): return True for ug in usersorgroups.replace(',', ' ').split(): - - if ug.startswith('!'): - # Test for excluded user or group. Format: - # if ug is a user name: !username - # if ug is a group name: !@groupname - ug = ug[1:] - if not ug.startswith('@') and user != ug \ - or ug.startswith('@') and user not in _getusers(ui, ug[1:]): - return True - - # Test for user or group. Format: - # if ug is a user name: username - # if ug is a group name: @groupname - elif user == ug \ - or ug.startswith('@') and user in _getusers(ui, ug[1:]): + if user == ug or ug.find('@') == 0 and user in _getusers(ui, ug[1:]): return True return False @@ -247,20 +188,15 @@ def buildmatch(ui, repo, user, key): ui.debug('acl: %s enabled, %d entries for user %s\n' % (key, len(pats), user)) - # Branch-based ACL if not repo: if pats: - # If there's an asterisk (meaning "any branch"), always return True; - # Otherwise, test if b is in pats - if '*' in pats: - return util.always - return lambda b: b in pats - return util.never - - # Path-based ACL + return lambda b: '*' in pats or b in pats + return lambda b: False + if pats: return match.match(repo.root, '', pats) - return util.never + return match.exact(repo.root, '', []) + def hook(ui, repo, hooktype, node=None, source=None, **kwargs): if hooktype not in ['pretxnchangegroup', 'pretxncommit']: @@ -280,8 +216,6 @@ def hook(ui, repo, hooktype, node=None, source=None, **kwargs): if user is None: user = getpass.getuser() - ui.debug('acl: checking access for user "%s"\n' % user) - cfg = ui.config('acl', 'config') if cfg: ui.readconfig(cfg, sections = ['acl.groups', 'acl.allow.branches', @@ -308,9 +242,9 @@ def hook(ui, repo, hooktype, node=None, source=None, **kwargs): for f in ctx.files(): if deny and deny(f): - raise util.Abort(_('acl: user "%s" denied on "%s"' - ' (changeset "%s")') % (user, f, ctx)) + ui.debug('acl: user %s denied on %s\n' % (user, f)) + raise util.Abort(_('acl: access denied for changeset %s') % ctx) if allow and not allow(f): - raise util.Abort(_('acl: user "%s" not allowed on "%s"' - ' (changeset "%s")') % (user, f, ctx)) - ui.debug('acl: path access granted: "%s"\n' % ctx) + ui.debug('acl: user %s not allowed on %s\n' % (user, f)) + raise util.Abort(_('acl: access denied for changeset %s') % ctx) + ui.debug('acl: allowing changeset %s\n' % ctx) |