allow @groups in setperms command also
This should hopefully be the final step in making wildrepos as close to normal repos as possible. You can now do pretty much anything with them that you can do with normal repos [1] Implementation notes: - compile puts out %groups into the compiled config file regardless of GL_BIG_CONFIG because this feature needs it - wild_repo_rights caches %groups because the part of the %groups hash we care about will not change between calls in the same run ---- [1] **except** use the full-blown config file syntax within the gl-perms file :-) I don't plan to do that; it's too complicated! [2] [2] yeah yeah I know -- famous last words!
This commit is contained in:
parent
34965b1b03
commit
6e2db12302
|
@ -255,28 +255,53 @@ sub new_repo
|
||||||
# metaphysics (like, "is there a god?", "who created me?", etc)
|
# metaphysics (like, "is there a god?", "who created me?", etc)
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
||||||
# "who created this repo", "am I on the R list", and "am I on the RW list"?
|
|
||||||
sub wild_repo_rights
|
|
||||||
{
|
{
|
||||||
my ($repo, $user) = @_;
|
# the following sub needs some persistent data, so we make a closure
|
||||||
# creator
|
my $cache_filled = 0;
|
||||||
my $c = '';
|
my %cached_groups;
|
||||||
if ( -f "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-creater") {
|
|
||||||
my $fh = wrap_open("<", "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-creater");
|
|
||||||
chomp($c = <$fh>);
|
|
||||||
}
|
|
||||||
# $user's R and W rights
|
|
||||||
my ($r, $w); $r = ''; $w = '';
|
|
||||||
if ($user and -f "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-perms") {
|
|
||||||
my $fh = wrap_open("<", "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-perms");
|
|
||||||
my $perms = join ("", <$fh>);
|
|
||||||
if ($perms) {
|
|
||||||
$r = $user if $perms =~ /^\s*R(?=\s).*\s(\@all|$user)(\s|$)/m;
|
|
||||||
$w = $user if $perms =~ /^\s*RW(?=\s).*\s(\@all|$user)(\s|$)/m;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ($c, $r, $w);
|
# "who created this repo", "am I on the R list", and "am I on the RW list"?
|
||||||
|
sub wild_repo_rights
|
||||||
|
{
|
||||||
|
my ($repo, $user) = @_;
|
||||||
|
# pull in basic group info
|
||||||
|
unless ($cache_filled) {
|
||||||
|
local(%repos, %groups);
|
||||||
|
# read group info from compiled config. At the time we're called
|
||||||
|
# this info has not yet been pulled in by the rest of the code, so
|
||||||
|
# we need to do this specially here. However, the info we're
|
||||||
|
# looking for is not subject to variable substitutions so we don't
|
||||||
|
# really care; we just pull it in once and save it for the rest of
|
||||||
|
# the run
|
||||||
|
do $GL_CONF_COMPILED;
|
||||||
|
%cached_groups = %groups;
|
||||||
|
$cache_filled++;
|
||||||
|
}
|
||||||
|
# creator
|
||||||
|
my $c = '';
|
||||||
|
if ( -f "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-creater") {
|
||||||
|
my $fh = wrap_open("<", "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-creater");
|
||||||
|
chomp($c = <$fh>);
|
||||||
|
}
|
||||||
|
# $user's R and W rights
|
||||||
|
my ($r, $w); $r = ''; $w = '';
|
||||||
|
if ($user and -f "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-perms") {
|
||||||
|
my $fh = wrap_open("<", "$ENV{GL_REPO_BASE_ABS}/$repo.git/gl-perms");
|
||||||
|
my $perms = join ("", <$fh>);
|
||||||
|
# $perms is say "R alice @foo @bar\nRW bob @baz" (the entire gl-perms
|
||||||
|
# file). We replace each @foo with $user if $cached_groups{'@foo'}{$user}
|
||||||
|
# exists (i.e., $user is a member of @foo)
|
||||||
|
for my $g ($perms =~ /\s(\@\S+)/g) {
|
||||||
|
$perms =~ s/ $g(?!\S)/ $user/ if $cached_groups{$g}{$user};
|
||||||
|
}
|
||||||
|
if ($perms) {
|
||||||
|
$r = $user if $perms =~ /^\s*R(?=\s).*\s(\@all|$user)(\s|$)/m;
|
||||||
|
$w = $user if $perms =~ /^\s*RW(?=\s).*\s(\@all|$user)(\s|$)/m;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ($c, $r, $w);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
# ----------------------------------------------------------------------------
|
# ----------------------------------------------------------------------------
|
||||||
|
|
|
@ -393,7 +393,7 @@ $dumped_data .= Data::Dumper->Dump([\%repo_config], [qw(*repo_config)]) if %repo
|
||||||
# much...
|
# much...
|
||||||
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
||||||
print $compiled_fh $dumped_data;
|
print $compiled_fh $dumped_data;
|
||||||
if ($GL_BIG_CONFIG and %groups) {
|
if (%groups) {
|
||||||
$dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
|
$dumped_data = Data::Dumper->Dump([\%groups], [qw(*groups)]);
|
||||||
$dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
|
$dumped_data =~ s/\bCREAT[EO]R\b/\$creator/g;
|
||||||
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
$dumped_data =~ s/'(?=[^']*\$(?:creator|readers|writers|gl_user))~?(.*?)'/"$1"/g;
|
||||||
|
|
105
t/out/t01-repo-groups.1b
Normal file
105
t/out/t01-repo-groups.1b
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
$data_version = '1.5';
|
||||||
|
%repos = (
|
||||||
|
'aa' => {
|
||||||
|
'R' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'u1' => [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u2' => [
|
||||||
|
[
|
||||||
|
4,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u3' => [
|
||||||
|
[
|
||||||
|
5,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'bb' => {
|
||||||
|
'R' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'u1' => [
|
||||||
|
[
|
||||||
|
3,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u2' => [
|
||||||
|
[
|
||||||
|
6,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u3' => [
|
||||||
|
[
|
||||||
|
7,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'gitolite-admin' => {
|
||||||
|
'R' => {
|
||||||
|
'tester' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'tester' => 1
|
||||||
|
},
|
||||||
|
'tester' => [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'testing' => {
|
||||||
|
'@all' => [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'R' => {
|
||||||
|
'@all' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'@all' => 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
%groups = (
|
||||||
|
'@g1' => {
|
||||||
|
'aa' => 'master',
|
||||||
|
'bb' => 'master'
|
||||||
|
}
|
||||||
|
);
|
80
t/out/t02-user-groups.1b
Normal file
80
t/out/t02-user-groups.1b
Normal file
|
@ -0,0 +1,80 @@
|
||||||
|
$data_version = '1.5';
|
||||||
|
%repos = (
|
||||||
|
'aa' => {
|
||||||
|
'R' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'u1' => 1,
|
||||||
|
'u2' => 1,
|
||||||
|
'u3' => 1
|
||||||
|
},
|
||||||
|
'u1' => [
|
||||||
|
[
|
||||||
|
2,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u2' => [
|
||||||
|
[
|
||||||
|
3,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'u3' => [
|
||||||
|
[
|
||||||
|
4,
|
||||||
|
'refs/.*',
|
||||||
|
'RW'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'gitolite-admin' => {
|
||||||
|
'R' => {
|
||||||
|
'tester' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'tester' => 1
|
||||||
|
},
|
||||||
|
'tester' => [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
'testing' => {
|
||||||
|
'@all' => [
|
||||||
|
[
|
||||||
|
1,
|
||||||
|
'refs/.*',
|
||||||
|
'RW+'
|
||||||
|
]
|
||||||
|
],
|
||||||
|
'R' => {
|
||||||
|
'@all' => 1
|
||||||
|
},
|
||||||
|
'W' => {
|
||||||
|
'@all' => 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
%groups = (
|
||||||
|
'@g1' => {
|
||||||
|
'u1' => 'master'
|
||||||
|
},
|
||||||
|
'@g2' => {
|
||||||
|
'u2' => 'master',
|
||||||
|
'u3' => 'master'
|
||||||
|
},
|
||||||
|
'@g3' => {
|
||||||
|
'u4' => 'master',
|
||||||
|
'u5' => 'master',
|
||||||
|
'u6' => 'master'
|
||||||
|
}
|
||||||
|
);
|
|
@ -26,7 +26,7 @@ echo "
|
||||||
" | ugc
|
" | ugc
|
||||||
|
|
||||||
catconf
|
catconf
|
||||||
expect_filesame $TESTDIR/out/t01-repo-groups.1
|
expect_filesame $TESTDIR/out/t01-repo-groups.1b
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
$TESTDIR/rollback || die "rollback failed"
|
$TESTDIR/rollback || die "rollback failed"
|
||||||
|
|
|
@ -29,7 +29,7 @@ echo "
|
||||||
" | ugc
|
" | ugc
|
||||||
|
|
||||||
catconf
|
catconf
|
||||||
expect_filesame $TESTDIR/out/t02-user-groups.1
|
expect_filesame $TESTDIR/out/t02-user-groups.1b
|
||||||
|
|
||||||
# ----------
|
# ----------
|
||||||
$TESTDIR/rollback || die "rollback failed"
|
$TESTDIR/rollback || die "rollback failed"
|
||||||
|
|
72
t/t61-setperms-wild
Normal file
72
t/t61-setperms-wild
Normal file
|
@ -0,0 +1,72 @@
|
||||||
|
# vim: syn=sh:
|
||||||
|
for bc in 0 1
|
||||||
|
do
|
||||||
|
cd $TESTDIR
|
||||||
|
$TESTDIR/rollback || die "rollback failed"
|
||||||
|
editrc GL_WILDREPOS 1
|
||||||
|
editrc GL_BIG_CONFIG $bc
|
||||||
|
|
||||||
|
name "INTERNAL"
|
||||||
|
echo "
|
||||||
|
@leads = u1 u2
|
||||||
|
@devs = u1 u2 u3 u4
|
||||||
|
|
||||||
|
@gbar = bar/CREATOR/..*
|
||||||
|
repo @gbar
|
||||||
|
C = @leads
|
||||||
|
RW+ = CREATOR
|
||||||
|
RW = WRITERS
|
||||||
|
R = READERS
|
||||||
|
" | ugc
|
||||||
|
name "nothing set yet"
|
||||||
|
expect_push_ok "master -> master"
|
||||||
|
|
||||||
|
name "u1 auto-creates a repo"
|
||||||
|
runlocal git ls-remote u1:bar/u1/try1
|
||||||
|
expect "Initialized empty Git repository in /home/gitolite-test/repositories/bar/u1/try1.git/"
|
||||||
|
name "default permissions for u2 and u4"
|
||||||
|
runlocal ssh u1 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u2 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u4 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
|
||||||
|
name "@leads can RW try1"
|
||||||
|
echo RW @leads | runlocal ssh u1 setperms bar/u1/try1
|
||||||
|
expect "RW @leads"
|
||||||
|
runlocal ssh u1 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u2 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u4 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
|
||||||
|
name "@devs can R try1"
|
||||||
|
echo R @devs | runlocal ssh u1 setperms bar/u1/try1
|
||||||
|
expect "R @devs"
|
||||||
|
notexpect "RW @leads"
|
||||||
|
runlocal ssh u1 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u2 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
expect R.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u4 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
expect R.*u1.*bar/u1/try1
|
||||||
|
|
||||||
|
name "combo of previous 2"
|
||||||
|
printf "R @devs\nRW @leads\n" | runlocal ssh u1 setperms bar/u1/try1
|
||||||
|
expect "R @devs"
|
||||||
|
expect "RW @leads"
|
||||||
|
runlocal ssh u1 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u2 expand
|
||||||
|
expect R.*W.*u1.*bar/u1/try1
|
||||||
|
runlocal ssh u4 expand
|
||||||
|
notexpect R.*W.*u1.*bar/u1/try1
|
||||||
|
expect R.*u1.*bar/u1/try1
|
||||||
|
|
||||||
|
name "INTERNAL"
|
||||||
|
|
||||||
|
done
|
Loading…
Reference in a new issue