|
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
|