[mod_python] Setting req->user for mod_dav_svn (SOLVED)

Deron Meranda deron.meranda at gmail.com
Tue Aug 1 15:15:15 EDT 2006


I finally got it working!  (Thanks Graham and Jim)

I apparently had a logic error in my complex access handler.  After
simplifying things to the bare minimum I can now use mod_python to set
the subversion user.

For those who are potentially interested, here's a simple illustrative
example of how to use mod_python along with subversion, whereby the
python handler *simulates* a BASIC auth (username and password), but
without using any of the built-in Apache Auth*, Satisfy*, Limit*, or
Requires* directives.

# In Apache config
<Location /svn>
  DAV svn
  SVNPath /path/to/svn/repo
  PythonAccessHandler myauth::setuser
</Location>

# File myauth.py
def decode_basic_auth(req):
    try:
        autype, auparm = req.headers_in['Authorization'].split()
        if autype.upper() != 'BASIC':
            return None
        import base64
        auparm = base64.decodestring( auparm )
        auuser, aupass = auparm.split( ':', 1 )
        return auuser, aupass
    except:
        return None

def setuser(req):
    basicauth = decode_basic_auth(req)
    if req.method in ('GET','PROPFIND','OPTIONS','REPORT','HEAD'):
        pass  # Allow anonymous read-only access
    else:
        # A non-read-only method requires authentication
        okay = False
        if basicauth:
            ba_user, ba_pass = basicauth
            if ba_user == ba_pass:  # Replace with real pw validate later
                req.user = ba_user   # Set the username as appears in
subversion logs
                okay = True
        if not okay:
            # Force UA to send authentication
            req.err_headers_out['WWW-Authenticate'] = 'BASIC realm="Subversion"'
            raise apache.SERVER_RETURN, apache.HTTP_UNAUTHORIZED
    return apache.OK

In actuality setting the req.user seems to work as long as you do it
in any phase all the way through the PythonFixupHandler.

For the curious, a typical subversion commit of changes to a single
file results in a flurry of HTTP requests with different methods, such
as follows.  Obviously if you do this for real you'll want to keep
your authentication phase quick.  You do not need to set req.user for
the read-only methods (if you allow anonymous read-only access), but
it is important that for any of the other methods you always set
req.user to the SAME string (otherwise you'll get a 501 error from
mod_dav_svn complaining it can't do multi-user commits).

  OPTIONS
  MKACTIVITY
  PROPFIND
  PROPFIND
  CHECKOUT
  PROPPATCH
  PROPFIND
  CHECKOUT
  PUT
  GET
  MERGE
  MERGE
  DELETE
  PROPFIND
  PROPFIND
  REPORT
  GET
  ... lots more GETS ...

-- 
Deron Meranda


More information about the Mod_python mailing list