compile/update: new "D" permission

normally, RW+ means permission to rewind or delete.

Now, if you use "D" permission anywhere in a repo config, that means
"delete" and RW+ then means only "rewind", no delete.
This commit is contained in:
Sitaram Chamarty 2010-03-30 20:01:49 +05:30
parent 33b886c512
commit 967af2c993
4 changed files with 40 additions and 10 deletions

View file

@ -60,11 +60,6 @@
# "@interns" now has 3 names in it, but note that this does # "@interns" now has 3 names in it, but note that this does
# not change @staff # not change @staff
# WILDCARD REPOSITORIES ("wildrepos" BRANCH ONLY)
# -----------------------------------------
# Please see doc/4-wildcard-repositories.mkd for details
# REPO AND BRANCH PERMISSIONS # REPO AND BRANCH PERMISSIONS
# --------------------------- # ---------------------------
@ -72,10 +67,13 @@
# start line: # start line:
# repo [one or more repos and/or repo groups] # repo [one or more repos and/or repo groups]
# followed by one or more permissions lines: # followed by one or more permissions lines:
# (R|RW|RW+) [zero or more refexes] = [one or more users] # (C|D|R|RW|RW+) [zero or more refexes] = [one or more users]
# there are 3 types of permissions: R, RW, and RW+. The "+" means permission # there are 5 types of permissions: R, RW, and RW+ are simple (the "+" means
# to "rewind" (force push a non-fast forward to) a branch # permission to "rewind" -- force push a non-fast forward to -- a branch).
# The C permission is described in doc/4-wildcard-repositories.mkd. The D
# permission is described in doc/3-faq-tips-etc.mkd, in the "advanced
# features" section.
# how permissions are matched: # how permissions are matched:
# - user, repo, and access (W or +) are known. For that combination, if # - user, repo, and access (W or +) are known. For that combination, if

View file

@ -18,6 +18,7 @@ In this document:
* two levels of access rights checking * two levels of access rights checking
* better logging * better logging
* "exclude" (or "deny") rules * "exclude" (or "deny") rules
* the "D" permission -- separating delete and rewind rights
* file/dir NAME based restrictions * file/dir NAME based restrictions
* delegating parts of the config file * delegating parts of the config file
* convenience features * convenience features
@ -366,6 +367,28 @@ And here's how it works:
before the third one, and it has a `-` as the permission, so the push before the third one, and it has a `-` as the permission, so the push
fails fails
#### the "D" permission -- separating delete and rewind rights
Since the beginning, `RW+` meant being able to rewind *or* delete a ref. My
stand is that these two are fairly similar, and infact a rewind is almost the
same as a delete+push (the only difference I can see is if you had
core.logAllRefUpdates set, which is *not* a default setting).
However, there seem to be cases where it is useful to distinguish them --
situations where one of them should be restricted more than the other.
([Arguments][sdrr] exist for both sides: restrict delete more than rewind, and
vice versa).
So we now allow these two rights to be separated. Just use the new `D`
permission anywhere in the config for the repo, and instantly all `RW+`
permissions (for that repo) cease to permit deletion of the ref matched.
This provides the *greatest* backward compatibility (if you don't specify any
`D` permissions, everything works just as before), while also enabling the new
semantics at the granularity of a repo, instead of the entire config.
[sdrr]: http://groups.google.com/group/gitolite/browse_thread/thread/9f2b4358ce406d4c#
#### file/dir NAME based restrictions #### file/dir NAME based restrictions
In addition to branch-name based restrictions, gitolite also allows you to In addition to branch-name based restrictions, gitolite also allows you to

View file

@ -75,6 +75,10 @@ $perm = '+' if $ref =~ m(refs/tags/) and $oldsha ne ('0' x 40);
# notice that ref delete looks like a rewind, as it should # notice that ref delete looks like a rewind, as it should
$perm = '+' if $oldsha ne $merge_base; $perm = '+' if $oldsha ne $merge_base;
# were any 'D' perms specified? If they were, it means we have to separate
# deletes from rewinds, so if the new sha is all 0's, change the '+' to a 'D'
$perm = 'D' if $repos{$ENV{GL_REPO}}{DELETE_IS_D} and $newsha eq '0' x 40;
my @allowed_refs; my @allowed_refs;
# @all repos: see comments in similar code in check_access # @all repos: see comments in similar code in check_access
push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{$ENV{GL_USER}} || [] }; push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{$ENV{GL_USER}} || [] };

View file

@ -191,7 +191,7 @@ sub parse_conf_file
s/\bCREAT[EO]R\b/\$creater/g for @repos; s/\bCREAT[EO]R\b/\$creater/g for @repos;
} }
# actual permission line # actual permission line
elsif (/^(-|C|R|RW|RW\+) (.* )?= (.+)/) elsif (/^(-|C|D|R|RW|RW\+) (.* )?= (.+)/)
{ {
my $perms = $1; my $perms = $1;
my @refs; @refs = split(' ', $2) if $2; my @refs; @refs = split(' ', $2) if $2;
@ -257,7 +257,12 @@ sub parse_conf_file
# for 1st level check (see faq/tips doc) # for 1st level check (see faq/tips doc)
$repos{$repo}{C}{$user} = 1, next if $perms eq 'C'; $repos{$repo}{C}{$user} = 1, next if $perms eq 'C';
$repos{$repo}{R}{$user} = 1 if $perms =~ /R/; $repos{$repo}{R}{$user} = 1 if $perms =~ /R/;
$repos{$repo}{W}{$user} = 1 if $perms =~ /W/; $repos{$repo}{W}{$user} = 1 if $perms =~ /W|D/;
# if the user specified even a single 'D' anywhere, make
# that fact easy to find; this changes the meaning of RW+
# to no longer permit deletes (see update hook)
$repos{$repo}{DELETE_IS_D} = 1 if $perms eq 'D';
# for 2nd level check, store each "ref, perms" pair in order # for 2nd level check, store each "ref, perms" pair in order
for my $ref (@refs) for my $ref (@refs)