Sophie

Sophie

distrib > Fedora > 14 > x86_64 > media > updates > by-pkgid > ba9fe7781d529b2e7b31d8489f5e0b8e > files > 15

gitolite-1.5.3-2.fc14.noarch.rpm

<h1>repositories named with wildcards</h1>

<p><strong><em>IMPORTANT NOTE</em></strong>:</p>

<p>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.</p>

<p>Also, there are some limitations.  For example, you cannot specify gitconfig
values for a wildcard repo; it only works for actual repos.</p>

<p>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 <em>no</em>
workarounds I may not have the time to code it right away.</p>

<hr />

<p>In this document:</p>

<ul>
<li><a href="#rc_file_setting_required">rc file setting required</a></li>
<li><a href="#Wildcard_repos">Wildcard repos</a>
<ul>
<li><a href="#Wildcard_repos_with_creator_name_in_them">Wildcard repos with creator name in them</a></li>
<li><a href="#Wildcard_repos_without_creator_name_in_them">Wildcard repos without creator name in them</a></li>
</ul></li>
<li><a href="#Side_note_Line_anchored_regexes">Side-note: Line-anchored regexes</a>
<ul>
<li><a href="#Contrast_with_refexes">Contrast with refexes</a></li>
</ul></li>
<li><a href="#Handing_out_rights_to_wildcard_matched_repos">Handing out rights to wildcard-matched repos</a></li>
<li><a href="#setting_a_gitweb_description_for_a_wildcard_matched_repo">setting a gitweb description for a wildcard-matched repo</a></li>
<li><a href="#reporting">reporting</a></li>
<li><a href="#other_issues_and_discussion">other issues and discussion</a></li>
<li><a href="#how_it_actually_works">how it actually works</a></li>
</ul>

<hr />

<p>This document is mostly "by example".</p>

<hr />

<p><a name="rc_file_setting_required"></a></p>

<h3>rc file setting required</h3>

<p>This feature requires that you set <code>$GL_WILDREPOS</code> to "1" in <code>~/.gitolite.rc</code>
on the server.  Please search for that variable and see comments around it in
<code>conf/example.gitolite.rc</code> for more information on this.</p>

<p><a name="Wildcard_repos"></a></p>

<h3>Wildcard repos</h3>

<p>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.</p>

<p><a name="Wildcard_repos_with_creator_name_in_them"></a></p>

<h4>Wildcard repos with creator name in them</h4>

<p>Here's an example snippet:</p>

<pre><code>@prof       =   u1
@TAs        =   u2 u3
@students   =   u4 u5 u6

repo    assignments/CREATOR/a[0-9][0-9]
    C   =   @students
    RW+ =   CREATOR
    RW  =   WRITERS @TAs
    R   =   READERS @prof
</code></pre>

<p>For now, ignore the special usernames READERS and WRITERS, and just create a
new repo, as user "u4" (a student):</p>

<pre><code>$ 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.
</code></pre>

<p>Notice the <em>two</em> empty repo inits, and the order in which they occur ;-)</p>

<p><a name="Wildcard_repos_without_creator_name_in_them"></a></p>

<h4>Wildcard repos without creator name in them</h4>

<p>Here's how the same example would look if you did not want the CREATOR's name
to be part of the actual repo name.</p>

<pre><code>repo    assignments/a[0-9][0-9]
    C   =   @students
    RW+ =   CREATOR
    RW  =   WRITERS @TAs
    R   =   READERS @prof
</code></pre>

<p>We haven't changed anything except the repo name pattern.  This means that the
first student that creates, say, <code>assignments/a12</code> 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.</p>

<p>You could also repace the C line like this:</p>

<pre><code>    C   =   @TAs
</code></pre>

<p>and have a TA create the repos in advance.</p>

<p>In either case, they could then use the <code>setperms</code> feature to specify which
users are "READERS" and which are "WRITERS".  See later for details.</p>

<p><a name="Side_note_Line_anchored_regexes"></a></p>

<h3>Side-note: Line-anchored regexes</h3>

<p>A regex like</p>

<pre><code>repo assignments/S[0-9]+/A[0-9]+
</code></pre>

<p>would match <code>assignments/S02/A37</code>.  It will not match <code>assignments/S02/ABC</code>,
or <code>assignments/S02/a37</code>, obviously.</p>

<p>But you may be surprised to find that it does not match even
<code>assignments/S02/A37/B99</code>.  This is because internally, gitolite
<em>line-anchors</em> the given regex; so that regex actually becomes
<code>^assignments/S[0-9]+/A[0-9]+$</code> -- notice the line beginning and ending
metacharacters.</p>

<p><a name="Contrast_with_refexes"></a></p>

<h4>Contrast with refexes</h4>

<p>Just for interest, note that this is in contrast to the refexes for the normal
"branch" permissions, as described in <code>conf/example.conf</code> and elsewhere.
These "refexes" are only anchored at the start; a pattern like
<code>refs/heads/master</code> actually can match <code>refs/heads/master01/bar</code> as well, even
if no one will actually push such a branch!  You can anchor both sides if you
really care, by using <code>master$</code> instead of <code>master</code>, but that is <em>not</em> the
default for refexes.</p>

<p><a name="Handing_out_rights_to_wildcard_matched_repos"></a></p>

