summaryrefslogtreecommitdiff
path: root/docs
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-01-25 02:30:46 +0000
committerChris McDonough <chrism@agendaless.com>2009-01-25 02:30:46 +0000
commitcfd4e5e06d05dac3e8f1c03b63bc3cf37242334a (patch)
tree506481ffc66fef568749c27bcd2611fe9a98d1b0 /docs
parentfbd7ff75bde1c59c1b791b0db1be4f81f81d2d3d (diff)
downloadpyramid-cfd4e5e06d05dac3e8f1c03b63bc3cf37242334a.tar.gz
pyramid-cfd4e5e06d05dac3e8f1c03b63bc3cf37242334a.tar.bz2
pyramid-cfd4e5e06d05dac3e8f1c03b63bc3cf37242334a.zip
- 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.
Diffstat (limited to 'docs')
-rw-r--r--docs/narr/hooks.rst135
1 files changed, 122 insertions, 13 deletions
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:
<utility provides="repoze.bfg.interfaces.IRequestFactory"
- component=".my.request.factory"/>
+ 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:
<utility provides="repoze.bfg.interfaces.IResponseFactory"
- component=".my.response.factory"/>
+ 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:
+
+ <utility provides="repoze.bfg.interfaces.INotFoundAppFactory"
+ component="helloworld.factories.notfound_app_factory"/>
+
+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:
+
+ <utility provides="repoze.bfg.interfaces.IUnauthorizedAppFactory"
+ component="helloworld.factories.unauthorized_app_factory"/>
+
+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.