summaryrefslogtreecommitdiff
path: root/hgext/acl.py
diff options
context:
space:
mode:
Diffstat (limited to 'hgext/acl.py')
-rw-r--r--hgext/acl.py102
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)