Ic @sdZddkZddklZddklZddklZddk l Z ddk l Z ddk lZdd klZlZdd klZlZlZd d d dgZedZd efdYZd efdYZedZddedZdS(s3Test utilities for repoze.who-powered applications.iN(tINFO(tcompile(t implements(tHTTPUnauthorized(tasbool(t!PluggableAuthenticationMiddleware(t WhoConfigtmake_middleware_with_config(t IIdentifiertIAuthenticatort IChallengertAuthenticationForgerPlugintAuthenticationForgerMiddlewaretmake_middlewareRs#^(?P[0-9]{3}) (?P.*)$cBsZeZdZeeeedddZdZdZ dZ dZ dZ RS( sQ :mod:`repoze.who` plugin to forge authentication easily and bypass :mod:`repoze.who` challenges. This plugin enables you to write identifier and challenger-independent tests. As a result, your protected areas will be easier to test: #. To forge authentication, without bypassing identification (i.e., running MD providers), you can use the following WebTest-powered test:: def test_authorization_granted(self): '''The right subject must get what she requested''' environ = {'REMOTE_USER': 'manager'} resp = self.app.get('/admin/', extra_environ=environ, status=200) assert 'some text' in resp.body As you can see, this is an identifier-independent way to forge authentication. #. To check that authorization was denied, in a challenger-independent way, you can use:: def test_authorization_denied_anonymous(self): '''Anonymous users must get a 401 page''' self.app.get('/admin/', status=401) def test_authorization_denied_authenticated(self): '''Authenticated users must get a 403 page''' environ = {'REMOTE_USER': 'editor'} self.app.get('/admin/', extra_environ=environ, status=403) t REMOTE_USERsrepoze.who.testutil.useridcCs||_||_dS(sJ :param fake_user_key: The key for the item in the ``environ`` which will contain the forged user Id. :type fake_user_key: str :param remote_user_key: The actual "external" ``remote_user_key`` used by :mod:`repoze.who`. :type remote_user_key: str N(t fake_user_keytremote_user_key(tselfRR((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyt__init__Js cCs-|i|joh||id6}|SdS(s Pre-authenticate using the user Id found in the relevant ``environ`` item, if any. The user Id. found will be put into ``identity['fake-userid']``, for :meth:`authenticate`. s fake-useridN(R(Rtenvirontidentity((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pytidentifyZs cCsdS(s Do nothingN((RRR((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pytrememberhscCsdS(s Do nothingN((RRR((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pytforgetmscCs3d|jo"|id||i<||iSdS(s Turn the value in ``identity['fake-userid']`` into the remote user's name. Finally, it removes ``identity['fake-userid']`` so that it won't reach the WSGI application. s fake-useridN(tpopR(RRR((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyt authenticaters c Csy||}ti|}|o(|id}t|id}n d}d}td|} || _|| _| S(s"Return a 401 page unconditionally.treasontcodesHTTP Unauthorizeditheaders(t_HTTP_STATUS_PATTERNtsearchtgrouptintRttitleR( RRtstatust app_headerstforget_headersRt status_partsRRtresponse((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyt challenges   ( t__name__t __module__t__doc__RRR R RRRRRR'(((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyR &s      cBs eZdZdeddZRS(s :class:`PluggableAuthenticationMiddleware ` proxy to forge authentication, without bypassing identification. Rc Cs| |_td| } d| f} |id| | g}| g}tt|i} | ||||||||| d dS(s Setup authentication in an easy to forge way. All the arguments received will be passed as is to :class:`repoze.who.middleware.PluggableAuthenticationMiddleware`, with one instance of :class:`AuthenticationForgerPlugin` in: * ``identifiers``. This instance will be inserted in the first position of the list. * ``authenticators``. Any authenticator passed will be ignored; such an instance will be the only authenticator defined. * ``challengers``. Any challenger passed will be ignored; such an instance will be the only challenger defined. Internally, it will also set ``remote_user_key`` to ``'repoze.who.testutil.userid'``, so that you can use the standard ``'REMOTE_USER'`` in your tests. The metadata providers won't be modified. Rt auth_forgerisrepoze.who.testutil.useridN(tactual_remote_user_keyR tinserttsuperR R( Rtappt identifierstauthenticatorst challengerst mdproviderst classifiertchallenge_decidert log_streamt log_levelRtforgertinit((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyRs     N(R(R)R*tNoneRR(((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyR scOs,t|ot||St||SdS(s Return the requested authentication middleware. :param skip_authentication: If ``True``, an instance of :class:`AuthenticationForgerMiddleware` will be returned instead of :class:`repoze.who.middleware.PluggableAuthenticationMiddleware` :type skip_authentication: bool ``args`` and ``kwargs`` are the positional and named arguments, respectively, to be passed to the relevant authentication middleware. N(RR R(tskip_authenticationtargstkwargs((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyR s c Cs~t|pt|||||St|d}|it|t||i|i|i|i |i |i d|i S(s Proxy :func:`repoze.who.config.make_middleware_with_config` to skip authentication when required. If ``skip_authentication`` evaluates to ``True``, then the returned middleware will be an instance of :class:`AuthenticationForgerMiddleware`. thereR( Rt mk_mw_cfgRtparsetopenR R0R1R2R3trequest_classifierR5R(R/t global_conft config_filetlog_fileR7R;tparser((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyRs  (R*tsystloggingRtreRt compile_regextzope.interfaceRtpaste.httpexceptionsRtpaste.deploy.convertersRtrepoze.who.middlewareRtrepoze.who.configRRR?trepoze.who.interfacesRR R t__all__RtobjectR R tFalseR R:(((s?/usr/lib/python2.6/site-packages/repoze/who/plugins/testutil.pyts"   l1