#!/usr/bin/perl use strict; use warnings; use lib $ENV{GL_LIBDIR}; use Gitolite::Rc; use Gitolite::Common; use Gitolite::Conf::Load; =for usage Usage: ssh git@host perms -l ssh git@host perms - ssh git@host perms + List or set permissions for user-created ("wild") repo. The first usage shown will list the current contents of the permissions file. The other two will change permissions, adding or removing a user from a role. Examples: ssh git@host perms foo + READERS user1 ssh git@host perms foo + READERS user2 ssh git@host perms foo + READERS user3 ---- There is also a batch mode useful for scripting and bulk loading. Do not combine this with the +/- mode above. This mode also accepts an optional "-c" flag to create the repo if it does not already exist (assuming $GL_USER has permissions to create it). Examples: cat copy-of-backed-up-gl-perms | ssh git@host perms cat copy-of-backed-up-gl-perms | ssh git@host perms -c =cut usage() if not @ARGV or $ARGV[0] eq '-h'; $ENV{GL_USER} or _die "GL_USER not set"; my $generic_error = "repo does not exist, or you are not authorised"; my $list = 0; if ( $ARGV[0] eq '-l' ) { $list++; shift; getperms(@ARGV); # doesn't return } # auto-create the repo if -c passed and repo doesn't exist if ( $ARGV[0] eq '-c' ) { shift; my $repo = $ARGV[0] or usage(); _die "invalid repo '$repo'" unless $repo =~ $REPONAME_PATT; if (not -d "$rc{GL_REPO_BASE}/$repo.git") { my $ret = access( $repo, $ENV{GL_USER}, '^C', 'any' ); _die $generic_error if $ret =~ /DENIED/; require Gitolite::Conf::Store; Gitolite::Conf::Store->import; new_wild_repo( $repo, $ENV{GL_USER}, 'perms-c' ); gl_log( 'create', $repo, $ENV{GL_USER}, 'perms-c' ); } } my $repo = shift; setperms(@ARGV); _system( "gitolite", "trigger", "POST_CREATE", $repo, $ENV{GL_USER}, 'perms' ); # ---------------------------------------------------------------------- sub getperms { my $repo = shift; _die $generic_error if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; my $pf = "$rc{GL_REPO_BASE}/$repo.git/gl-perms"; print slurp($pf) if -f $pf; exit 0; } sub setperms { _die $generic_error if repo_missing($repo) or creator($repo) ne $ENV{GL_USER}; my $pf = "$rc{GL_REPO_BASE}/$repo.git/gl-perms"; if ( not @_ ) { # legacy mode; pipe data in print STDERR "'batch' mode started, waiting for input (run with '-h' for details).\n"; print STDERR "Please hit Ctrl-C if you did not intend to do this.\n"; @ARGV = (); my @a; for (<>) { _die "Invalid role '$1'; check the rc file" if /(\S+)/ and not $rc{ROLES}{$1}; push @a, $_; } print STDERR "\n"; # make sure Ctrl-C gets caught _print( $pf, @a ); return; } _die "Invalid syntax. Please re-run with '-h' for detailed usage" if @_ != 3; my ( $op, $role, $user ) = @_; _die "Invalid syntax. Please re-run with '-h' for detailed usage" if $op ne '+' and $op ne '-'; _die "Invalid role '$role'; check the rc file" if not $rc{ROLES}{$role}; _die "Invalid user '$user'" if not $user =~ $USERNAME_PATT; my $text = ''; my @text = slurp($pf) if -f $pf; my $present = grep { $_ eq "$role $user\n" } @text; if ( $op eq '-' ) { if ( not $present ) { _warn "'$role $user' was not present in file"; } else { @text = grep { $_ ne "$role $user\n" } @text; _print( $pf, @text ); } } else { if ($present) { _warn "'$role $user' already present in file"; } else { push @text, "$role $user\n"; @text = sort @text; _print( $pf, @text ); } } }