基于路径的授权

Both Apache and svnserve are capable of granting (or denying) permissions to users. Typically this is done over the entire repository: a user can read the repository (or not), and she can write to the repository (or not). It's also possible, however, to define finer-grained access rules. One set of users may have permission to write to a certain directory in the repository, but not others; another directory might not even be readable by all but a few special people.

Both servers use a common file format to describe these path-based access rules. In the case of Apache, one needs to load the mod_authz_svn module and then add the AuthzSVNAccessFile directive (within the httpd.conf file) pointing to your own rules-file. (For a full explanation, see “每目录访问控制”一节.) If you're using svnserve, then you need to make the authz-db variable (within svnserve.conf) point to your rules-file.

当你的服务器知道去查找规则文件时,就是需要定义规则的时候了。

The syntax of the file is the same familiar one used by svnserve.conf and the runtime configuration files. Lines that start with a hash (#) are ignored. In its simplest form, each section names a repository and path within it, and the authenticated usernames are the option names within each section. The value of each option describes the user's level of access to the repository path: either r (read-only) or rw (read-write). If the user is not mentioned at all, no access is allowed.

To be more specific: the value of the section-names are either of the form [repos-name:path] or the form [path]. If you're using the SVNParentPath directive, then it's important to specify the repository names in your sections. If you omit them, then a section like [/some/dir] will match the path /some/dir in every repository. If you're using the SVNPath directive, however, then it's fine to only define paths in your sections—after all, there's only one repository.

[calc:/branches/calc/bug-142]
harry = rw
sally = r

In this first example, the user harry has full read and write access on the /branches/calc/bug-142 directory in the calc repository, but the user sally has read-only access. Any other users are blocked from accessing this directory.

当然,访问控制是父目录传递给子目录的,这意味着我们可以为Sally指定一个子目录的不同访问策略:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

# give sally write access only to the 'testing' subdir
[calc:/branches/calc/bug-142/testing]
sally = rw

Now Sally can write to the testing subdirectory of the branch, but can still only read other parts. Harry, meanwhile, continues to have complete read-write access to the whole branch.

也可以通过继承规则明确的的拒绝某人的访问,只需要设置用户名参数为空:

[calc:/branches/calc/bug-142]
harry = rw
sally = r

[calc:/branches/calc/bug-142/secret]
harry =

In this example, Harry has read-write access to the entire bug-142 tree, but has absolutely no access at all to the secret subdirectory within it.

需要记住的是最详细的的路径会被匹配,服务器首先找到匹配自己的目录,然后父目录,然后父目录的父目录,就这样继续下去,更具体的路径控制会覆盖所有继承下来的访问控制。

By default, nobody has any access to the repository at all. That means that if you're starting with an empty file, you'll probably want to give at least read permission to all users at the root of the repository. You can do this by using the asterisk variable (*), which means “all users”:

[/]
* = r

This is a common setup; notice that there's no repository name mentioned in the section name. This makes all repositories world readable to all users. Once all users have read-access to the repositories, you can give explicit rw permission to certain users on specific subdirectories within specific repositories.

The asterisk variable (*) is also worth special mention here: it's the only pattern which matches an anonymous user. If you've configured your server block to allow a mixture of anonymous and authenticated access, all users start out accessing anonymously. The server looks for a * value defined for the path being accessed; if it can't find one, then it demands real authentication from the client.

The access file also allows you to define whole groups of users, much like the Unix /etc/group file:

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = harry, sally, joe, frank, sally, jane

Groups can be granted access control just like users. Distinguish them with an “at” (@) prefix:

[calc:/projects/calc]
@calc-developers = rw

[paint:/projects/paint]
@paint-developers = rw
jane = r

组中也可以定义为包含其它的组:

[groups]
calc-developers = harry, sally, joe
paint-developers = frank, sally, jane
everyone = @calc-developers, @paint-developers


[45] 本书的共同主题!