diff options
Diffstat (limited to 'src/triggers/expand-deny-messages')
-rwxr-xr-x | src/triggers/expand-deny-messages | 191 |
1 files changed, 191 insertions, 0 deletions
diff --git a/src/triggers/expand-deny-messages b/src/triggers/expand-deny-messages new file mode 100755 index 0000000..107202c --- /dev/null +++ b/src/triggers/expand-deny-messages @@ -0,0 +1,191 @@ +#!/usr/bin/perl +use strict; +use warnings; + +$|++; + +# program name: expand-deny-messages + +# DOCUMENTATION IS AT THE BOTTOM OF THIS FILE; PLEASE READ + +use lib $ENV{GL_LIBDIR}; +use Gitolite::Rc; +use Gitolite::Common; + +my %attempted_access = ( + # see triggers.html + 'ACCESS_1' => { + 'R' => 'Repo read', + 'W' => 'Repo write', + }, + 'ACCESS_2' => { + 'W' => "Fast forward push", + '+' => "Rewind push branch or overwrite tag", + 'C' => "Create ref", + 'D' => "Delete ref", + } +); + +# env var to disable is set? +exit 0 if $ENV{GL_OPTION_EDM_DISABLE}; + +# argument 1 +my $a12 = shift; # ACCESS_1 or ACCESS_2 +exit 0 if $a12 !~ /^ACCESS_[12]$/; # shouldn't happen; error in rc file? + +# the rest of the arguments +my ( $repo, $user, $aa, $ref, $msg, $oldsha, $newsha ) = @ARGV; + +# we're only interested in deny messages +exit 0 if $msg !~ /DENIED/; + +print STDERR "\nFATAL -- ACCESS DENIED\n"; + +_info( "Repo", $repo ); +_info( "User", $user ); +_info( "Stage", ( $a12 eq 'ACCESS_1' ? "Before git was called" : "From git's update hook" ) ); +_info( "Ref", _ref($ref) ) if $a12 eq 'ACCESS_2'; +_info( "Operation", _op( $a12, $aa, $oldsha, $newsha ) ); + +if ( $ref =~ m((^VREF/[^/]+)) ) { + my $vref = $1; + if ($ref =~ s(^VREF/NAME/)()) { + print STDERR "You're apparently not allowed to push '$ref'"; + } else { + my $vref_text = slurp( _which( $vref, 'x' ) ); + my $etag = '(?:help|explain|explanation)'; + $vref_text =~ m(^\s*# $etag.start\n(.*)^\s*# $etag.end\n)sm + and print STDERR "Explanation for $vref:\n$1"; + } +} + +print STDERR "\n"; +print STDERR "$ENV{GL_OPTION_EDM_EXTRA_INFO}\n\n" if $ENV{GL_OPTION_EDM_EXTRA_INFO}; + +# ------------------------------------------------------------------------ + +sub _ref { + my $r = shift; + return "VREF '$r'" if $r =~ s(^VREF/)(); + return "Branch '$r'" if $r =~ s(^refs/heads/)(); + return "Tag '$r'" if $r =~ s(^refs/tags/)(); + return "Non-standard ref '$r'"; +} + +sub _info { + printf STDERR "%-14s %-60s\n", @_; +} + +sub _op { + my ( $a12, $aa, $oldsha, $newsha ) = @_; + + # first remove the M part and save the text for later addition if needed + my $merge = ( $aa =~ s/M// ? " with merge commit" : "" ); + + # next, the attempted access is modified to reflect the actual operation being + # attempted. NOTE: this no longer necessarily reflects what the gitolite log + # file stores; it's more granular and truly distinguishes a branch create from + # an ff push, etc. Could help when user typos a branch name I suppose + $aa = 'C' if $oldsha and $oldsha eq '0' x 40; + $aa = 'D' if $newsha and $newsha eq '0' x 40; + + # then we map it, add merge text if any + my $op = $attempted_access{$a12}{$aa} || "Unknown operation '$aa'"; + $op .= $merge; + + return $op; +} + +__END__ + +ENABLING THE FEATURE +-------------------- + +To enable this feature, uncomment the line in the rc file if your gitolite was +installed recently enough. Otherwise you will need to add these lines to the +end of your rc file, just before the "%RC" block ends: + + ACCESS_1 => [ + 'expand-deny-messages', + ], + + ACCESS_2 => [ + 'expand-deny-messages', + ], + +Please don't miss the trailing commas! + +DISABLING IT FOR SPECIFIC REPOS +------------------------------- + +Once it is enabled at the rc file level, if you wish to disable it for +specific repositories just add a line like this to those repos: + + option ENV.EDM_DISABLE = 1 + +Or you can also disable it for all repos, then enable it for some: + + repo @all + option ENV.EDM_DISABLE = 1 + + # ... then later ... + + repo foo bar @baz + option ENV.EDM_DISABLE = 0 + +(options.html[1] and pages linked from it will explain how that works). + +[1]: http://gitolite.com/gitolite/options.html + +SUPPLYING EXTRA INFORMATION +--------------------------- + +You can also supply some extra information to be printed, by adding a line +like this to each repository in the gitolite.conf file: + + option ENV.EDM_EXTRA_INFO = "please contact alice@example.com" + +You could of course add it under a "repo @all" section if you like. + +SUPPLYING EXTRA INFORMATION FOR VREFs +------------------------------------- + +If you have VREFs that do funky things and you want to **lecture** your users +when they screw up, add something like the following to your VREF code. + + # help start + + Some help text. + + Some more help text. This can be + multi-line. + + (etc etc etc) + + # help end + +Then everything between the "# help start" line and the "# help end" line will +get printed if a users falls afoul of this VREF. If any of the lines shown +are not valid syntax for your language, figure out some way to put the whole +thing in a comment block. Here a C example: + + /* + # help start + line 1 + line 2 + ... + last line + # help end + */ + +Even if your language does not support multi-line comments like C does, there +may be other ways to specify those lines. Here's an example in shell: + + cat << EOF > /dev/null + # help start + line 1 + line 2 + ... + last line + # help end + EOF |