allow access checks from ADC or hook
For sample code see new file contrib/adc/get-rights-and-owner.in-perl. Despite the name, you can use similar code in a hook also -- comments in that file will tell you how. implementation notes: - check_access now takes an optional last arg "dry_run", which is also passes through to check_ref - check_ref returns a "DENIED by ..." instead of die-ing if dry_run is passed in - as a side effect, cli_repo_rights is now just a stub calling check_access (we kept it hanging around for backward compat -- too much adc pain for too many people if we change it now)
This commit is contained in:
parent
f88b097db1
commit
5b9bf700cc
41
contrib/adc/get-rights-and-owner.in-perl
Executable file
41
contrib/adc/get-rights-and-owner.in-perl
Executable file
|
@ -0,0 +1,41 @@
|
||||||
|
#!/usr/bin/perl
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
unshift @INC, $ENV{GL_BINDIR};
|
||||||
|
require gitolite or die "parse gitolite.pm failed\n";
|
||||||
|
|
||||||
|
# get the repo name
|
||||||
|
my $repo = shift;
|
||||||
|
$repo =~ s/\.git$//;
|
||||||
|
# IMPORTANT NOTE: to do any of this inside a hook, you should just use
|
||||||
|
# $ENV{GL_REPO}, since it's guaranteed to be set to the right value
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# to do a "level 1" check (repo level -- not branch level), do this:
|
||||||
|
my ($perm, $creator) = &check_access($repo);
|
||||||
|
# you can pass in any repo name you wish instead of the active repo
|
||||||
|
|
||||||
|
# the first return value looks like one of these, so you can just check for
|
||||||
|
# the presence of "R" or "W" and be done:
|
||||||
|
# _____R___W_
|
||||||
|
# _____R_____
|
||||||
|
# ___________
|
||||||
|
|
||||||
|
# The second value is "<gitolite>" for a normal repo, an actual username for
|
||||||
|
# a wildrepo, or "<notfound>" for a non-existent repo.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
# to do a "level 2" check (branches), do something like this
|
||||||
|
my $ret = &check_access($repo, 'refs/heads/foo', 'W', 1);
|
||||||
|
# the 2nd argument must be a *full* refname (i.e., not "master", but
|
||||||
|
# "refs/heads/master"). The 3rd argument is one of W, +, C, or D. The 4th
|
||||||
|
# argument should be any non-false perl value, like 1.
|
||||||
|
|
||||||
|
# the return value may look like this:
|
||||||
|
# refs/.*
|
||||||
|
# or perhaps this, if you were denied
|
||||||
|
# DENIED by fallthru
|
|
@ -151,21 +151,21 @@ sub check_ref {
|
||||||
# permission must also match the action (W or +) being attempted. If none
|
# permission must also match the action (W or +) being attempted. If none
|
||||||
# of them match, the access is denied.
|
# of them match, the access is denied.
|
||||||
|
|
||||||
# Notice that the function DIES!!! Any future changes that require more
|
# Notice that the function DIES unless a non-false 5th argument is present
|
||||||
# work to be done *after* this, even on failure, can start using return
|
|
||||||
# codes etc., but for now we're happy to just die.
|
|
||||||
|
|
||||||
my ($allowed_refs, $repo, $ref, $perm) = @_;
|
my ($allowed_refs, $repo, $ref, $perm, $dry_run) = @_;
|
||||||
my @allowed_refs = sort { $a->[0] <=> $b->[0] } @{$allowed_refs};
|
my @allowed_refs = sort { $a->[0] <=> $b->[0] } @{$allowed_refs};
|
||||||
for my $ar (@allowed_refs) {
|
for my $ar (@allowed_refs) {
|
||||||
my $refex = $ar->[1];
|
my $refex = $ar->[1];
|
||||||
# refex? sure -- a regex to match a ref against :)
|
# refex? sure -- a regex to match a ref against :)
|
||||||
next unless $ref =~ /^$refex/;
|
next unless $ref =~ /^$refex/;
|
||||||
|
return "DENIED by $refex" if $ar->[2] eq '-' and $dry_run;
|
||||||
die "$perm $ref $ENV{GL_USER} DENIED by $refex\n" if $ar->[2] eq '-';
|
die "$perm $ref $ENV{GL_USER} DENIED by $refex\n" if $ar->[2] eq '-';
|
||||||
|
|
||||||
# as far as *this* ref is concerned we're ok
|
# as far as *this* ref is concerned we're ok
|
||||||
return $refex if ($ar->[2] =~ /\Q$perm/);
|
return $refex if ($ar->[2] =~ /\Q$perm/);
|
||||||
}
|
}
|
||||||
|
return "DENIED by fallthru" if $dry_run;
|
||||||
die "$perm $ref $repo $ENV{GL_USER} DENIED by fallthru\n";
|
die "$perm $ref $repo $ENV{GL_USER} DENIED by fallthru\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -770,10 +770,9 @@ sub expand_wild
|
||||||
|
|
||||||
# helper/convenience routine to get rights and ownership from a shell command
|
# helper/convenience routine to get rights and ownership from a shell command
|
||||||
sub cli_repo_rights {
|
sub cli_repo_rights {
|
||||||
my ($perm, $creator, $wild) = &repo_rights($_[0]);
|
# check_access does a lot more, so just call it. Since it returns perms
|
||||||
$perm =~ s/ /_/g;
|
# and creator separately, just space-join them and print it.
|
||||||
$creator =~ s/^\(|\)$//g;
|
print join(" ", &check_access($_[0])), "\n";
|
||||||
print "$perm $creator\n";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sub can_read {
|
sub can_read {
|
||||||
|
@ -1046,10 +1045,13 @@ sub get_memberships {
|
||||||
|
|
||||||
sub check_access
|
sub check_access
|
||||||
{
|
{
|
||||||
my ($GL_CONF_COMPILED, $repo, $path, $perm) = @_;
|
my ($repo, $ref, $aa, $dry_run) = @_;
|
||||||
my $ref = "NAME/$path";
|
# aa = attempted access
|
||||||
|
|
||||||
&parse_acl($GL_CONF_COMPILED);
|
my ($perm, $creator, $wild) = &repo_rights($repo);
|
||||||
|
$perm =~ s/ /_/g;
|
||||||
|
$creator =~ s/^\(|\)$//g;
|
||||||
|
return ($perm, $creator) unless $ref;
|
||||||
|
|
||||||
# until I do some major refactoring (which will bloat the update hook a
|
# until I do some major refactoring (which will bloat the update hook a
|
||||||
# bit, sadly), this code duplicates stuff in the current update hook.
|
# bit, sadly), this code duplicates stuff in the current update hook.
|
||||||
|
@ -1062,7 +1064,11 @@ sub check_access
|
||||||
push @allowed_refs, @ { $repos{'@all'}{$ENV{GL_USER}} || [] };
|
push @allowed_refs, @ { $repos{'@all'}{$ENV{GL_USER}} || [] };
|
||||||
push @allowed_refs, @ { $repos{$repo}{'@all'} || [] };
|
push @allowed_refs, @ { $repos{$repo}{'@all'} || [] };
|
||||||
|
|
||||||
&check_ref(\@allowed_refs, $repo, $ref, $perm);
|
if ($dry_run) {
|
||||||
|
return &check_ref(\@allowed_refs, $repo, $ref, $aa, $dry_run);
|
||||||
|
} else {
|
||||||
|
&check_ref(\@allowed_refs, $repo, $ref, $aa);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
@ -1092,7 +1098,7 @@ sub ext_cmd_rsync
|
||||||
# ok now check if we're permitted to execute a $perm action on $path
|
# ok now check if we're permitted to execute a $perm action on $path
|
||||||
# (taken as a refex) using rsync.
|
# (taken as a refex) using rsync.
|
||||||
|
|
||||||
&check_access($GL_CONF_COMPILED, 'EXTCMD/rsync', $path, $perm);
|
&check_access('EXTCMD/rsync', "NAME/$path", $perm);
|
||||||
# that should "die" if there's a problem
|
# that should "die" if there's a problem
|
||||||
|
|
||||||
wrap_chdir($RSYNC_BASE);
|
wrap_chdir($RSYNC_BASE);
|
||||||
|
|
Loading…
Reference in a new issue