This file is indexed.

/usr/share/pyshared/repoze/what/middleware.py is in python-repoze.what 1.0.9-2.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
# -*- coding: utf-8 -*-
##############################################################################
#
# Copyright (c) 2007, Agendaless Consulting and Contributors.
# Copyright (c) 2008, Florent Aide <florent.aide@gmail.com>.
# Copyright (c) 2008-2009, Gustavo Narea <me@gustavonarea.net>.
# All Rights Reserved.
#
# This software is subject to the provisions of the BSD-like license at
# http://www.repoze.org/LICENSE.txt.  A copy of the license should accompany
# this distribution.  THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL
# EXPRESS OR IMPLIED WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO,
# THE IMPLIED WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND
# FITNESS FOR A PARTICULAR PURPOSE.
#
##############################################################################

"""
Utilities to setup authorization by configuring repoze.who's middleware to
use repoze.what.

"""

import os

from zope.interface import implements
from repoze.who.plugins.testutil import make_middleware
from repoze.who.classifiers import default_challenge_decider, \
                                   default_request_classifier
from repoze.who.interfaces import IAuthenticator, IMetadataProvider

__all__ = ['AuthorizationMetadata', 'setup_auth']


class AuthorizationMetadata(object):
    """
    repoze.who metadata provider to load groups and permissions data for
    the current user.
    
    There's no need to include this class in the end-user documentation,
    as there's no reason why they may ever need it... It's only by
    :func:`setup_auth`.
    
    """
    
    implements(IMetadataProvider)
    
    def __init__(self, group_adapters=None, permission_adapters=None):
        """
        Fetch the groups and permissions of the authenticated user.
        
        :param group_adapters: Set of adapters that retrieve the known groups
            of the application, each identified by a keyword.
        :type group_adapters: dict
        :param permission_adapters: Set of adapters that retrieve the
            permissions for the groups, each identified by a keyword.
        :type permission_adapters: dict
        
        """
        self.group_adapters = group_adapters
        self.permission_adapters = permission_adapters
    
    def _find_groups(self, identity):
        """
        Return the groups to which the authenticated user belongs, as well as
        the permissions granted to such groups.
        
        """
        groups = set()
        permissions = set()
        if self.group_adapters is not None:
            # repoze.what-2.X group adapters expect to find the
            # 'repoze.what.userid' key in the credentials
            credentials = identity.copy()
            credentials['repoze.what.userid'] = identity['repoze.who.userid']
            # It's using groups/permissions-based authorization
            for grp_fetcher in self.group_adapters.values():
                groups |= set(grp_fetcher.find_sections(credentials))
            for group in groups:
                for perm_fetcher in self.permission_adapters.values():
                    permissions |= set(perm_fetcher.find_sections(group))
        return tuple(groups), tuple(permissions)
    
    # IMetadataProvider
    def add_metadata(self, environ, identity):
        """
        Load the groups and permissions of the authenticated user.
        
        It will load such data into the :mod:`repoze.who` ``identity`` and 
        the :mod:`repoze.what` ``credentials`` dictionaries.
        
        :param environ: The WSGI environment.
        :param identity: The :mod:`repoze.who`'s ``identity`` dictionary.
        
        """
        logger = environ.get('repoze.who.logger')
        # Finding the groups and permissions:
        groups, permissions = self._find_groups(identity)
        identity['groups'] = groups
        identity['permissions'] = permissions
        # Adding the groups and permissions to the repoze.what credentials for
        # forward compatibility:
        if 'repoze.what.credentials' not in environ:
            environ['repoze.what.credentials'] = {}
        environ['repoze.what.credentials']['groups'] = groups
        environ['repoze.what.credentials']['permissions'] = permissions
        # Adding the userid:
        userid = identity['repoze.who.userid']
        environ['repoze.what.credentials']['repoze.what.userid'] = userid
        # Adding the adapters:
        environ['repoze.what.adapters'] = {
            'groups': self.group_adapters,
            'permissions': self.permission_adapters
            }
        # Logging
        logger and logger.info('User belongs to the following groups: %s' %
                               str(groups))
        logger and logger.info('User has the following permissions: %s' %
                               str(permissions))


