summaryrefslogtreecommitdiff
path: root/docs/tutorials/bfgwiki/authorization.rst
diff options
context:
space:
mode:
authorChris McDonough <chrism@agendaless.com>2009-05-30 06:54:31 +0000
committerChris McDonough <chrism@agendaless.com>2009-05-30 06:54:31 +0000
commitb0a3958409901788da67ad5bf9f8ff4e664c6516 (patch)
tree4534d2d96b9444a4663c41b03f0f108cf0ed5335 /docs/tutorials/bfgwiki/authorization.rst
parentc92023b5bd630a91f2ae1dc8812349d920105343 (diff)
downloadpyramid-b0a3958409901788da67ad5bf9f8ff4e664c6516.tar.gz
pyramid-b0a3958409901788da67ad5bf9f8ff4e664c6516.tar.bz2
pyramid-b0a3958409901788da67ad5bf9f8ff4e664c6516.zip
Modify tutorial for a6.
Diffstat (limited to 'docs/tutorials/bfgwiki/authorization.rst')
-rw-r--r--docs/tutorials/bfgwiki/authorization.rst235
1 files changed, 84 insertions, 151 deletions
diff --git a/docs/tutorials/bfgwiki/authorization.rst b/docs/tutorials/bfgwiki/authorization.rst
index 3b5c2e3de..f52312c14 100644
--- a/docs/tutorials/bfgwiki/authorization.rst
+++ b/docs/tutorials/bfgwiki/authorization.rst
@@ -7,133 +7,121 @@ view, edit, and add pages to our wiki. For purposes of demonstration
we'll change our application to allow people whom possess a specific
username (`editor`) to add and edit wiki pages but we'll continue
allowing anyone with access to the server to view pages.
+:mod:`repoze.bfg` provides facilities for *authorization* and
+*authentication*. We'll make use of both features to provide security
+to our application.
-:mod:`repoze.bfg` provides a facility for *authorization*, but it
-relies on "upstream" software to provide *authentication* information.
-We're going to use a package named ``repoze.who`` to our setup, and
-we'll rely on it to give us authentication information.
-
-Adding a Dependency on ``repoze.who`` to Our ``setup.py`` File
---------------------------------------------------------------
-
-We need to change our ``setup.py`` file, adding a dependency on the
-``repoze.who`` package. The ``repoze.who`` package provides a
-mechanism for providing *authentication* data via :term:`WSGI`
-middleware. We'll add the ``repoze.who`` package to our ``requires``
-list.
+Configuring a ``repoze.bfg`` Authentication Policy
+--------------------------------------------------
-The resulting setup.py file:
+For any :mod:`repoze.bfg` application to perform authorization, we
+need to change our ``run.py`` module to add an :term:`authentication
+policy`. Adding an authentication policy actually causes the system
+to begin to use :term:`authorization`.
+
+Changing ``run.py``
+~~~~~~~~~~~~~~~~~~~
+
+Change your ``run.py`` module to import the
+``AuthTktAuthenticationPolicy`` from ``repoze.bfg.authentication``.
+Within the body of the ``make_app`` function, construct an instance of
+the policy, and pass it as the ``authentication_policy`` argument to
+the ``make_app`` function. The first positional argument of an
+``AuthTktAuthenticationPolicy`` is a secret used to encrypt cookie
+data. Its second argument ("callback") should be a callable that
+accepts a userid. If the userid exists in the system, the callback
+should return a sequence of group identifiers (or an empty sequence if
+the user isn't a member of any groups). If the userid *does not*
+exist in the system, the callback should return ``None``. We'll use
+"dummy" data to represent user and groups sources. When we're done,
+your application's ``run.py`` will look like this.
-.. literalinclude:: src/authorization/setup.py
+.. literalinclude:: src/authorization/tutorial/run.py
:linenos:
:language: python
-Changing our ``tutorial.ini`` file to Include the ``repoze.who`` Middleware
----------------------------------------------------------------------------
-
-In order to make use of the ``repoze.who`` middleware which provides
-authentication services, we need to wire it into our ``tutorial.ini``
-file. We'll add a ``[filter:who]`` section to our ``tutorial.ini``
-file and wire it into our pipeline. Our resulting ``tutorial.ini``
-file will look like so:
+BFG's ``make_app`` callable also can accept an authorization policy
+parameter. We don't need to specify one, we'll use the default.
-.. literalinclude:: src/authorization/tutorial.ini
- :linenos:
- :language: ini
+Adding Login and Logout Views
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-Note that we added a ``who`` line to our pipeline. This refers to the
-``[filter:who]`` section above it. The ``[filter:who]`` section has a
-``use`` line that points at an egg entry point for configuring the
-repoze.who middleware via a config file. The ``config_file`` line
-points at an .ini config file named ``who.ini``. This file is assumed
-to live in the same directory as the ``tutorial.ini`` file. We'll
-need to create this file in order to get authentication working.
+We'll add a ``login`` view which renders a login form and processes
+the post from the login form, checking credentials.
-Adding a ``who.ini`` File
--------------------------
+We'll also add a ``logout`` view to our application and provide a link
+to it. This view will clear the credentials of the logged in user and
+redirect back to the front page.
-We'll create a file in our package directory named ``who.ini``. It
-will have the following contents.
+We'll add a different file (for presentation convenience) to add login
+and logout views. Add a file to your application in the same
+directory as ``login.py`` with the following content:
-.. literalinclude:: src/authorization/who.ini
+.. literalinclude:: src/authorization/tutorial/login.py
:linenos:
- :language: ini
+ :language: python
-The ``[general]``, ``[identifiers]``, ``[authenticators]``, and
-``[challengers]`` section of this file are the meat of the
-configuration in this file.
+Changing Existing Views
+~~~~~~~~~~~~~~~~~~~~~~~
-The ``[general]`` Section
-~~~~~~~~~~~~~~~~~~~~~~~~~
+Then we need to change each opf our ``view_page``, ``edit_page`` and
+``add_page`` views to pass a "logged in" parameter into its template.
+We'll add something like this to each view body:
-The ``[general]`` section configures the default "request classifier"
-and "challenge decider". For the purposes of this tutorial, it is not
-important that you understand these settings.
+.. code-block:: python
+ :linenos:
-The ``[identifiers]`` Section
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ logged_in = authenticated_user(context, request)
-The ``[identifiers]`` section configures the identifier plugins that
-will be used for this application. In our case, our identifiers are
-both the ``form`` plugin (configured above the ``[identifiers]``
-section within ``[plugin:form]``) and the ``auth_tkt`` plugin
-(configured above the ``[identifiers]`` section within
-``[plugin:auth_tkt]``. The ``form`` identifier will only be used when
-the request is a "browser request" (for example, it *won't* be used
-when the request is an XML-RPC request).
+We'll then change the return value of ``render_template_to_response``
+to pass the `resulting `logged_in`` value to the template, e.g.:
-The ``[authenticators]`` Section
+.. code-block:: python
+ :linenos:
+
+ return render_template_to_response('templates/view.pt',
+ request = request,
+ page = context,
+ content = content,
+ logged_in = logged_in,
+ edit_url = edit_url)
+
+Adding the ``login.pt`` Template
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The ``[authenticators]`` section configures the "authenticator"
-plugins that will be used in our setup. An authenticator plugin is
-one which checks a username and password provided by a user against a
-database of valid username/password combinations. We'll use an
-htpasswd file as this database. Since the ``htpasswd`` plugin
-requires a file, we'll need to add a ``wiki.passwd`` file to our
-``tutorial`` package with these contents:
+Add a ``login.pt`` template to your templates directory. It's
+referred to within the login view we just added to ``login.py``.
-.. literalinclude:: src/authorization/wiki.passwd
+.. literalinclude:: src/authorization/tutorial/templates/login.pt
:linenos:
- :language: ini
+ :language: xml
-The ``[challengers]`` Section
-~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+Change ``view.pt`` and ``edit.pt``
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-The ``[challengers]`` section configures a "challenger" which is a
-``repoze.who`` plugin which displays a login form. We'll use the
-standard ``repoze.who.plugins.form`` plugin for this, configured
-within the ``[plugin:form]`` section of the file.
+We'll also need to change our ``edit.pt`` and ``view.pt`` templates to
+display a "Logout" link if someone is logged in. This link will
+invoke the logout view.
-The ``[plugin:*]`` Sections
----------------------------
+To do so we'll add this to both templates within the ``<div
+class="main_content">`` div:
-The ``[plugin:*]`` sections of the configuration file configure
-individual plugins used by the more general configuration sections
-(``[identifiers]``, ``[authenticators]``, ``[challengers]``). The
-``auth_tkt`` plugin is an identifier plugin which obtains credentials
-from a cookie, the ``form`` plugin is an identifier and challenger
-plugin which obtains credentials from a form post, the ``htpasswd``
-plugin is an authenticator plugin which checks credentials against
-valid usernames and files specified in an htpasswd file.
+.. code-block:: xml
+ :linenos:
-Configuring a ``repoze.bfg`` Authentication Policy
---------------------------------------------------
+ <span tal:condition="logged_in"><a href="${request.application_url}/logout">Logout</a></span>
-For any :mod:`repoze.bfg` application to perform authorization, we
-need to change our ``run.py`` module to add an :term:`authentication
-policy`. Adding an authentication policy causes the system to use
-authorization.
+Changing ``configure.zcml``
+~~~~~~~~~~~~~~~~~~~~~~~~~
-Change your run.py to import the ``RepozeWho1AuthenticationPolicy``
-from ``repoze.who.authentication``, construct an instance of the
-policy, and pass it as the ``authentication_policy`` argument to the
-``make_app`` function. When you're done, your application's
-``run.py`` will look like this.
+Change your application's ``configure.zcml`` to add a slightly
+inscrutable ``utility`` stanza. This configures our login view to
+show up when BFG detects that a view invocation can not be authorized.
+When you're done, your ``configure.zcml`` will look like so:
-.. literalinclude:: src/authorization/tutorial/run.py
+.. literalinclude:: src/authorization/tutorial/configure.zcml
:linenos:
- :language: python
+ :language: xml
Giving Our Root Model Object an ACL
-----------------------------------
@@ -248,61 +236,6 @@ our application in a browser. The views we'll try are as follows:
username ``editor``, password ``editor`` will show the edit page
form being displayed.
-Add A Logout View
--------------------
-
-We'll add a ``logout`` view to our application and provide a link to
-it. This view will clear the credentials of the logged in user and
-redirect back to the front page. The logout view will look someting
-like this:
-
-.. code-block:: python
- :linenos:
-
- @bfg_view(for_=Wiki, name='logout')
- def logout(context, request):
- identity = request.environ.get('repoze.who.identity')
- headers = []
- if identity is not None:
- auth_tkt = request.environ['repoze.who.plugins']['auth_tkt']
- headers = auth_tkt.forget(request.environ, identity)
- return HTTPFound(location = model_url(context, request),
- headers = headers)
-
-
-We'll also change our ``edit.pt`` template to display a "Logout" link
-if someone is logged in. This link will invoke the logout view.
-
-To do so we'll add this to both templates within the ``<div
-class="main_content">`` div:
-
-.. code-block:: xml
- :linenos:
-
- <span tal:condition="logged_in"><a href="${request.application_url}/logout">Logout</a></span>
-
-Then we need to change each opf our ``view_page``, ``edit_page`` and
-``add_page`` views to pass a "logged in" parameter into its template.
-We'll add something like this to each view body:
-
-.. code-block:: python
- :linenos:
-
- logged_in = 'repoze.who.identity' in request.environ
-
-We'll then change the return value of ``render_template_to_response``
-to pass the `resulting `logged_in`` value to the template, e.g.:
-
-.. code-block:: python
- :linenos:
-
- return render_template_to_response('templates/view.pt',
- request = request,
- page = context,
- content = content,
- logged_in = logged_in,
- edit_url = edit_url)
-
Seeing Our Changes To ``views.py`` and our Templates
----------------------------------------------------