5 use lib
$ENV{GL_LIBDIR
};
8 use Gitolite
::Conf
::Load
;
10 our ( $q, $s, $h ); # quiet, show, help
13 Usage: gitolite access [-q|-s] <repo> <user> <perm> <ref>
15 Print access rights for arguments given. The string printed has the word
16 DENIED in it if access was denied. With '-q', returns only an exit code
17 (shell truth, not perl truth -- 0 is success). For '-s', see below.
21 - perm: defauts to '+'. Valid values: R, W, +, C, D, M
22 - ref: defauts to 'any'. See notes below
25 - ref: something like 'master', or 'refs/tags/v1.0', or even a VREF if you
26 know what they look like.
28 The 'any' ref is special -- it ignores deny rules, thus simulating
29 gitolite's behaviour during the pre-git access check (see 'deny-rules'
30 section in rules.html for details).
32 - batch mode: see src/triggers/post-compile/update-git-daemon-access-list
33 for a good example that shows how to test several repos in one invocation.
34 This is orders of magnitude faster than running the command multiple
35 times; you'll notice if you have more than a hundred or so repos.
37 - '-s' shows the rules (conf file name, line number, and rule) that were
38 considered and how they fared.
40 - you can also test the ability to create wild repos if you set GL_USER to
41 the username and use ^C as the permission to check for.
44 usage
() if not @ARGV or $h;
46 my ( $repo, $user, $aa, $ref ) = @ARGV;
47 # default access is '+'
49 # default ref is 'any'
51 # fq the ref if needed
52 $ref =~ s
(^)(refs
/heads
/) if $ref and $ref ne 'any' and $ref !~ m
(^(refs
|VREF
)/);
53 _die
"invalid perm" if not( $aa and $aa =~ /^(R|W|\+|C|D|M|\^C)$/ );
54 _die
"invalid ref name" if not( $ref and $ref =~ $REPONAME_PATT );
58 if ( $repo ne '%' and $user ne '%' ) {
59 # single repo, single user; no STDIN
60 $ret = access
( $repo, $user, $aa, $ref );
64 if ( $ret =~ /DENIED/ ) {
65 print "$ret\n" unless $q;
69 print "$ret\n" unless $q;
73 $repo = '' if $repo eq '%';
74 $user = '' if $user eq '%';
76 _die
"'-q' and '-s' meaningless in pipe mode" if $q or $s;
80 my $r = $repo || shift @in;
81 my $u = $user || shift @in;
82 $ret = access
( $r, $u, $aa, $ref );
83 print "$r\t$u\t$ret\n";
88 die "repo already exists; ^C won't work\n" if $ret =~ /DENIED by existence/;
90 my $in = $rc{RULE_TRACE
} or die "this should not happen! $ret";
92 print STDERR
"legend:";
94 d => skipped deny rule due to ref unknown or 'any',
95 r => skipped due to refex not matching,
96 p => skipped due to perm (W, +, etc) not matching,
97 D => explicitly denied,
98 A => explicitly allowed,
99 F => denied due to fallthru (no rules matched)
103 my %rule_info = read_ri
($in); # get rule info data for all traced rules
104 # this means conf filename, line number, and content of the line
106 # the rule-trace info is a set of pairs of a number plus a string. Only
107 # the last character in a string is valid (and has meanings shown above).
108 # At the end there may be a final 'f'
109 my @in = split ' ', $in;
112 if ( $in =~ /^\d+$/ ) {
113 my $res = shift @in or die "this should not happen either!";
115 printf " %s %20s:%-6s %s\n", $m,
119 } elsif ( $in eq 'F' ) {
120 printf " %s %20s\n", $in, "(fallthru)";
122 die "and finally, this also should not happen!";
129 my %rules = map { $_ => 1 } $_[0] =~ /(\d+)/g;
130 # contains a series of rule numbers, each of which we must search in
131 # $GL_ADMIN_BASE/.gitolite/conf/rule_info
134 for ( slurp
( $ENV{GL_ADMIN_BASE
} . "/conf/rule_info" ) ) {
135 my ( $r, $f, $l ) = split ' ', $_;
136 next unless $rules{$r};
137 $rule_info{$r}{fn
} = $f;
138 $rule_info{$r}{ln
} = $l;
139 $rule_info{$r}{cl
} = conf_lines
( $f, $l );
141 # a wee bit of optimisation, in case the rule_info file is huge and
142 # what we want is up near the beginning
153 my ( $file, $line ) = @_;
156 unless ( $conf_lines{$file} ) {
157 $conf_lines{$file} = [ slurp
( $ENV{GL_ADMIN_BASE
} . "/conf/$file" ) ];
158 chomp( @
{ $conf_lines{$file} } );
160 return $conf_lines{$file}[$line];