[mod_python] Using mod_python to customise subversion repository access.

Graham Dumpleton grahamd at dscpl.com.au
Fri Sep 1 00:04:36 EDT 2006


In my real job, we are finally converting to using subversion. Now
although subversion when used through Apache still supports a
level of user authorisation, whereby one can see if a user has read
or read/write to different parts of a repository, the paths have to
be listed in full, with no support for wildcarding. Also, you can't
use its authorisation mechanism to implement a fine grained level
of authorisation.

For example, we want to allow users to be able to copy the trunk
to a tags directory to effectively mark a specific version, and we
want to be able to users to check out a copy of a tagged version,
but we do not want to allow users to make changes to and commit
back in changes into a tagged version of a package.

So, mod_python to the rescue.

  from mod_python import apache
  import fnmatch

  BLOCK_URI = '/svn/drives/!svn/*/*/packages/tags/*/*/*'

  BLOCK_METHOD = [ 'MKCOL', 'PUT', 'PROPPATCH', 'CHECKOUT',
          'MERGE', 'MKACTIVITY', 'LOCK', 'UNLOCK' ]

  def authzhandler(req):
      if fnmatch.fnmatch(req.uri, BLOCK_URI):
          if req.method in BLOCK_METHOD:
              return apache.HTTP_FORBIDDEN
      return apache.OK

The associated Apache configuration is something like:

  <Location /svn>

    DAV svn
    SVNParentPath /usr/local/repository/subversion

    Require valid-user

    AuthzSVNAccessFile /usr/local/repository/svnserve.conf

    PythonInterpreter subversion_authz
    PythonPath 'sys.path + ["/usr/local/repository/handlers"]'
    PythonFixupHandler drives_authz::authzhandler
    PythonDebug On

  </Location>

In the pattern being matched, '/svn/drives' identifies the actual repository
root path in the URI. The '/packages/tags/*/*/*' is identifying the directories
where we keep our tagged versions. The structure we use is:

  /packages/tags/package-name/package-version

When creating a tag, subversion client uses "COPY" method, so making the
copy still works. When doing commits, it needs to at least use 'CHECKOUT',
and 'PUT'. Depending on what else it does, it could use the others in the
block list.

Anyway, end result is that people can't write over tagged versions.

Gotta run now, so enjoy.

Graham


More information about the Mod_python mailing list