Graham,

Thanks for your response.  Here's some more info on my test scenario.
It includes Apache access logs and debug output for an access handler
for mod_wsgi vs mod_python.  Even though the access_log resulting from
methods does not show anything from which an actual path or filename
can be determined, for some reason mod_python has access to this
data.  Is it possible that in mod_wsgi I have to use <LimitExcept>
blocks and rewrite the config file instead of doing this exclusively
via custom code?

Thanks again!
Brian

localhost:~$ svn co  http://localhost/svn/project

svn response:
A    project/b.txt
A    project/c
A    project/c/ac.txt
A    project/a.txt
Checked out revision 6.

---------- Apache log from mod_wsgi ----------
127.0.0.1 - - [29/Mar/2011:10:55:01 -0400] "OPTIONS /svn/project HTTP/
1.1" 401 673 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:07 -0400] "OPTIONS /svn/
project HTTP/1.1" 200 866 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:07 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:08 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:08 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 466 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/!svn/
bc/6/project HTTP/1.1" 207 561 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - - [29/Mar/2011:10:55:09 -0400] "OPTIONS /svn/project HTTP/
1.1" 401 673 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "OPTIONS /svn/
project HTTP/1.1" 200 866 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:09 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:10 -0400] "REPORT /svn/!svn/
vcc/default HTTP/1.1" 200 570 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - - [29/Mar/2011:10:55:21 -0400] "OPTIONS /svn/project HTTP/
1.1" 401 673 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:23 -0400] "OPTIONS /svn/
project HTTP/1.1" 200 866 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:23 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:23 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:23 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 466 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - - [29/Mar/2011:10:55:24 -0400] "OPTIONS /svn/project HTTP/
1.1" 401 673 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "OPTIONS /svn/
project HTTP/1.1" 200 866 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
bc/6/project HTTP/1.1" 207 561 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/
project HTTP/1.1" 207 557 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
vcc/default HTTP/1.1" 207 446 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "PROPFIND /svn/!svn/
bln/6 HTTP/1.1" 207 460 "-" "SVN/1.6.12 (r955767) neon/0.29.3"
127.0.0.1 - testuser [29/Mar/2011:10:55:24 -0400] "REPORT /svn/!svn/
vcc/default HTTP/1.1" 200 849 "-" "SVN/1.6.12 (r955767) neon/0.29.3"

----------

Here's code I am using to dump the path from the WSGIAccessScript.
def allow_access(environ, host):
        path = environ['REQUEST_URI']
        method = environ['REQUEST_METHOD']

        f = open('/tmp/svn.log', 'a')
        f.write('access path = %s\nmethod = %s\n\n' % (path, method))
        f.close()
        return True

---------- mod_wsgi svn.log dump ----------
access path = /svn/project
method = OPTIONS

access path = /svn/project
method = PROPFIND

access path = /svn/!svn/vcc/default
method = PROPFIND

access path = /svn/!svn/bln/6
method = PROPFIND

access path = /svn/project
method = PROPFIND

access path = /svn/!svn/vcc/default
method = PROPFIND

access path = /svn/!svn/bln/6
method = PROPFIND

access path = /svn/project
method = PROPFIND

access path = /svn/!svn/vcc/default
method = PROPFIND

access path = /svn/!svn/bc/6/project
method = PROPFIND

access path = /svn/project
method = OPTIONS

access path = /svn/project
method = PROPFIND

access path = /svn/project
method = PROPFIND

access path = /svn/!svn/vcc/default
method = PROPFIND

access path = /svn/!svn/bln/6
method = PROPFIND

access path = /svn/project
method = PROPFIND

access path = /svn/!svn/vcc/default
method = PROPFIND

access path = /svn/!svn/bln/6
method = PROPFIND

access path = /svn/!svn/vcc/default
method = REPORT

access path = /svn/!svn/vcc/default
method = GET

access path = /svn/!svn/vcc/default
method = GET

access path = /svn/!svn/vcc/default
method = GET

access path = /svn/!svn/vcc/default
method = GET

access path = /svn/!svn/vcc/default
method = GET

---------- Apache log for mod_python for the same repo ----------
127.0.0.1 - - [29/Mar/2011:11:59:37 -0400] "OPTIONS /svn/project/trunk
HTTP/1.1" 401 1957 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "OPTIONS /svn/
project/trunk HTTP/1.1" 200 996 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
vcc/default HTTP/1.1" 207 580 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
bln/2 HTTP/1.1" 207 596 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
vcc/default HTTP/1.1" 207 580 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
bln/2 HTTP/1.1" 207 596 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - LOCAL\\test [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
vcc/default HTTP/1.1" 207 596 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
bc/2/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "OPTIONS /svn/project/trunk
HTTP/1.1" 401 1957 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "OPTIONS /svn/
project/trunk HTTP/1.1" 200 996 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
vcc/default HTTP/1.1" 207 580 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
bln/2 HTTP/1.1" 207 596 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - testuser [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/
project/trunk HTTP/1.1" 207 692 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
vcc/default HTTP/1.1" 207 580 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "PROPFIND /svn/project/!svn/
bln/2 HTTP/1.1" 207 596 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
127.0.0.1 - - [29/Mar/2011:11:59:39 -0400] "REPORT /svn/project/!svn/
vcc/default HTTP/1.1" 200 1058 "-" "SVN/1.6.6 (r40053) neon/0.29.0"
----------
This is the mod_python acces handler:
def access(req):
    f = open('/tmp/svn.log', 'a')
    f.write('access path = %s\nmethod = %s\n\n' % (req.path_info,
req.method))
    f.close()
    return apache.OK

