gl-perms handling and roles, first cut

(additional memberships that user has when accessing a specific repo)
This commit is contained in:
Sitaram Chamarty 2012-03-17 12:25:38 +05:30
parent 9650d2fb3f
commit 941de722da
3 changed files with 94 additions and 19 deletions

View file

@ -205,7 +205,7 @@ sub load_1 {
my @rules = (); my @rules = ();
my @repos = memberships( 'repo', $repo ); my @repos = memberships( 'repo', $repo );
my @users = memberships( 'user', $user ); my @users = memberships( 'user', $user, $repo );
trace( 3, "memberships: " . scalar(@repos) . " repos and " . scalar(@users) . " users found" ); trace( 3, "memberships: " . scalar(@repos) . " repos and " . scalar(@users) . " users found" );
for my $r (@repos) { for my $r (@repos) {
@ -235,44 +235,109 @@ sub load_1 {
} }
sub memberships { sub memberships {
my $type = shift; trace( 3, @_ );
my $item = shift; my ($type, $base, $repo) = @_;
my $item2 = ''; my $base2 = '';
trace( 3, $type, $item );
my @ret = ( $item, '@all' ); my @ret = ( $base, '@all' );
if ( $type eq 'repo' ) { if ( $type eq 'repo' ) {
my $f = "$rc{GL_REPO_BASE}/$item.git/gl-creator"; # first, if a repo, say, pub/sitaram/project, has a gl-creator file
if ( -f $f ) { # that says "sitaram", find memberships for pub/CREATOR/project also
my $creator; $base2 = generic_name($base);
chomp( $creator = slurp($f) );
( $item2 = $item ) =~ s(/$creator/)(/CREATOR/); # second, you need to check in %repos also
$item2 = '' if $item2 eq $item; # no change
}
for my $i ( keys %repos ) { for my $i ( keys %repos ) {
if ( $item eq $i or $item =~ /^$i$/ or $item2 and ( $item2 eq $i or $item2 =~ /^$i$/ ) ) { if ( $base eq $i or $base =~ /^$i$/ or $base2 and ( $base2 eq $i or $base2 =~ /^$i$/ ) ) {
push @ret, $i; push @ret, $i;
} }
} }
} }
for my $i ( keys %groups ) { for my $i ( keys %groups ) {
if ( $item eq $i or $item =~ /^$i$/ or $item2 and ( $item2 eq $i or $item2 =~ /^$i$/ ) ) { if ( $base eq $i or $base =~ /^$i$/ or $base2 and ( $base2 eq $i or $base2 =~ /^$i$/ ) ) {
push @ret, @{ $groups{$i} }; push @ret, @{ $groups{$i} };
} }
} }
if ( $type eq 'user' and $repo ) {
# find the roles this user has when accessing this repo and add those
# in as groupnames he is a member of. You need the already existing
# memberships for this; see below this function for an example
push @ret, user_roles($base, $repo, @ret);
}
@ret = @{ sort_u( \@ret ) }; @ret = @{ sort_u( \@ret ) };
trace( 3, sort @ret ); trace( 3, sort @ret );
return @ret; return @ret;
} }
=for example
conf/gitolite.conf:
@g1 = u1
@g2 = u1
# now user is a member of both g1 and g2
gl-perms for repo being accessed:
READERS @g1
This should result in @READERS being added to the memberships that u1 has
(when accessing this repo). So we send the current list (@g1, @g2) to
user_roles(), otherwise it has to redo that logic.
=cut
sub data_version_mismatch { sub data_version_mismatch {
return $data_version ne glrc('current-data-version'); return $data_version ne glrc('current-data-version');
} }
sub user_roles {
my ($user, $repo, @eg) = @_;
# eg == existing groups (that user is already known to be a member of)
my %eg = map { $_ => 1 } @eg;
my %ret = ();
my $f = "$rc{GL_REPO_BASE}/$repo.git/gl-perms";
if ( -f $f ) {
my $fh = _open("<", $f);
while (<$fh>) {
chomp;
# READERS u3 u4 @g1
s/^\s+//; s/ +$//; s/=/ /; s/\s+/ /g; s/\@//;
my ($role, @members) = split;
# role = READERS, members = u3, u4, @g1
if (not $rc{ROLES}{$role}) {
_warn "role '$role' not allowed, ignoring";
next;
}
for my $m (@members) {
if ($m !~ $USERNAME_PATT) {
_warn "ignoring '$m' in perms line";
next;
}
# if user eq u3/u4, or is a member of @g1, he has role READERS
$ret{'@' . $role} = 1 if $m eq $user or $eg{$m};
}
}
}
return keys %ret;
}
sub generic_name {
my $base = shift;
my $base2 = '';
my $f = "$rc{GL_REPO_BASE}/$base.git/gl-creator";
if ( -f $f ) {
my $creator;
chomp( $creator = slurp($f) );
( $base2 = $base ) =~ s(/$creator/)(/CREATOR/);
$base2 = '' if $base2 eq $base; # if there was no change
}
return $base2;
}
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------
# api functions # api functions
# ---------------------------------------------------------------------- # ----------------------------------------------------------------------

View file

@ -200,7 +200,7 @@ sub new_wild_repo {
_chdir( $rc{GL_REPO_BASE} ); _chdir( $rc{GL_REPO_BASE} );
new_repo($repo); new_repo($repo);
_print( "$repo.git/gl-creator", $user ); _print( "$repo.git/gl-creator", $user );
# XXX _print("$repo.git/gl-perms", "$rc{WILDREPOS_DEFAULT_PERMS}\n") if $rc{WILDREPOS_DEFAULT_PERMS}; _print( "$repo.git/gl-perms", "$rc{DEFAULT_ROLE_PERMS}\n" ) if $rc{DEFAULT_ROLE_PERMS};
# XXX git config, daemon, web... # XXX git config, daemon, web...
# XXX pre-create, post-create # XXX pre-create, post-create
_chdir( $rc{GL_ADMIN_BASE} ); _chdir( $rc{GL_ADMIN_BASE} );

View file

@ -179,13 +179,23 @@ __DATA__
# configuration variables for gitolite # configuration variables for gitolite
# This file is in perl syntax. But you do NOT need to know perl to edit it -- # This file is in perl syntax. But you do NOT need to know perl to edit it --
# just mind the commas and make sure the brackets and braces stay matched up! # just mind the commas, use single quotes unless you know what you're doing,
# and make sure the brackets and braces stay matched up!
# (Tip: perl allows a comma after the last item in a list also!) # (Tip: perl allows a comma after the last item in a list also!)
%RC = ( %RC = (
UMASK => 0077, UMASK => 0077,
GIT_CONFIG_KEYS => "", GIT_CONFIG_KEYS => '',
# add more roles (like MANAGER, TESTER, ...) here
ROLES =>
{
READERS => 1,
WRITERS => 1,
},
# uncomment (and change) this if you wish
# DEFAULT_ROLE_PERMS => 'READERS @all',
# comment out or uncomment as needed # comment out or uncomment as needed
# these will run in sequence during the conf file parse # these will run in sequence during the conf file parse