1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
|
#!/usr/bin/perl
use 5.10.0;
# ---- WARNING ----
# If your site makes a distinction between "right to push the admin repo" and
# "right to run arbitrary commands on the server" (i.e., if not all of your
# "admins" have shell access to the server), this is a security risk. If that
# is the case, DO NOT ENABLE THIS COMMAND.
# ----------------------------------------------------------------------
# gitolite command to allow "git config" on repos (with some restrictions)
# (Not to be confused with the 'git-config' command, which is used only in
# server-side scripts, not remotely.)
# setup:
# 1. Enable the command by adding it to the COMMANDS section in the ENABLE
# list in the rc file. (Have you read the warning above?)
#
# 2. Specify configs allowed to be changed by the user. This is a space
# separated regex list. For example:
# repo ...
# ... (various rules) ...
# option user-configs = hook\..* foo.bar[0-9].*
use strict;
use warnings;
use lib $ENV{GL_LIBDIR};
use Gitolite::Easy;
use Gitolite::Common;
# ----------------------------------------------------------------------
# usage
=for usage
Usage: ssh git@host config <repo> [git config options]
Runs "git config" in the repo. Only the following 3 syntaxes are supported
(see 'man git-config'):
--add name value
--get-all name
--unset-all name
--list
Your administrator should tell you what keys are allowed for the "name".
=cut
# ----------------------------------------------------------------------
# arg checks
my %nargs = qw(
--add 3
--get-all 2
--unset-all 2
--list 1
);
usage() if not @ARGV or $ARGV[0] eq '-h';
my $repo = shift;
my $op = shift;
usage() unless $op and exists $nargs{$op};
# ----------------------------------------------------------------------
# authorisation checks
die "sorry, you are not authorised\n" unless
owns($repo)
or
( ( $op eq '--get-all' or $op eq '--list' )
? can_read($repo)
: ( can_write($repo) and option( $repo, 'writer-is-owner' ) )
);
# ----------------------------------------------------------------------
# key validity checks
unless ($op eq '--list') {
my $key = shift;
my $val = '';
$val = join(" ", @ARGV) if @ARGV;
# values with spaces embedded get flattened by sshd when it passes
# SSH_ORIGINAL_COMMAND to gitolite. In this specific instance, we will
# pretend we know what the user meant, and join up the last 1+ args into
# one space-separated arg.
my $user_configs = option( $repo, 'user-configs' );
# this is a space separated list of allowed config keys
my @validkeys = split( ' ', ( $user_configs || '' ) );
my @matched = grep { $key =~ /^$_$/i } @validkeys;
_die "config '$key' not allowed\n" if ( @matched < 1 );
@ARGV = ($key);
push @ARGV, $val if $val;
}
# ----------------------------------------------------------------------
# go!
unshift @ARGV, $op;
usage() unless @ARGV == $nargs{$op};
_chdir("$rc{GL_REPO_BASE}/$repo.git");
_system( "git", "config", @ARGV );
|