refactored and lifted out the line parse part from inside parse_conf_file
adapted from code by kpfleming@digium.com. I basically cherry-picked the top commit on "pu-work" (30068d1) on his fork at github, and made some minor fixups to it
This commit is contained in:
parent
5f342c0444
commit
7b633049be
|
@ -163,35 +163,12 @@ sub check_fragment_repo_disallowed
|
|||
return 1;
|
||||
}
|
||||
|
||||
sub parse_conf_file
|
||||
sub parse_conf_line
|
||||
{
|
||||
my ($conffile, $fragment) = @_;
|
||||
# the second arg, $fragment, is passed in as "master" when parsing the
|
||||
# main config, and the fragment name when parsing a fragment. In the
|
||||
# latter case, the parser uses that information to ignore (and warn about)
|
||||
# any repos in the fragment that are not members of the "repo group" of
|
||||
# the same name.
|
||||
my %ignored = ();
|
||||
|
||||
my $conf_fh = wrap_open( "<", $conffile );
|
||||
|
||||
# the syntax is fairly simple, so we parse it inline
|
||||
|
||||
my @repos;
|
||||
while (<$conf_fh>)
|
||||
{
|
||||
# kill comments, but take care of "#" inside *simple* strings
|
||||
s/^((".*?"|[^#"])*)#.*/$1/;
|
||||
# normalise whitespace; keeps later regexes very simple
|
||||
s/=/ = /;
|
||||
s/\s+/ /g;
|
||||
s/^ //;
|
||||
s/ $//;
|
||||
# and blank lines
|
||||
next unless /\S/;
|
||||
my ($line, $fragment, $repos_p, $ignored_p) = @_;
|
||||
|
||||
# user or repo groups
|
||||
if (/^(@\S+) = (.*)/)
|
||||
if ($line =~ /^(@\S+) = (.*)/)
|
||||
{
|
||||
die "$ABRT defining groups is not allowed inside fragments\n"
|
||||
if $GL_BIG_CONFIG and $fragment ne 'master';
|
||||
|
@ -201,28 +178,28 @@ sub parse_conf_file
|
|||
die "$ABRT bad group $1\n" unless $1 =~ $REPONAME_PATT;
|
||||
}
|
||||
# repo(s)
|
||||
elsif (/^repo (.*)/)
|
||||
elsif ($line =~ /^repo (.*)/)
|
||||
{
|
||||
# grab the list...
|
||||
@repos = split ' ', $1;
|
||||
unless (@repos == 1 and $repos[0] eq '@all') {
|
||||
@{ $repos_p } = split ' ', $1;
|
||||
unless (@{ $repos_p } == 1 and $repos_p->[0] eq '@all') {
|
||||
# ...expand groups in the default case
|
||||
@repos = expand_list ( @repos ) unless $GL_BIG_CONFIG;
|
||||
@{ $repos_p } = expand_list ( @{ $repos_p } ) unless $GL_BIG_CONFIG;
|
||||
# ...sanity check
|
||||
for (@repos) {
|
||||
for (@{ $repos_p }) {
|
||||
die "$ABRT bad reponame $_\n"
|
||||
if ($GL_WILDREPOS and $_ !~ $REPOPATT_PATT);
|
||||
die "$ABRT bad reponame $_ or you forgot to set \$GL_WILDREPOS\n"
|
||||
if (not $GL_WILDREPOS and $_ !~ $REPONAME_PATT);
|
||||
}
|
||||
}
|
||||
s/\bCREAT[EO]R\b/\$creator/g for @repos;
|
||||
s/\bCREAT[EO]R\b/\$creator/g for @{ $repos_p };
|
||||
}
|
||||
# actual permission line
|
||||
elsif (/^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/)
|
||||
elsif ($line =~ /^(-|C|R|RW\+?(?:C?D?|D?C?)) (.* )?= (.+)/)
|
||||
{
|
||||
my $perms = $1;
|
||||
my @refs; @refs = split(' ', $2) if $2;
|
||||
my @refs; @refs = split( ' ', $2 ) if $2;
|
||||
@refs = expand_list ( @refs );
|
||||
my @users = split ' ', $3;
|
||||
die "$ABRT \$GL_WILDREPOS is not set, you cant use 'C' in config\n" if $perms eq 'C' and not $GL_WILDREPOS;
|
||||
|
@ -246,16 +223,16 @@ sub parse_conf_file
|
|||
s/\bWRITERS\b/\$writers/g for @users;
|
||||
|
||||
# ok, we can finally populate the %repos hash
|
||||
for my $repo (@repos) # each repo in the current stanza
|
||||
for my $repo (@{ $repos_p }) # each repo in the current stanza
|
||||
{
|
||||
# if we're processing a delegated config file (not the master
|
||||
# config), we need to prevent attempts by that admin to obtain
|
||||
# rights on stuff outside his domain
|
||||
|
||||
# trying to set access for $repo (='foo')...
|
||||
if (check_fragment_repo_disallowed($fragment, $repo))
|
||||
if (check_fragment_repo_disallowed( $fragment, $repo ))
|
||||
{
|
||||
$ignored{$fragment}{$repo} = 1;
|
||||
$ignored_p->{$fragment}{$repo} = 1;
|
||||
next;
|
||||
}
|
||||
for my $user (@users)
|
||||
|
@ -299,13 +276,13 @@ sub parse_conf_file
|
|||
}
|
||||
}
|
||||
# configuration
|
||||
elsif (/^config (.+) = ?(.*)/)
|
||||
elsif ($line =~ /^config (.+) = ?(.*)/)
|
||||
{
|
||||
my ($key, $value) = ($1, $2);
|
||||
my @validkeys = split (' ', ($GL_GITCONFIG_KEYS || ''));
|
||||
my @validkeys = split(' ', ($GL_GITCONFIG_KEYS || '') );
|
||||
my @matched = grep { $key =~ /^$_$/ } @validkeys;
|
||||
die "$ABRT git config $key not allowed\n" if (@matched < 1);
|
||||
for my $repo (@repos) # each repo in the current stanza
|
||||
for my $repo (@{ $repos_p }) # each repo in the current stanza
|
||||
{
|
||||
$repo_config{$repo}{$key} = $value;
|
||||
# no problem if it's a plain repo (non-pattern, non-groupname)
|
||||
|
@ -320,30 +297,69 @@ sub parse_conf_file
|
|||
}
|
||||
}
|
||||
# include
|
||||
elsif (/^include "(.+)"/)
|
||||
elsif ($line =~ /^include "(.+)"/)
|
||||
{
|
||||
my $file = $1;
|
||||
$file = "$GL_ADMINDIR/conf/$file" unless $file =~ /^\//;
|
||||
die "$WARN $fragment attempting to include configuration\n" if $fragment ne 'master';
|
||||
die "$ABRT included file not found: '$file'\n" unless -f $file;
|
||||
|
||||
parse_conf_file($file, $fragment);
|
||||
parse_conf_file( $file, $fragment );
|
||||
}
|
||||
# very simple syntax for the gitweb description of repo; one of:
|
||||
# reponame = "some description string"
|
||||
# reponame "owner name" = "some description string"
|
||||
elsif (/^(\S+)(?: "(.*?)")? = "(.*)"$/)
|
||||
elsif ($line =~ /^(\S+)(?: "(.*?)")? = "(.*)"$/)
|
||||
{
|
||||
my ($repo, $owner, $desc) = ($1, $2, $3);
|
||||
die "$ABRT bad repo name $repo\n" unless $repo =~ $REPONAME_PATT;
|
||||
die "$WARN $fragment attempting to set description for $repo\n" if check_fragment_repo_disallowed($fragment, $repo);
|
||||
die "$WARN $fragment attempting to set description for $repo\n" if check_fragment_repo_disallowed( $fragment, $repo );
|
||||
$desc{"$repo.git"} = $desc;
|
||||
$owner{"$repo.git"} = $owner || '';
|
||||
}
|
||||
else
|
||||
{
|
||||
die "$ABRT can't make head or tail of '$_'\n";
|
||||
die "$ABRT can't make head or tail of '$line'\n";
|
||||
}
|
||||
}
|
||||
|
||||
sub cleanup_conf_line
|
||||
{
|
||||
my ($line) = @_;
|
||||
|
||||
# kill comments, but take care of "#" inside *simple* strings
|
||||
$line =~ s/^((".*?"|[^#"])*)#.*/$1/;
|
||||
# normalise whitespace; keeps later regexes very simple
|
||||
$line =~ s/=/ = /;
|
||||
$line =~ s/\s+/ /g;
|
||||
$line =~ s/^ //;
|
||||
$line =~ s/ $//;
|
||||
return $line;
|
||||
}
|
||||
|
||||
sub parse_conf_file
|
||||
{
|
||||
my ($conffile, $fragment) = @_;
|
||||
# the second arg, $fragment, is passed in as "master" when parsing the
|
||||
# main config, and the fragment name when parsing a fragment. In the
|
||||
# latter case, the parser uses that information to ignore (and warn about)
|
||||
# any repos in the fragment that are not members of the "repo group" of
|
||||
# the same name.
|
||||
my %ignored = ();
|
||||
|
||||
my $conf_fh = wrap_open( "<", $conffile );
|
||||
|
||||
# the syntax is fairly simple, so we parse it inline
|
||||
|
||||
my @repos;
|
||||
my $line;
|
||||
while (<$conf_fh>)
|
||||
{
|
||||
$line = cleanup_conf_line($_);
|
||||
# skip blank lines
|
||||
next unless $line =~ /\S/;
|
||||
|
||||
parse_conf_line( $line, $fragment, \@repos, \%ignored );
|
||||
}
|
||||
for my $ig (sort keys %ignored)
|
||||
{
|
||||
|
|
Loading…
Reference in a new issue