def setup_auth(app, group_adapters=None, permission_adapters=None, **who_args):
    """
    Setup :mod:`repoze.who` with :mod:`repoze.what` support.
    
    :param app: The WSGI application object.
    :param group_adapters: The group source adapters to be used.
    :type group_adapters: dict
    :param permission_adapters: The permission source adapters to be used.
    :type permission_adapters: dict
    :param who_args: Authentication-related keyword arguments to be passed to
        :mod:`repoze.who`.
    :return: The WSGI application with authentication and authorization
        middleware.
    
    .. tip::
        If you are looking for an easier way to get started, you may want to
        use :mod:`the quickstart plugin <repoze.what.plugins.quickstart>` and
        its :func:`setup_sql_auth() 
        <repoze.what.plugins.quickstart.setup_sql_auth>` function.
    
    You must define the ``group_adapters`` and ``permission_adapters``
    keyword arguments if you want to use the groups/permissions-based
    authorization pattern.
    
    Additional keyword arguments will be passed to
    :func:`repoze.who.plugins.testutil.make_middleware` -- and
    among those keyword arguments, you *must* define at least the identifier(s),
    authenticator(s) and challenger(s) to be used. For example::
        
        from repoze.who.plugins.basicauth import BasicAuthPlugin
        from repoze.who.plugins.htpasswd import HTPasswdPlugin, crypt_check
        
        from repoze.what.middleware import setup_auth
        from repoze.what.plugins.xml import XMLGroupsAdapter
        from repoze.what.plugins.ini import INIPermissionAdapter

        # Defining the group adapters; you may add as much as you need:
        groups = {'all_groups': XMLGroupsAdapter('/path/to/groups.xml')}

        # Defining the permission adapters; you may add as much as you need:
        permissions = {'all_perms': INIPermissionAdapter('/path/to/perms.ini')}

        # repoze.who identifiers; you may add as much as you need:
        basicauth = BasicAuthPlugin('Private web site')
        identifiers = [('basicauth', basicauth)]

        # repoze.who authenticators; you may add as much as you need:
        htpasswd_auth = HTPasswdPlugin('/path/to/users.htpasswd', crypt_check)
        authenticators = [('htpasswd', htpasswd_auth)]

        # repoze.who challengers; you may add as much as you need:
        challengers = [('basicauth', basicauth)]

        app_with_auth = setup_auth(
            app,
            groups,
            permissions,
            identifiers=identifiers,
            authenticators=authenticators,
            challengers=challengers)
    
    .. attention::
        Keep in mind that :mod:`repoze.who` must be configured `through`
        :mod:`repoze.what` for authorization to work.
    
    .. note::
        If you want to skip authentication while testing your application,
        you should pass the ``skip_authentication`` keyword argument with a
        value that evaluates to ``True``.
    
    .. versionchanged:: 1.0.5
        :class:`repoze.who.middleware.PluggableAuthenticationMiddleware`
        replaced with :func:`repoze.who.plugins.testutil.make_middleware`
        internally.
    
    """
    authorization = AuthorizationMetadata(group_adapters,
                                          permission_adapters)
    
    if 'mdproviders' not in who_args:
        who_args['mdproviders'] = []
    
    who_args['mdproviders'].append(('authorization_md', authorization))
    
    if 'classifier' not in who_args:
        who_args['classifier'] = default_request_classifier
    
    if 'challenge_decider' not in who_args:
        who_args['challenge_decider'] = default_challenge_decider
    
    auth_log = os.environ.get('AUTH_LOG', '') == '1'
    if auth_log:
        import sys
        who_args['log_stream'] = sys.stdout
    
    skip_authn = who_args.pop('skip_authentication', False)
    middleware = make_middleware(skip_authn, app, **who_args)
    return middleware