diff --git a/conf/example.conf b/conf/example.conf index 8f018ee..86fdeca 100644 --- a/conf/example.conf +++ b/conf/example.conf @@ -4,6 +4,7 @@ # - everything in this is space-separated; no commas, semicolons, etc # - comments in the normal shell-ish style; no surprises there # - there are no continuation lines of any kind +# - user/repo names as simple as possible # objectives, over and above gitosis: # - simpler syntax @@ -12,17 +13,19 @@ # - allows branch level control # ---------------------------------------------------------------------------- -# USERS and GROUPS +# LISTS # syntax: -# @groupname = username [...] +# @listname = name [...] +# lists can be used as shorthand for usernames as well as reponames -# usernames and groupnames should be as simple as possible - -# too many users in one group? just add more such lines -# (they accumulate, like squid ACLs) +# a list is equivalent to typing out all the right hand side names, so why do +# we need lists at all? (1) to be able to reuse the same set of usernames in +# the paras for different repos, (2) to keep the lines short, because lists +# accumulate, like squid ACLs, so you can say: @cust_A = cust1 cust2 @cust_A = cust99 +# and this is the same as listing all three on the same line # you can nest groups, but not recursively of course! @interns = indy james @@ -31,11 +34,15 @@ @staff = me alice @secret_staff = bruce whitfield martin +@pubrepos = linux git + +@privrepos = supersecretrepo anothersecretrepo + # ---------------------------------------------------------------------------- # REPOS, REFS, and PERMISSIONS # syntax: -# repo [one or more reponames] +# repo [one or more repos] # (R|RW|RW+) [zero or more refnames] = [one or more users] # notes: @@ -51,8 +58,9 @@ # - prefixed by "refs/heads/" if it doesn't start with "refs/" # (i.e., tags have to be explicitly named as refs/tags/pattern) -# - the list of users can inlude any group name defined earlier -# - "@all" is a special, predefined, groupname +# - the list of users or repos can inlude any group name defined earlier +# - "@all" is a special, predefined, groupname that means "all users" +# (there is no corresponding shortcut for all repos) # anyone can play in the sandbox, including making non-fastforward commits # (that's what the "+" means) @@ -72,7 +80,7 @@ repo cust_A_repo # idea for the tags syntax shamelessly copied from git.git # Documentation/howto/update-hook-example.txt :) -repo secret +repo @privrepos thirdsecretrepo RW+ pu = bruce RW master next = bruce RW refs/tags/v[0-9].* = bruce diff --git a/doc/0-UPGRADE.mkd b/doc/0-UPGRADE.mkd index 4d55ac0..9b0d9a5 100644 --- a/doc/0-UPGRADE.mkd +++ b/doc/0-UPGRADE.mkd @@ -37,6 +37,13 @@ And you're done. If any extra steps beyond the generic ones above are needed, they will be listed here, newest first. +#### upgrading from 5758f69 + +Between 5758f69 and this version, gitolite learnt to allow "groupnames" for +repos as well. The `conf/example.conf` has been recommented to explain the +syntax but it's really a no-brainer: what you could previously do only for +usernames, you can now do for reponames also. + #### upgrading from abb4580 Two new features (personal branches, and customisable logfile names/locations) diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 69bbb75..d8a583b 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -58,8 +58,11 @@ die "$ATTN parse $glrc failed: " . ($! or $@) unless do $glrc; # command and options for authorized_keys my $AUTH_COMMAND="$GL_ADMINDIR/src/gl-auth-command"; my $AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty"; -my $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern +# note that REPONAME_PATT allows a "/" also, which USERNAME_PATT doesn't +my $REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern +my $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern +# groups can now represent user groups or repo groups my %groups = (); my %repos = (); @@ -80,14 +83,16 @@ sub wrap_open { return $fh; } -sub expand_userlist +sub expand_list { my @list = @_; my @new_list = (); for my $item (@list) { - die "$ATTN bad user $item\n" unless $item =~ $USERNAME_PATT; + # we test with the slightly more relaxed pattern here; we'll catch the + # "/" in user name thing later; it doesn't affect security anyway + die "$ATTN bad user or repo name $item\n" unless $item =~ $REPONAME_PATT; if ($item =~ /^@/) # nested group { die "$ATTN undefined group $item\n" unless $groups{$item}; @@ -124,16 +129,19 @@ while (<$conf_fh>) # and blank lines next unless /\S/; - # user groups + # user or repo groups if (/^(@\S+) = (.*)/) { - push @{ $groups{$1} }, expand_userlist( split(' ', $2) ); - die "$ATTN bad group $1\n" unless $1 =~ $USERNAME_PATT; + push @{ $groups{$1} }, expand_list( split(' ', $2) ); + # again, we take the more "relaxed" pattern + die "$ATTN bad group $1\n" unless $1 =~ $REPONAME_PATT; } # repo(s) elsif (/^repo (.*)/) { - @repos = split(' ', $1); + # grab the list and expand any @stuff in it + @repos = split ' ', $1; + @repos = expand_list ( @repos ); } # actual permission line elsif (/^(R|RW|RW\+) (.* )?= (.+)/) @@ -150,8 +158,9 @@ while (<$conf_fh>) @refs = map { m(^refs/) or s(^)(refs/heads/); $_ } @refs; # expand the user list, unless it is just "@all" - @users = expand_userlist ( @users ) + @users = expand_list ( @users ) unless (@users == 1 and $users[0] eq '@all'); + do { die "$ATTN bad username $_\n" unless $_ =~ $USERNAME_PATT } for @users; # ok, we can finally populate the %repos hash for my $repo (@repos) # each repo in the current stanza