diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-06-21 16:47:52 +0300 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2013-06-21 17:43:15 +0300 |
commit | 9e6f5e5fe3c9422f5ab7182e88e8cfd05470c86c (patch) | |
tree | 45ded1f54689fb7a9773cf1e594966b087713f3a /gitaclhook | |
parent | 702fcc7b2326c03e20e999dfa606cc471e6744a3 (diff) | |
download | gitaclhook-9e6f5e5fe3c9422f5ab7182e88e8cfd05470c86c.tar.gz gitaclhook-9e6f5e5fe3c9422f5ab7182e88e8cfd05470c86c.tar.bz2 |
gitaclhook: Implement test mode.
Diffstat (limited to 'gitaclhook')
-rwxr-xr-x | gitaclhook | 76 |
1 files changed, 71 insertions, 5 deletions
@@ -24,12 +24,14 @@ use Pod::Usage; gitaclhook - control access to git repositories =head1 SYNOPSIS B<gitaclhook> I<refname> I<old-sha1> I<new-sha1> +B<gitacthook> B<--test> I<REPO> I<USER> I<OP> I<REF> + B<gitaclhook --help> =head1 DESCRIPTION This program is intended to be run as an "update" hook by git. It is called by B<git-receive-pack> with arguments: @@ -170,12 +172,61 @@ Name of the user httpd runs as. Define it if the repository can be accessed via HTTP(S). If B<gitaclhook> is run as this user, it will get the name of the user on behalf of which the update is performed from the environment variable B<REMOTE_USER>. =back +=head1 TEST MODE + +The B<--test> option provides a mechanism for testing access control lists +from the command line. When given this option, B<gitaclhook> expects four +arguments: + +=over 4 + +B<gitacthook> B<--test> I<REPO> I<USER> I<OP> I<REF> + +=back + +I<REPO> is a pathname of the repository to test, I<USER> is the username, +I<OP> is the operation code and I<REF> is the reference. + +=head1 ENVIRONMENT + +The program uses following environment variables: + +=over 4 + +=item B<GIT_UPDATE_DEBUG> + +When set to 1, enables debugging mode. The B<hooks.acldebug> +configuration variable overrides this setting. + +=item B<GIT_DIR> + +Path to the affected repository. + +=back + +If updates are performed via HTTP or HTTPS and the B<hooks.httpd-user> +configuration variable is set, the following two variables are used +to determine the identity of the user: + +=over 4 + +=item B<AUTH_TYPE> + +If this variable is not set or set to an empty value, the program will +deny the update. + +=item B<REMOTE_USER> + +The authenticated name of the user. + +=back + =head1 SEE ALSO B<git-receive-pack>(1). =head1 AUTHOR @@ -240,12 +291,19 @@ sub allow($) { sub info($) { logmsg("INFO", $_[0]); print STDERR "info: $_[0]\n" if $debug; } +sub project_name($) { + my $dir = shift; + + File::Spec->rel2abs($dir) =~ m,/([^/]+)(?:\.git|/\.git)$,; + return $1; +} + sub git_value(@) { my $fd; open($fd,'-|','git',@_); local $_ = <$fd>; chop; @@ -299,13 +357,13 @@ sub check_acl($$$) { my @x = split(/\s+/, $_, 5); deny("unknown keyword", "$filename:$line") unless ($x[0] eq 'allow' || $x[0] eq 'deny'); deny("malformed line", "$filename:$line") unless $#x >= 2; - + next if ($x[1] ne "*" and $x[1] ne $project); next unless match_user($x[2]); next if ($#x >= 3 && index(uc $x[3], $op) == -1); next if ($#x == 4 && !match_ref($x[4])); allow("$filename:$line") if ($x[0] eq 'allow'); @@ -318,38 +376,46 @@ sub check_acl($$$) { #### # Sanity checks unless ($git_dir) { pod2usage(-exitstatus => 0, -verbose => 2) if ($ref eq "--help"); + if ($ref eq "--test") { + deny("--test requires four arguments") unless ($#ARGV == 4); + $ENV{GIT_DIR} = $ARGV[1]; + $user_name = $ARGV[2]; + $op = $ARGV[3]; + deny("invalid op") unless defined($opstr{$op}); + $ref = $ARGV[4]; + check_acl(project_name($ARGV[1]), $op, $ref); + exit(0); + } deny "try \"$0 --help\" for fore info" } $debug = git_value('config', '--bool', 'hooks.acldebug') unless ($debug); $logfile = git_value('config', 'hooks.acllog'); if ($logfile && $logfile !~ /[>|]/) { $logfile = ">>$logfile"; } $quiet = git_value('config', 'hooks.aclquiet') unless ($debug); my $httpdusr = git_value('config', 'hooks.httpd-user'); if (defined($httpdusr) and $user_name eq $httpdusr) { - deny "need authenticated user" unless defined($ENV{AUTH_TYPE}); + deny "need authenticated user" unless $ENV{AUTH_TYPE}; $user_name = $ENV{REMOTE_USER}; } deny "need a ref name" unless $ref; deny "bogus ref $ref" unless $ref =~ s,^refs/,,; deny "bad old value $old" unless $old =~ /^[a-z0-9]{40}$/; deny "bad new value $new" unless $new =~ /^[a-z0-9]{40}$/; deny "no such user" unless $user_name; allow "no change requested" if $old eq $new; -$project_name = File::Spec->rel2abs($git_dir); -$project_name =~ m,/([^/]+)(?:\.git|/\.git)$,; -$project_name = $1; +$project_name = project_name($git_dir); if ($old =~ /^0{40}$/) { $op = 'C'; } elsif ($new =~ /^0{40}$/) { $op = 'D'; } elsif ($ref =~ m,^heads/, && $old eq git_value('merge-base',$old,$new)) { |