From f0c280cd389a32d67eb230e5cc9039e883b24ea5 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 30 Jul 2010 21:24:39 +0530 Subject: [PATCH] allow "info" to have some chance of working on big-config setups! Fedora, till now, had no hope in hell of running the info command. Why? Because the output of the info command is semantically the same as the output of the compile script *before* the big-config mode was created. And we all know how _that_ went ;-) So now you get to give "info" a partial reponame or a pattern, just like in the case of "expand". And if you're under GL_BIG_CONFIG this pattern is mandatory. And if you try to cheat it'll still stop after showing 5 entries to prevent (accidental?) DOSs Anyway, see doc changes in this commit for more details. --- doc/3-faq-tips-etc.mkd | 31 ++++++++++++++++++++++++++----- doc/report-output.mkd | 15 ++++++++------- src/gitolite.pm | 30 ++++++++++++++++++++++++------ 3 files changed, 58 insertions(+), 18 deletions(-) diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index 345ac77..25a83ff 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -455,15 +455,36 @@ Easy! Just use ssh to give the "info" command to the gitolite server: @R @W testing #R W vkc -To understand what these symbols mean, please see doc/report-output.mkd. The -administrator can also say things like: +To understand what these symbols mean, please see doc/report-output.mkd. + +You can also pass an extra argument to subset the listing; it's treated as a +regex pattern that can match anywhere in the reponame. + +In "big-config" mode (i.e., when `GL_BIG_CONFIG` is set) this argument is +**mandatory**. You can try and cheat the system by passing in a "." but +gitolite truncates the output after 5 results to prevent a DOS. + + $ ssh git@server info git + hello sitaram, the gitolite version here is v1.4.2-4-g40cbecd + the gitolite config gives you the following access: + @R W git-notes + @R W gitolite + #R W gitolite-admin + + $ ssh git@server info admin + hello sitaram, the gitolite version here is v1.4.2-4-g40cbecd + the gitolite config gives you the following access: + #R W gitolite-admin + +The administrator can also say things like: # if you installed using the "from-client" method - ssh gitolite info u1 u2 u3 + ssh gitolite info foo u1 u2 u3 # for the other 3 install methods - ssh git@server info u1 u2 u3 + ssh git@server info foo u1 u2 u3 -to get this info for other user(s). +to get this info for other user(s). The "foo" is a partial reponame or a +regex pattern; see above for details. diff --git a/doc/report-output.mkd b/doc/report-output.mkd index 51cb565..ba632e4 100644 --- a/doc/report-output.mkd +++ b/doc/report-output.mkd @@ -13,14 +13,15 @@ Here is the output of the 2 commands (info and expand): Usage: - ssh git@server info - ssh git@server info [list of users] + ssh git@server info [optional_pattern [list of users]] The "info" command shows you all the repos (and repo patterns) in the config -file that you have been given any kind of access to. If you're an admin you -can append a list of users to see their permissions instead of your own. -(Side note: if you installed using easy-install that would probably be `ssh -gitolite info`, by the way). +file that you have been given any kind of access to. If you supply an +optional pattern the output will be limited to repos matching that pattern. +If you're an admin you can append a list of users to see their permissions +instead of your own; in this mode the pattern is mandatory, even if you just +use `.` to cheat. (Side note: if you installed using easy-install that would +probably be `ssh gitolite info`, by the way). The meaning of C, R, and W are self-explanatory, but they might sometimes be prefixed by a symbol. For example, `@R` means that `@all` users have @@ -31,7 +32,7 @@ root's shell prompt) and so has access to `@all` repos. Usage: - ssh git@server expand [optional pattern] + ssh git@server expand [optional_pattern] The "expand" command trawls through all the repositories on the server, limiting to repos matching the pattern you provide (default is all repos diff --git a/src/gitolite.pm b/src/gitolite.pm index dbcfcfc..8eee76c 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -325,7 +325,7 @@ sub report_version { # got parsed by the compile script sub report_basic { - my($GL_ADMINDIR, $GL_CONF_COMPILED, $user) = @_; + my($GL_ADMINDIR, $GL_CONF_COMPILED, $repo, $user) = @_; # XXX The correct way is actually to give parse_acl another argument # (defaulting to $ENV{GL_USER}, the value being used now). But for now @@ -338,7 +338,11 @@ sub report_basic # send back some useful info if no command was given &report_version($GL_ADMINDIR, $user); print "\rthe gitolite config gives you the following access:\r\n"; + my $count = 0; for my $r (sort keys %repos) { + next unless $r =~ /$repo/i; + # if $GL_BIG_CONFIG is on, limit the number of output lines to 5 + next if $GL_BIG_CONFIG and $count++ >= 5; if ($r =~ $REPONAME_PATT and $r !~ /\bCREAT[EO]R\b/) { &parse_acl($GL_CONF_COMPILED, $r, "NOBODY", "NOBODY", "NOBODY"); } else { @@ -354,6 +358,7 @@ sub report_basic $perm .= ( $repos{$r}{W}{'@all'} ? ' @W' : ( $repos{'@all'}{W}{$user} ? ' #W' : ( $repos{$r}{W}{$user} ? ' W' : ' ' ))); print "$perm\t$r\r\n" if $perm =~ /\S/; } + print "only 5 out of $count candidate repos examined\r\nplease use a partial reponame or regex pattern to limit output\r\n" if $GL_BIG_CONFIG and $count > 5; } # ---------------------------------------------------------------------------- @@ -374,17 +379,20 @@ sub expand_wild # has at least "R" access to chdir("$repo_base_abs") or die "chdir $repo_base_abs failed: $!\n"; + my $count = 0; for my $actual_repo (`find . -type d -name "*.git"|sort`) { chomp ($actual_repo); $actual_repo =~ s/^\.\///; $actual_repo =~ s/\.git$//; # actual_repo has to match the pattern being expanded - next unless $actual_repo =~ /$repo/; + next unless $actual_repo =~ /$repo/i; + next if $GL_BIG_CONFIG and $count++ >= 5; my($perm, $creator, $wild) = &repo_rights($actual_repo); next unless $perm =~ /\S/; print "$perm\t$creator\t$actual_repo\n"; } + print "only 5 out of $count candidate repos examined\nplease use a partial reponame or regex pattern to limit output\n" if $GL_BIG_CONFIG and $count > 5; } # there will be multiple calls to repo_rights; better to use a closure. We @@ -471,18 +479,28 @@ sub special_cmd # check each special command we know about and call it if enabled if ($cmd eq 'info') { - &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $user); + &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, '^', $user); print "you also have shell access\r\n" if $shell_allowed; } elsif ($cmd =~ /^info\s+(.+)$/) { my @otherusers = split ' ', $1; + # the first argument is assumed to be a repo pattern, like in the + # expand command + my $repo = shift(@otherusers); + die "$repo has invalid characters" unless "x$repo" =~ $REPOPATT_PATT; + print STDERR "(treating $repo as pattern to limit output)\n"; - my($perm, $creator, $wild) = &repo_rights('gitolite-admin'); - die "you can't ask for others' permissions\n" unless $perm =~ /W/; + # set up the list of users being queried; it's either a list passed in + # (allowed only for admin pushers) or just $user + if (@otherusers) { + my($perm, $creator, $wild) = &repo_rights('gitolite-admin'); + die "you can't ask for others' permissions\n" unless $perm =~ /W/; + } + push @otherusers, $user unless @otherusers; &parse_acl($GL_CONF_COMPILED); for my $otheruser (@otherusers) { warn("ignoring illegal username $otheruser\n"), next unless $otheruser =~ $USERNAME_PATT; - &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $otheruser); + &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $repo, $otheruser); } } elsif ($HTPASSWD_FILE and $cmd eq 'htpasswd') { &ext_cmd_htpasswd($HTPASSWD_FILE);