def test_it(self): L = [] def gen(L=L): L.append('yo!') yield 'a' yield 'b' wrap_generator = self._getFUT() newgen = wrap_generator(gen()) self.assertEqual(L, ['yo!']) self.assertEqual(list(newgen), ['a', 'b'])
def _callFUT(self, iterable): from repoze.who.middleware import wrap_generator return wrap_generator(iterable)
def __call__(self, environ, start_response): """ Cette méthode est inspirée de C{repoze.who.middleware.PluggableAuthenticationMiddleware:__call__}. La différence réside dans le fait que la méthode originale désactive complètement le middleware d'authentification lorsqu'un identifiant d'utilisateur est passé dans l'environnement (par exemple, via la variable C{REMOTE_USER}). Au contraire, cette version s'assure que les modules qui interviennent après les processus d'identification et d'authentification de l'utilisateur sont quand même appelés. Ceci permet par exemple de récupérer des informations importantes concernant l'utilisateur (depuis la base de données par exemple) via les modules fournisseurs de méta-données (mdproviders). """ path_info = environ.get('PATH_INFO', None) environ['repoze.who.plugins'] = self.name_registry environ['repoze.who.logger'] = self.logger environ['repoze.who.application'] = self.app environ['repoze.who.remote_user_key'] = self.remote_user_key environ['vigilo.external_auth'] = False logger = self.logger logger and logger.info(_STARTED % path_info) classification = self.classifier(environ) logger and logger.info('request classification: %s' % classification) identity = None identifier = None userid = environ.get(self.remote_user_key) if userid: logger and logger.info('using external identity: %s' % userid) # Pas besoin d'effectuer les phases d'identification # et d'authentification si elles ont déjà été faites en amont. identity = { 'login': userid, 'password': None, 'repoze.who.userid': userid, } # Marque l'utilisateur comme identifié par un mécanisme externe. environ['vigilo.external_auth'] = True else: ids = self.identify(environ, classification) # ids will be list of tuples: [ (IIdentifier, identity) ] if ids: auth_ids = self.authenticate(environ, classification, ids) # auth_ids will be a list of five-tuples in the form # ( (auth_rank, id_rank), authenticator, identifier, identity, # userid ) # # When sorted, its first element will represent the "best" # identity for this request. if auth_ids: auth_ids.sort() best = auth_ids[0] rank, authenticator, identifier, identity, userid = best else: logger and logger.info('no identities found, not authenticating') # Même si un mécanisme externe d'authentification a été utilisé, # on fait appel aux "mdproviders" pour peupler les méta-données. if identity: identity = Identity(identity) # don't show contents at print # allow IMetadataProvider plugins to scribble on the identity self.add_metadata(environ, classification, identity) # add the identity to the environment; a downstream # application can mutate it to do an 'identity reset' # as necessary, e.g. identity['login'] = '******', # identity['password'] = '******' environ['repoze.who.identity'] = identity # allow identifier plugins to replace the downstream # application (to do redirection and unauthorized themselves # mostly) app = environ.pop('repoze.who.application') if app is not self.app: logger and logger.info( 'static downstream application replaced with %s' % app) wrapper = StartResponseWrapper(start_response) app_iter = app(environ, wrapper.wrap_start_response) # The challenge decider almost(?) always needs information from the # response. The WSGI spec (PEP 333) states that a WSGI application # must call start_response by the iterable's first iteration. If # start_response hasn't been called, we'll wrap it in a way that # triggers that call. if not wrapper.called: app_iter = wrap_generator(app_iter) if self.challenge_decider(environ, wrapper.status, wrapper.headers): logger and logger.info('challenge required') challenge_app = self.challenge( environ, classification, wrapper.status, wrapper.headers, identifier, identity ) if challenge_app is not None: logger and logger.info('executing challenge app') if app_iter: list(app_iter) # unwind the original app iterator # replace the downstream app with the challenge app app_iter = challenge_app(environ, start_response) else: logger and logger.info('configuration error: no challengers') raise RuntimeError('no challengers found') else: logger and logger.info('no challenge required') remember_headers = [] if identifier: remember_headers = identifier.remember(environ, identity) if remember_headers: logger and logger.info('remembering via headers from %s: %s' % (identifier, remember_headers)) wrapper.finish_response(remember_headers) logger and logger.info(_ENDED % path_info) return app_iter