6a44c564a2
thanks to Ilari for helping fix a bug (see previous commit) and then prompting this documentation
287 lines
10 KiB
Markdown
287 lines
10 KiB
Markdown
# repositories named with wildcards
|
|
|
|
***IMPORTANT NOTE***:
|
|
|
|
This feature may be somewhat "brittle" in terms of security. Creating
|
|
repositories based on wild cards, giving "ownership" to the specific user who
|
|
created it, allowing him/her to hand out R and RW permissions to other users
|
|
to collaborate, all these are possible. And any of these could have a bug in
|
|
it. I haven't found any yet, but that doesn't mean there aren't any.
|
|
|
|
Also, there are some limitations. For example, you cannot specify gitconfig
|
|
values for a wildcard repo; it only works for actual repos.
|
|
|
|
There may be other such missing features. Sometimes it's just not possible to
|
|
make it work. Or it may be cumbersome enough that unless there are *no*
|
|
workarounds I may not have the time to code it right away.
|
|
|
|
----
|
|
|
|
In this document:
|
|
|
|
* wildcard repos
|
|
* wildcard repos with creater name in them
|
|
* wildcard repos without creater name in them
|
|
* side-note: line-anchored regexes
|
|
* contrast with refexes
|
|
* handing out rights to wildcard-matched repos
|
|
* setting a gitweb description for a wildcard-matched repo
|
|
* reporting
|
|
* other issues and discussion
|
|
* how it actually works
|
|
|
|
This document is mostly "by example".
|
|
|
|
----
|
|
|
|
### Wildcard repos
|
|
|
|
Which of these alternatives you choose depends on your needs, and the social
|
|
aspects of your environment. The first one is a little more rigid, making it
|
|
harder to make mistakes, and the second is more flexible and trusting.
|
|
|
|
#### Wildcard repos with creater name in them
|
|
|
|
Here's an example snippet:
|
|
|
|
@prof = u1
|
|
@TAs = u2 u3
|
|
@students = u4 u5 u6
|
|
|
|
repo assignments/CREATER/a[0-9][0-9]
|
|
C = @students
|
|
RW+ = CREATER
|
|
RW = WRITERS @TAs
|
|
R = READERS @prof
|
|
|
|
For now, ignore the special usernames READERS and WRITERS, and just create a
|
|
new repo, as user "u4" (a student):
|
|
|
|
$ git clone git@server:assignments/u4/a12
|
|
Initialized empty Git repository in /home/sitaram/t/a12/.git/
|
|
Initialized empty Git repository in /home/gitolite/repositories/assignments/u4/a12.git/
|
|
warning: You appear to have cloned an empty repository.
|
|
|
|
Notice the *two* empty repo inits, and the order in which they occur ;-)
|
|
|
|
#### Wildcard repos without creater name in them
|
|
|
|
Here's how the same example would look if you did not want the CREATER's name
|
|
to be part of the actual repo name.
|
|
|
|
repo assignments/a[0-9][0-9]
|
|
C = @students
|
|
RW+ = CREATER
|
|
RW = WRITERS @TAs
|
|
R = READERS @prof
|
|
|
|
We haven't changed anything except the repo name pattern. This means that the
|
|
first student that creates, say, `assignments/a12` becomes the owner.
|
|
Mistakes (such as claiming a12 instead of a13) need to be rectified by an
|
|
admin logging on to the back end, though it's not too difficult.
|
|
|
|
You could also repace the C line like this:
|
|
|
|
C = @TAs
|
|
|
|
and have a TA create the repos in advance.
|
|
|
|
In either case, they could then use the `setperms` feature to specify which
|
|
users are "READERS" and which are "WRITERS". See later for details.
|
|
|
|
### Side-note: Line-anchored regexes
|
|
|
|
A regex like
|
|
|
|
repo assignments/S[0-9]+/A[0-9]+
|
|
|
|
would match `assignments/S02/A37`. It will not match `assignments/S02/ABC`,
|
|
or `assignments/S02/a37`, obviously.
|
|
|
|
But you may be surprised to find that it does not match even
|
|
`assignments/S02/A37/B99`. This is because internally, gitolite
|
|
*line-anchors* the given regex; so that regex actually becomes
|
|
`^assignments/S[0-9]+/A[0-9]+$` -- notice the line beginning and ending
|
|
metacharacters.
|
|
|
|
#### Contrast with refexes
|
|
|
|
Just for interest, note that this is in contrast to the refexes for the normal
|
|
"branch" permissions, as described in `conf/example.conf` and elsewhere.
|
|
Those "refexes" are *not* anchored; a pattern like `refs/heads/master`
|
|
actually matches `foo/refs/heads/master01/bar` as well, even if no one will
|
|
actually push such a branch! You can anchor it if you really care, by using
|
|
`master$` instead of `master`, but anchoring is *not* the default for
|
|
refexes.]
|
|
|
|
### Handing out rights to wildcard-matched repos
|
|
|
|
In the examples above, we saw two special "user" names: READERS and WRITERS.
|
|
The permissions they have are controlled by the config file, but ***who is
|
|
part of this list*** is controlled by the person who created the repository.
|
|
|
|
The use case is that, although our toy example has only 3 students, in reality
|
|
there will be a few dozen, but each assignment will be worked on only by a
|
|
handful from among those. This allows the creater to take ad hoc sets of
|
|
users from among the actual users in the system, and place them into one of
|
|
two categories (whose permissions are, in this example, R and RW
|
|
respectively). In theory you could do the same thing by creating lots of
|
|
little "assignment-NN" groups in the config file but that may be a little too
|
|
cumbersome for non-secret environments.
|
|
|
|
Create a small text file that contains the permissions you desire:
|
|
|
|
$ cat > myperms
|
|
R u5
|
|
RW u6
|
|
(hit ctrl-d here)
|
|
|
|
...and use the new "setperms" command to set permissions for your repo:
|
|
|
|
$ ssh git@server setperms assignments/u4/a12 < myperms
|
|
New perms are:
|
|
R u5
|
|
RW u6
|
|
|
|
'setperms' will helpfully print what the new permissions are but you can also
|
|
use 'getperms' to check:
|
|
|
|
$ ssh git@server getperms assignments/u4/a12
|
|
R u5
|
|
RW u6
|
|
|
|
The following points are important:
|
|
|
|
* note the syntax of the commands; it's not a "git" command, and there's no
|
|
`:` like in a repo URL. The first space-separated word is R or RW, and
|
|
the rest are simple usernames.
|
|
|
|
* whoever you specify as "R" will match the special user READERS. "RW" will
|
|
match WRITERS.
|
|
|
|
### setting a gitweb description for a wildcard-matched repo
|
|
|
|
Similar to the getperm/setperm commands, there are the getdesc/setdesc
|
|
commands, thanks to Teemu.
|
|
|
|
### reporting
|
|
|
|
Remember the cool stuff you see when you just do `ssh git@server` (grep for
|
|
"myrights" in `doc/3-faq-tips-etc.mkd` if you forgot, or go [here][mr]).
|
|
|
|
[mr]: http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#myrights
|
|
|
|
This still works, except the format is a little more compressed to accommodate
|
|
a new column (at the start) for "C" permissions, which indicate that you are
|
|
allowed to *create* repos matching that pattern.
|
|
|
|
In addition, there is also the "expand" command, which takes any regex pattern
|
|
and returns you a list of all wildcard-created repos that you have access to
|
|
which fit that pattern. And if, as an administrator, you wish to list out
|
|
*every single* repo that your users have created, add this to your config
|
|
file:
|
|
|
|
repo @all
|
|
R = sitaram # or whoever you are
|
|
|
|
Push the config, then try
|
|
|
|
ssh gitolite expand
|
|
|
|
### other issues and discussion
|
|
|
|
* *what if the repo name being pushed matches more than one pattern*?
|
|
|
|
I think it would be very hard to reason about access if we were to do
|
|
something like combine all the access rights in all the matching patterns.
|
|
No matter how you do it, and how carefully you document it, there'll be
|
|
someone who is surprised by the result.
|
|
|
|
And in security, that's a ***Bad Thing***.
|
|
|
|
So we don't combine permissions. At runtime, we die if we find more than
|
|
one match. Let 'em go holler at the admin for creating multiple matching
|
|
repo patterns :-)
|
|
|
|
This can make some repos inaccessible if the patterns changed *after* they
|
|
were created. The administrator should be careful not to do this. Most
|
|
of the time, it won't be difficult; the fixed prefix will usually be
|
|
different anyway so there won't be overlaps.
|
|
|
|
### how it actually works
|
|
|
|
This section tells you what is happening inside gitolite so you can understand
|
|
this feature better. Let's use the config example at the beginning of this
|
|
document:
|
|
|
|
repo assignments/CREATER/a[0-9][0-9]
|
|
C = @students
|
|
RW+ = CREATER
|
|
RW = WRITERS @TAs
|
|
R = READERS @prof
|
|
|
|
First we find the set of rules to apply. This involves replacing the special
|
|
words CREATER, WRITERS, and READERS with appropriate usernames to derive an
|
|
"effective" ruleset for the repo in question.
|
|
|
|
For a **new** repo, replace the word CREATER in all repo patterns and rules
|
|
with the name of the invoking user.
|
|
|
|
> (Note: this is why you should never use `C = CREATER`; it becomes `C =
|
|
> invoking_user`! Unless you really want to allow *all* users to create
|
|
> repos, you should restrict "C" perms to an actual user or set of users,
|
|
> like in the examples in this document).
|
|
|
|
For an **existing** repo, do the same but replace with the name of the user
|
|
who actually *created* the repo (this name is recorded in a special file in
|
|
the repo directory when the repo is first created, so it is available).
|
|
|
|
Now find a repo pattern that matches the actual reponame being pushed -- this
|
|
tells you which set of rules to apply. Only one pattern is allowed to match;
|
|
matching more than one is an error.
|
|
|
|
If the invoking user has been given "RW" permissions using `setperms`, all
|
|
occurrences of the word WRITERS are replaced by the invoking username.
|
|
Otherwise -- and this includes the "new repo" case, since you couldn't have
|
|
run `setperms` on a non-existant repo -- they are replaced by "NOBODY".
|
|
|
|
(The same thing is done with "R" access and the word "READERS".)
|
|
|
|
At this point we have an effective ruleset, and the normal access rules (R,
|
|
RW, etc) apply, with the addition that the invoking user needs "C" access to
|
|
be able to create a repo.
|
|
|
|
> (Note: "C" rights do not automatically give the CREATER any other rights;
|
|
> they must be specifically given. `RW+ = CREATER` is recommended in most
|
|
> situations, as you can see in our example).
|
|
|
|
Assuming user "u4" trying to push-create a new repo called
|
|
`assignments/u4/a23`, this is what the effective ruleset looks like (we're
|
|
ignoring the "NOBODY" business):
|
|
|
|
repo assignments/u4/a23
|
|
C = @students
|
|
RW+ = u4
|
|
RW = @TAs
|
|
R = @prof
|
|
|
|
If u4 gives "RW" perms to u5 using `setperms`, and u5 tries to access that
|
|
repo, the ruleset looks like:
|
|
|
|
repo assignments/u4/a23
|
|
C = @students
|
|
RW+ = u4
|
|
RW = u5 @TAs
|
|
R = @prof
|
|
|
|
I hope that helps.
|
|
|
|
----
|
|
|
|
Enjoy, and please use with care. This is pretty powerful stuff. As they say:
|
|
if you break it, you get to keep both pieces :)
|
|
|
|
[jwzq]: http://regex.info/blog/2006-09-15/247
|
|
|
|
[av]: http://en.wikipedia.org/wiki/Autovivification
|