Python Paste by boorad
Description: Apache's SVN conf using Django authn and dsource authz
Hide line numbers

Create new paste
Post a reply
View replies

Paste:
1  
2  
3  
4  
5  
6  
7  
8  
9  
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  
20  
21  
22  
23  
24  
25  
26  
27  
28  
29  
30  
31  
32  
33  
34  
35  
36  
37  
38  
39  
40  
41  
42  
43  
44  
45  
46  
47  
48  
49  
50  
51  
52  
53  
54  
55  
56  
57  
58  
59  
60  
61  
62  
63  
64  
65  
66  
67  
68  
69  
70  
71  
72  
73  
74  
75  
76  
77  
78  
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98  
99  
100  
101  
102  
103  
104  
105  
106  
107  
108  
109  
110  
111  
112  
113  
114  
115  
116  
117  
118  
119  
120  
121  
122  
123  
124  
125  
126  
127  
128  
129  
130  
131  
132  
133  
134  
135  
136  
137  
138  
139  
140  
141  
142  
143  
144  
145  
146  
147  
148  
149  
# dsource/web/modpython.py

from mod_python import apache
import os

DEBUG = False

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
        if user.check_password(password):
            return apache.OK
        else:
            # password check failed
            return apache.HTTP_UNAUTHORIZED

    finally:
        db.connection.close()


def authzhandler(req, **kwargs):

    from django import db
    from tracdsource.perm import get_groups
    
    # 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)

    username = req.user
    requires = req.requires()
    options = req.get_options()
    proj = options['PROJECT']

    if DEBUG:
        req.log_error("username        : %s" % username)
        req.log_error("project         : %s" % proj)
        req.log_error("requires        : %s" % requires)

    settings_module = options.get('DJANGO_SETTINGS_MODULE', None)
    if settings_module:
        os.environ['DJANGO_SETTINGS_MODULE'] = settings_module
    db.reset_queries()

    try:
        if requires:
            # check dsource groups
            required_groups = _get_required_groups(req, requires)
            if DEBUG:
                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)
                if DEBUG:
                    req.log_error("user_groups     : %s" % user_groups)

                for group in required_groups:
                    if group in user_groups:
                        if DEBUG:
                            req.log_error("w00t - match    : %s" % group)
                        return apache.OK
    finally:
        db.connection.close()

    return apache.HTTP_UNAUTHORIZED


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)
            finally:
                pass
    return groups


# apache svn conf

        <Macro ProjectClosed $PROJ>
        <Location /projects/$PROJ>
                DAV svn
                SVNPath /var/svn/$PROJ
                AuthType Basic
                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
                PythonHandlerModule dsource.web.modpython
                AuthAuthoritative Off
                Require dsource-group dsource project_admin developer # works
#               Require valid-user      # works
#               Require user brad       # works
#               Require user bradd      # fails (and should)

                SetHandler None
        </Location>
        </Macro>

Replies:

    (some replies deleted)