---------- mod_python svn.log dump ----------
access path = /project/trunk
method = OPTIONS

access path = /project/trunk
method = OPTIONS

access path = /project/trunk
method = PROPFIND

access path = /project/trunk
method = PROPFIND

access path = /project/trunk
method = PROPFIND

access path = /project/trunk
method = OPTIONS

access path = /project/trunk
method = OPTIONS

access path = /project/trunk
method = PROPFIND

access path = /project/trunk
method = PROPFIND

access path = /project/trunk
method = PROPFIND

access path = /project/!svn/ver/2/trunk
method = GET

access path = /project/!svn/ver/2/trunk/b.txt
method = GET

access path = /project/!svn/ver/2/trunk/c
method = GET

access path = /project/!svn/ver/2/trunk/c/ac.txt
method = GET

access path = /project/!svn/ver/2/trunk/a.txt
method = GET


Graham Dumpleton wrote:
> On 29 March 2011 08:00, Brian <[email protected]> wrote:
> > I currently use mod_python to manage permissions for a svn repository.  The
> > key part of my apache2 config looks like this:
> >
> > PythonAccessHandler MyProject.svn_authz::access
> > PythonAuthenHandler MyProject.auth::authenticate
> > PythonAuthzHandler MyProject.svn_authz::authorize
> >
> > I have made attempts to replace this with mod_wsgi, like this:
> >
> > WSGIAccessScript /usr/local/myproject/auth.wsgi
> > WSGIAuthUserScript /usr/local/myproject/auth.wsgi
> >
> > In general, this works.  I can allow control to the repository by user or
> > allow anonymous access, but unfortunately I want to be able to allow some
> > parts of the repo to be public and grant permissions by path.  Even though
> > the access_log looks the same between mod_python and mod_wsgi, in mod_python
> > the request object had access to path_info, which would contain the path to
> > the file being accessed.  With mod_wsgi I seem to only have access to the
> > environment variables, with only REQUEST_METHOD and REQUEST_URI being
> > potentially useful.  Through inspection I see REQUEST_URI first contains the
> > requested path, like when doing a checkout.  Each subsequent request in the
> > same checkout action only has /svn/!svn/vcc/default or similar URIs, which
> > is what I see in the access_log both with mod_python and mod_wsgi.  For some
> > reason the path_info element in mod_python always had some flavor of the
> > filename.  Without being able to know the path in mod_wsgi, I'm not sure how
> > I can use WSGIAccessScript and WSGIAuthUserScript to manage fine-grained
> > permissions in svn.
>
> PATH_INFO is derived from whatever is in REQUEST_URI. The only
> additional thing with PATH_INFO is that it would have been normalised
> for bit a subversion client it should be using well formed URI so what
> you extract from REQUEST_URI should be fine, although might still be a
> good idea to do some sanity checks on it. Either way, the information
> to do it should be there.
>
> Alternatively and depending on what operations you want to block then
> you do it at Apache configuration level. For example the following
> Apache configuration duplicates the listed thing from subversion
> authnz file.
>
> # [Project1:/]
> # vishwajeet = rw
>
> <Location /svn/Project1/!svn/*/*/*>
> Require user vishwajeet
> </Location>
>
> # [Project2:/]
> # vishwajeet = r
>
> <Location /svn/Project2/!svn/*/*/*>
> Require user vishwajeet
> <LimitExcept OPTIONS GET PROPFIND REPORT COPY>
> deny from all
> </LimitExcept>
> </Location>
>
> You could also start to tie this in with WSGIAuthGroupScript and have
> what groups users are in defined by Python code. For example with
> Location with path have:
>
> Require wsgi-group svn_read
> <LimitExcept GET PROPFIND OPTIONS REPORT>
>   Require wsgi-group svn_write
> </LimitExcept>
>
> Where for Django Python code behind might be:
>
> def groups_for_user(environ, user):
>    db.reset_queries()
>
>    kwargs = {'username': req.user, 'is_active': True}
>
>    try:
>        try:
>            user = User.objects.get(**kwargs)
>        except User.DoesNotExist:
>            return None
>
>         return user.groups
>
>    finally:
>        db.connection.close()
>
> BTW, just a warning. WSGIAuthUserScript/WSGIAuthGroupScript are called
> on every request when HTTP Basic authentication is being used. In high
> volume sites the overhead of this can be noticeable if you have to go
> back to a database to authenticate/authorise every time. You might
> want to look at some level of caching and credential expiration within
> the process to avoid going to the database all the time.
>
> That is probably all I can say at the moment without seeing the
> specific values of REQUEST_METHOD and REQUEST_URI you are getting for
> the request  you think you are getting the wrong information for.
>
> Graham

-- 
You received this message because you are subscribed to the Google Groups 
"modwsgi" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/modwsgi?hl=en.

Reply via email to