diff --git a/src/Gitolite/Conf/Load.pm b/src/Gitolite/Conf/Load.pm index 1f3592e..45c44b1 100644 --- a/src/Gitolite/Conf/Load.pm +++ b/src/Gitolite/Conf/Load.pm @@ -229,6 +229,9 @@ sub load_1 { $lastuser = $user; @cached = @rules; + # however if the repo was missing, invalidate the cache + $lastrepo = '' if repo_missing($repo); + return @rules; } @@ -309,44 +312,60 @@ sub user_roles { my %ret = (); my $f = "$rc{GL_REPO_BASE}/$repo.git/gl-perms"; + my @roles = (); if ( -f $f ) { my $fh = _open( "<", $f ); - while (<$fh>) { - chomp; - # READERS u3 u4 @g1 - s/^\s+//; s/ +$//; s/=/ /; s/\s+/ /g; s/\@//; - my ( $role, @members ) = split; - # role = READERS, members = u3, u4, @g1 - if ( not $rc{ROLES}{$role} ) { - _warn "role '$role' not allowed, ignoring"; + chomp(@roles = <$fh>); + } + push @roles, "CREATOR = " . creator($repo); + for (@roles) { + # READERS u3 u4 @g1 + s/^\s+//; s/ +$//; s/=/ /; s/\s+/ /g; s/^\@//; + my ( $role, @members ) = split; + # role = READERS, members = u3, u4, @g1 + if ( $role ne 'CREATOR' and not $rc{ROLES}{$role} ) { + _warn "role '$role' not allowed, ignoring"; + next; + } + for my $m (@members) { + if ( $m !~ $USERNAME_PATT ) { + _warn "ignoring '$m' in perms line"; next; } - for my $m (@members) { - if ( $m !~ $USERNAME_PATT ) { - _warn "ignoring '$m' in perms line"; - next; - } - # if user eq u3/u4, or is a member of @g1, he has role READERS - $ret{ '@' . $role } = 1 if $m eq $user or $eg{$m}; - } + # if user eq u3/u4, or is a member of @g1, he has role READERS + $ret{ '@' . $role } = 1 if $m eq $user or $eg{$m}; } } + return keys %ret; } sub generic_name { my $base = shift; my $base2 = ''; - my $f = "$rc{GL_REPO_BASE}/$base.git/gl-creator"; - if ( -f $f ) { - my $creator; - chomp( $creator = slurp($f) ); - ( $base2 = $base ) =~ s(/$creator/)(/CREATOR/); - $base2 = '' if $base2 eq $base; # if there was no change - } + my $creator; + + # get the creator name. For not-yet-born repos this is $ENV{GL_USER}, + # which should be set in all cases that we care about, viz., where we are + # checking ^C permissions before new_wild_repo(), and the info command. + # In particular, 'gitolite access' can't be used to check ^C perms. + $creator = creator($base); + + ( $base2 = $base ) =~ s(/$creator/)(/CREATOR/) if $creator; + $base2 = '' if $base2 eq $base; # if there was no change + return $base2; } +sub creator { + my $repo = shift; + return ( $ENV{GL_USER} || '' ) if repo_missing($repo); + my $f = "$rc{GL_REPO_BASE}/$repo.git/gl-creator"; + my $creator = ''; + chomp( $creator = slurp($f) ) if -f $f; + return $creator; +} + # ---------------------------------------------------------------------- # api functions # ---------------------------------------------------------------------- diff --git a/src/Gitolite/Conf/Sugar.pm b/src/Gitolite/Conf/Sugar.pm index 2ac2dd7..04a5e1e 100644 --- a/src/Gitolite/Conf/Sugar.pm +++ b/src/Gitolite/Conf/Sugar.pm @@ -67,6 +67,7 @@ sub sugar { $lines = option($lines); # must come after rw_cdm $lines = owner_desc($lines); $lines = name_vref($lines); + $lines = role_names($lines); return $lines; } @@ -173,5 +174,30 @@ sub name_vref { return \@ret; } +sub role_names { + my $lines = shift; + my @ret; + + # [] = + # -> same but with "@" prepended to rolenames + + for my $line (@$lines) { + if ( $line =~ /^(-|C|R|RW\+?(?:C?D?|D?C?)M?) (.* )?= (.+)/ ) { + my($p, $r) = ($1, $2); + my $u = ''; + for (split ' ', $3) { + $_ = "\@$_" if $_ eq 'CREATOR' or $rc{ROLES}{$_}; + $u .= " $_"; + } + $r ||= ''; + # mind the spaces (or play safe and run cleanup_conf_line again) + push @ret, cleanup_conf_line("$p $r = $u"); + } else { + push @ret, $line; + } + } + return \@ret; +} + 1;