Jim Gallacher
jpg at jgassociates.ca
Sat Jul 21 20:54:46 EDT 2007
Hi Brad, It's been awhile since I've messed with aaa, but I may have a spark of an idea. Brad Anderson wrote: > Hi, > > I'm trying to tie into Django's auth subsystem for http authn/authz in > front of Subversion, as seen here: > http://www.djangoproject.com/documentation/apache_auth/ > > So, my Apache 2.0.59 conf looks like this (with some mod_macro voodoo): > > ##################################################################### > > <Macro ProjectClosed $PROJ> > <Location /projects/$PROJ> > DAV svn > SVNPath /var/svn/$PROJ > AuthType Basic Try changing your AuthType to something else. Heck, you could even use: AuthType somethingelse but you'll likely want something a little clearer - dsource-auth might be a good choice. You can retrieve this string in your handler with req.auth_type(). Likewise req.auth_name() will get you the AuthName setting. As I recall the AuthType Basic will cause the default authentication mechanism to fire, and that's the thing that is generating the "couldn't check access. No groups file?" verbiage in your log. > AuthName "dsource-$PROJ" > > SetEnv DJANGO_SETTINGS_MODULE dsource.settings > PythonOption DJANGO_SETTINGS_MODULE dsource.settings > PythonOption PROJECT $PROJ > PythonPath "['/home/brad/dev/python'] + sys.path" > > PythonAuthenHandler dsource.web.modpython > AuthAuthoritative Off > Require dsource-group project_admin developer > # Require valid-user > > SetHandler None > </Location> > </Macro> > > ##################################################################### > > > > And the dsource.web.modpython handler function looks like this: > > ##################################################################### > from mod_python import apache > import os > > def authenhandler(req, **kwargs): > """ > Authentication handler that checks against Django's auth database. > """ > > # mod_python fakes the environ, and thus doesn't process SetEnv. > # This fixes that so that the following import works > os.environ.update(req.subprocess_env) > > # check for PythonOptions > _str_to_bool = lambda s: s.lower() in ('1', 'true', 'on', 'yes') > > options = req.get_options() > permission_name = options.get('DjangoPermissionName', None) > staff_only = _str_to_bool(options.get('DjangoRequireStaffStatus', "on")) > superuser_only = > _str_to_bool(options.get('DjangoRequireSuperuserStatus', "off")) > settings_module = options.get('DJANGO_SETTINGS_MODULE', None) > if settings_module: > os.environ['DJANGO_SETTINGS_MODULE'] = settings_module > > from django.contrib.auth.models import User > from django import db > db.reset_queries() > > username = req.user > password = req.get_basic_auth_pw() > requires = req.requires() > proj = options['PROJECT'] > > # check that the username is valid > kwargs = {'username': username, 'is_active': True} > if staff_only: > kwargs['is_staff'] = True > if superuser_only: > kwargs['is_superuser'] = True > try: > try: > user = User.objects.get(**kwargs) > except User.DoesNotExist: > return apache.HTTP_UNAUTHORIZED > > # check the password and any permission given > if user.check_password(password): > > if requires: > # check dsource groups > required_groups = _get_required_groups(req, requires) > req.log_error("required_groups : %s" % required_groups) > > if required_groups: > from tracdsource.perm import get_groups > user_groups = get_groups(username, proj, db.connection) > req.log_error("user_groups : %s" % user_groups) > > for group in required_groups: > if group in user_groups: > req.log_error("w00t - match : %s" % group) > return apache.OK # WTF? working? > else: > req.log_error("no requires") > return apache.OK > > else: > # password check failed > return apache.HTTP_UNAUTHORIZED > > finally: > db.connection.close() > > > def _get_required_groups(req, requires): > groups = [] > group_token = 'dsource-group ' > > for require in requires: > if require.startswith(group_token): > try: > group_list = require[len(group_token):].split(' ') > for group in group_list: > groups.append(group) > # req.log_error("group: %s" % group) > finally: > pass > else: > try: > user_list = require.split(' ') > for user in user_list: > if user == "valid-user": > groups.append('registered_user') > # req.log_error("group: %s" % group) > finally: > pass > > return groups > ##################################################################### > > When I activate 'Require valid-user' things are fine (in error_log): > > required_groups : ['registered_user'] > user_groups : ['anonymous', 'registered_user', 'project_admin'] > w00t - match : registered_user > > > But when I activate 'Require dsource-group project_admin developer' I > get an error: > > required_groups : ['dsource', 'project_admin', 'developer'] > user_groups : ['anonymous', 'registered_user', 'project_admin'] > w00t - match : project_admin > configuration error: couldn't check access. No groups file?: > /projects/test > > I've been looking at > http://www.modpython.org/pipermail/mod_python/2006-April/020959.html and > it's caused me to add 'AuthAuthoritative Off' to httpd.conf, but it says > 'group' and 'valid-user' are a no-no, but that's all I can get to work. > Maybe this is an Apache 2.2.4 thing? Nope. AuthAuthoritative disappears in 2.2, along with mod_auth. There was a reorganization of the aaa stuff for 2.2 with a bunch of new modules being added such as mod_auth_basic and mod_auth_digest. > Search for WTF? in the Python handler code - that return apache.OK > doesn't seem to return 200 even though we found a match (in error_log). > It's as if the handler function returns None or 0. For some reason I can't seem to parse that paragraph. Hopefully the change to AuthType I suggested will take care of the problem. On the other hand the value of apache.OK *is* 0 and this is perfectly fine. Don't confuse the value your handler returns to apache with the status value that apache eventually sets in the response header. There is obviously a relationship but it's not a 1:1 mapping. For example your handler could return apache.DECLINED, which would cause the next authenhandler in the chain to be called. > What bonehead thing am I doing? You think you're boneheaded? I read the thread from April '06 you quoted and I don't remember any of it. The only way I know I participated is that I recognize the typos I typically mak. :) Jim
|