From cfd4e5e06d05dac3e8f1c03b63bc3cf37242334a Mon Sep 17 00:00:00 2001 From: Chris McDonough Date: Sun, 25 Jan 2009 02:30:46 +0000 Subject: - You can now override the NotFound and Unauthorized responses that :mod:`repoze.bfg` generates when a view cannot be found or cannot be invoked due to lack of permission. See the "ZCML Hooks" chapter in the docs for more information. - Use a homegrown Unauthorized error instead of ``webob.exc.Unauthorized`` (the latter is slow). - Various speed micro-tweaks. --- docs/narr/hooks.rst | 135 +++++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 122 insertions(+), 13 deletions(-) (limited to 'docs') diff --git a/docs/narr/hooks.rst b/docs/narr/hooks.rst index 08164eddc..585e3e655 100644 --- a/docs/narr/hooks.rst +++ b/docs/narr/hooks.rst @@ -5,7 +5,7 @@ Using ZCML Hooks ZCML "hooks" can be used to influence the behavior of the :mod:`repoze.bfg` framework in various ways. This is an advanced -topic; very few people will want or need to do any of these things. +topic; not many people will want or need to do any of these things. Changing the request factory ---------------------------- @@ -21,22 +21,36 @@ ZCML in your ``configure.zcml`` file. :linenos: + component="helloworld.factories.request_factory"/> -Replace ``my.request.factory`` with the Python dotted name to the -request factory you want to use. +Replace ``helloworld.factories.request_factory`` with the Python +dotted name to the request factory you want to use. Here's some +sample code that implements a minimal request factory: -.. warning:: If you register an IRequestFactory utility in such a way, - you *must* be sure that the factory returns an object that +.. code-block:: python + + from webob import Request + from repoze.bfg.interfaces import IRequest + + class MyRequest(Request): + implements(IRequest) + + def request_factory(): + return MyRequest + +.. warning:: If you register an ``IRequestFactory`` utility in this + way, you *must* be sure that the factory returns an object that implements *at least* the ``repoze.bfg.interfaces.IRequest`` interface. Otherwise all application view lookups will fail (they will all return a 404 response code). Likewise, if you want to be able to use method-related interfaces such as ``IGETRequest``, - ``IPOSTRequest``, etc. in your view declarations, your factory must - also do the same introspection of the environ that the default - request factory does, and cause the custom factory to decorate the + ``IPOSTRequest``, etc. in your view declarations, the callable + returned by the factory must also do the same introspection of the + environ that the default request factory does and decorate the returned object to implement one of these interfaces based on the - ``HTTP_METHOD`` present in the environ. + ``HTTP_METHOD`` present in the environ. Note that the above + example does not do this, so lookups for method-related interfaces + will fail. Changing the response factory ----------------------------- @@ -53,8 +67,103 @@ following ZCML in your ``configure.zcml`` file. :linenos: + component="helloworld.factories.response_factory"/> + +Replace ``helloworld.factories.response_factory`` with the Python +dotted name to the response factory you want to use. Here's some +sample code that implements a minimal response factory: + +.. code-block:: python + + from webob import Response + + class MyResponse(Response): + pass + + def response_factory(): + return MyResponse + +Unlike a request factory, a response factory does not need to return +an object that implements any particular interface; it simply needs +have a ``status`` attribute, a ``headerlist`` attribute, and and +``app_iter`` attribute. + +Changing the NotFound application +--------------------------------- + +When :mod:`repoze.bfg` can't map a URL to code, it creates and invokes +a NotFound WSGI application. The application it invokes can be +customized by placing something like the following ZCML in your +``configure.zcml`` file. + +.. code-block:: xml + :linenos: + + + +Replace ``helloworld.factories.notfound_app_factory`` with the Python +dotted name to the request factory you want to use. Here's some +sample code that implements a minimal NotFound application factory: + +.. code-block:: python + + from webob.exc import HTTPNotFound + + class MyNotFound(HTTPNotFound): + pass + + def notfound_app_factory(): + return MyNotFound + +.. note:: When a NotFound application factory is invoked, it is passed + the WSGI environ and the WSGI ``start_response`` handler by + :mod:`repoze.bfg`. Within the WSGI environ will be a key named + ``message`` that has a value explaining why the not found error was + raised. This error will be different when the ``debug_notfound`` + environment setting is true than it is when it is false. + +Changing the Unauthorized application +------------------------------------- + +When :mod:`repoze.bfg` can't authorize execution of a view based on +the security policy in use, it creates and invokes an Unauthorized +WSGI application. The application it invokes can be customized by +placing something like the following ZCML in your ``configure.zcml`` +file. + +.. code-block:: xml + :linenos: + + + +Replace ``helloworld.factories.unauthorized_app_factory`` with the +Python dotted name to the request factory you want to use. Here's +some sample code that implements a minimal Unauthorized application +factory: + +.. code-block:: python + + from webob.exc import HTTPUnauthorized + + class MyUnauthorized(HTTPUnauthorized): + pass + + def notfound_app_factory(): + return MyUnauthorized -Replace ``my.response.factory`` with the Python dotted name to the -response factory you want to use. +.. note:: When an Unauthorized application factory is invoked, it is + passed the WSGI environ and the WSGI ``start_response`` handler by + :mod:`repoze.bfg`. Within the WSGI environ will be a key named + ``message`` that has a value explaining why the action was not + authorized. This error will be different when the + ``debug_authorization`` environment setting is true than it is when + it is false. +.. note:: You can influence the status code of Unauthorized responses + by using an alterate unauthorized application factory. For + example, you may return an unauthorized application with a ``403 + Forbidden`` status code, rather than use the default unauthorized + application factory, which sends a response with a ``401 + Unauthorized`` status code. -- cgit v1.2.3