diff --git a/doc/0-UPGRADE.mkd b/doc/0-UPGRADE.mkd index 9086661..a374c05 100644 --- a/doc/0-UPGRADE.mkd +++ b/doc/0-UPGRADE.mkd @@ -42,6 +42,12 @@ And you're done. If any extra steps beyond the generic ones above are needed, they will be listed here, newest first. +#### upgrading from 86faae4 + +Between 86faae4 and this version, gitolite had a *major* change in the +*internal* format of the compiled config file. Please do not omit step 5 in +the generic instructions above. + #### upgrading from 5758f69 Between 5758f69 and this version, gitolite learnt to allow "groupnames" for diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 3154dc1..33cc057 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -3,6 +3,7 @@ use strict; use warnings; use Data::Dumper; +$Data::Dumper::Indent = 1; # === add-auth-keys === @@ -146,8 +147,7 @@ while (<$conf_fh>) # actual permission line elsif (/^(R|RW|RW\+) (.* )?= (.+)/) { - # split perms to separate out R, W, and + - my @perms = split //, $1; + my $perms = $1; my @refs; @refs = split(' ', $2) if $2; my @users = split ' ', $3; @@ -165,11 +165,16 @@ while (<$conf_fh>) # ok, we can finally populate the %repos hash for my $repo (@repos) # each repo in the current stanza { - for my $perm (@perms) + for my $user (@users) { - for my $user (@users) + # for 1st level check (see faq/tips doc) + $repos{$repo}{R}{$user} = 1 if $perms =~ /R/; + $repos{$repo}{W}{$user} = 1 if $perms =~ /W/; + + # for 2nd level check, store each "ref, perms" pair in order + for my $ref (@refs) { - push @{ $repos{$repo}{$perm}{$user} }, @refs; + push @{ $repos{$repo}{$user} }, { $ref => $perms }; } } } diff --git a/src/update-hook.pl b/src/update-hook.pl index c703723..f65641e 100755 --- a/src/update-hook.pl +++ b/src/update-hook.pl @@ -58,13 +58,17 @@ $perm = '+' if $ref =~ m(refs/tags/) and $oldsha ne ('0' x 40); $perm = '+' if $oldsha ne $merge_base; my @allowed_refs; -push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{$perm}{$ENV{GL_USER}} || [] }; -push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{$perm}{'@all'} || [] }; -push @allowed_refs, "$PERSONAL/$ENV{GL_USER}/" if $PERSONAL; -for my $refex (@allowed_refs) -# refex? sure -- a regex to match a ref against :) +# personal stuff -- right at the start in the new regime, I guess! +push @allowed_refs, { "$PERSONAL/$ENV{GL_USER}/" => "RW+" } if $PERSONAL; +# we want specific perms to override @all, so they come first +push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{$ENV{GL_USER}} || [] }; +push @allowed_refs, @ { $repos{$ENV{GL_REPO}}{'@all'} || [] }; +for my $ar (@allowed_refs) { - if ($ref =~ /$refex/) + my $refex = (keys %$ar)[0]; + # refex? sure -- a regex to match a ref against :) + next unless $ref =~ /$refex/; + if ($ar->{$refex} =~ /\Q$perm/) { # if log failure isn't important enough to block pushes, get rid of # all the error checking @@ -72,9 +76,9 @@ for my $refex (@allowed_refs) or die "open log failed: $!\n"; print $log_fh "$ENV{GL_TS} $perm\t" . substr($oldsha, 0, 14) . "\t" . substr($newsha, 0, 14) . - "\t$ENV{GL_REPO}\t$ref\t$ENV{GL_USER}\n"; + "\t$ENV{GL_REPO}\t$ref\t$ENV{GL_USER}\t$refex\n"; close $log_fh or die "close log failed: $!\n"; exit 0; } } -exit 1; +die "$perm $ref $ENV{GL_USER} DENIED by fallthru\n";