diff options
-rw-r--r-- | src/lib/Gitolite/Conf/Load.pm | 16 | ||||
-rw-r--r-- | t/C-vs-C.t | 43 |
2 files changed, 57 insertions, 2 deletions
diff --git a/src/lib/Gitolite/Conf/Load.pm b/src/lib/Gitolite/Conf/Load.pm index 88d1612..7728a5a 100644 --- a/src/lib/Gitolite/Conf/Load.pm +++ b/src/lib/Gitolite/Conf/Load.pm @@ -123,9 +123,21 @@ sub access { trace( 2, "DENIED by $refex" ) if $perm eq '-'; return "$aa $safe_ref $repo $user DENIED by $refex" if $perm eq '-'; - # $perm can be RW\+?(C|D|CD|DC)?M?. $aa can be W, +, C or D, or - # any of these followed by "M". + # For repo creation, perm will be C and aa will be "^C". For branch + # access, $perm can be RW\+?(C|D|CD|DC)?M?, and $aa can be W, +, C or + # D, or any of these followed by "M". + + # We need to turn $aa into a regex that can match a suitable $perm. + # This is trivially true for "^C", "W" and "D", but the others (+, C, + # M) need some tweaking. + + # first, quote the '+': ( my $aaq = $aa ) =~ s/\+/\\+/; + # if aa is just "C", the user is trying to create a *branch* (not a + # *repo*), so let's make the pattern clearer to reflect that. + $aaq = "RW.*C" if $aaq eq "C"; + # if the aa is, say "WM", make this "W.*M" because the perm could be + # 'RW+M', 'RW+CDM' etc, and they are all valid: $aaq =~ s/M/.*M/; $rc{RULE_TRACE} .= "A"; diff --git a/t/C-vs-C.t b/t/C-vs-C.t new file mode 100644 index 0000000..fee5cc4 --- /dev/null +++ b/t/C-vs-C.t @@ -0,0 +1,43 @@ +#!/usr/bin/perl +use strict; +use warnings; + +# the commit message in which this test is introduced should have details, but +# briefly, this test makes sure that access() does not get confused by +# repo-create permissions being allowed, when looking for branch-create +# permissions. + +# this is hardcoded; change it if needed +use lib "src/lib"; +use Gitolite::Test; + +# branch permissions test +# ---------------------------------------------------------------------- + +try "plan 25"; + +confreset;confadd ' + repo foo/..* + C = @all + RW+CD = CREATOR + RW = u2 + +'; + +try "ADMIN_PUSH set1; !/FATAL/" or die text(); + +try " + cd ..; ok + glt clone u1 file:///foo/aa; ok + cd aa; ok + tc l-1; ok; /master/ + glt push u1 origin master:m1; ok; /To file:///foo/aa/ + /\\* \\[new branch\\] master -> m1/ + + tc l-2; ok; /master/ + glt push u2 origin master:m2; !ok; /FATAL: C/ + /DENIED by fallthru/ + glt push u2 origin master:m1; ok; /To file:///foo/aa/ + /8cd302a..29b8683/ + /master -> m1/ +"; |