<h3>Handing out rights to wildcard-matched repos</h3>

<p>In the examples above, we saw two special "user" names: READERS and WRITERS.
The permissions they have are controlled by the config file, but <strong><em>who is
part of this list</em></strong> is controlled by the person who created the repository.</p>

<p>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 creator 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.</p>

<p>Create a small text file that contains the permissions you desire:</p>

<pre><code>$ cat &gt; myperms
R u5
RW u6
(hit ctrl-d here)
</code></pre>

<p>...and use the new "setperms" command to set permissions for your repo:</p>

<pre><code>$ ssh git@server setperms assignments/u4/a12 &lt; myperms
New perms are:
R u5
RW u6
</code></pre>

<p>'setperms' will helpfully print what the new permissions are but you can also
use 'getperms' to check:</p>

<pre><code>$ ssh git@server getperms assignments/u4/a12
R u5
RW u6
</code></pre>

<p>The following points are important:</p>

<ul>
<li><p>note the syntax of the commands; it's not a "git" command, and there's no
<code>:</code> like in a repo URL.  The first space-separated word is R or RW, and
the rest are simple usernames.</p></li>
<li><p>whoever you specify as "R" will match the special user READERS.  "RW" will
match WRITERS.</p></li>
</ul>

<p><a name="setting_a_gitweb_description_for_a_wildcard_matched_repo"></a></p>

<h3>setting a gitweb description for a wildcard-matched repo</h3>

<p>Similar to the getperm/setperm commands, there are the getdesc/setdesc
commands, thanks to Teemu.</p>

<p><a name="reporting"></a></p>

<h3>reporting</h3>

<p>Remember the cool stuff you see when you just do <code>ssh git@server</code> (grep for
"myrights" in <code>doc/3-faq-tips-etc.mkd</code> if you forgot, or go <a href="http://github.com/sitaramc/gitolite/blob/pu/doc/3-faq-tips-etc.mkd#myrights">here</a>).</p>

<p>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 <em>create</em> repos matching that pattern.</p>

<p>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
<em>every single</em> repo that your users have created, add this to your config
file:</p>

<pre><code>repo @all
    R       =   sitaram     # or whoever you are
</code></pre>

<p>Push the config, then try</p>

<pre><code>ssh gitolite expand
</code></pre>

<p><a name="other_issues_and_discussion"></a></p>

<h3>other issues and discussion</h3>

<ul>
<li><p><em>what if the repo name being pushed matches more than one pattern</em>?</p>

<p>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.</p>

<p>And in security, that's a <strong><em>Bad Thing</em></strong>.</p>

<p>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 :-)</p>

<p>This can make some repos inaccessible if the patterns changed <em>after</em> 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.</p></li>
</ul>

<p><a name="how_it_actually_works"></a></p>

<h3>how it actually works</h3>

<p>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:</p>

<pre><code>repo    assignments/CREATOR/a[0-9][0-9]
    C   =   @students
    RW+ =   CREATOR
    RW  =   WRITERS @TAs
    R   =   READERS @prof
</code></pre>

<p>First we find the set of rules to apply.  This involves replacing the special
words CREATOR, WRITERS, and READERS with appropriate usernames to derive an
"effective" ruleset for the repo in question.</p>

<p>For a <strong>new</strong> repo, replace the word CREATOR in all repo patterns and rules
with the name of the invoking user.</p>

<blockquote>
  <p>(Note: this is why you should never use <code>C = CREATOR</code>; it becomes <code>C =
    invoking_user</code>!  Unless you really want to allow <em>all</em> users to create
    repos, you should restrict "C" perms to an actual user or set of users,
    like in the examples in this document).</p>
</blockquote>

<p>For an <strong>existing</strong> repo, do the same but replace with the name of the user
who actually <em>created</em> the repo (this name is recorded in a special file in
the repo directory when the repo is first created, so it is available).</p>

<p>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.</p>

<p>If the invoking user has been given "RW" permissions using <code>setperms</code>, 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 <code>setperms</code> on a non-existant repo -- they are replaced by "NOBODY".</p>

<p>(The same thing is done with "R" access and the word "READERS".)</p>

<p>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.</p>

<blockquote>
  <p>(Note: "C" rights do not automatically give the CREATOR any other rights;
    they must be specifically given.  <code>RW+ = CREATOR</code> is recommended in most
    situations, as you can see in our example).</p>
</blockquote>

<p>Assuming user "u4" trying to push-create a new repo called
<code>assignments/u4/a23</code>, this is what the effective ruleset looks like (we're
ignoring the "NOBODY" business):</p>

<pre><code>repo    assignments/u4/a23
    C   =   @students
    RW+ =   u4
    RW  =   @TAs
    R   =   @prof
</code></pre>

<p>If u4 gives "RW" perms to u5 using <code>setperms</code>, and u5 tries to access that
repo, the ruleset looks like:</p>

<pre><code>repo    assignments/u4/a23
    C   =   @students
    RW+ =   u4
    RW  =   u5 @TAs
    R   =   @prof
</code></pre>

<p>I hope that helps.</p>

<hr />

<p>Enjoy, and please use with care.  This is pretty powerful stuff.  As they say:
if you break it, you get to keep both pieces :)</p>