diff options
| author | Patricio Paez <pp@pp.com.mx> | 2012-04-01 12:50:28 -0500 |
|---|---|---|
| committer | Patricio Paez <pp@pp.com.mx> | 2012-04-01 17:01:14 -0500 |
| commit | 9d05d137864df98bc1e3657f862921d2e7071ebc (patch) | |
| tree | c9b83f350ddff271880c13da702bd995bc36ed21 /docs | |
| parent | 611582fafe01261777289bf3bd71a83413f977ab (diff) | |
| download | pyramid-9d05d137864df98bc1e3657f862921d2e7071ebc.tar.gz pyramid-9d05d137864df98bc1e3657f862921d2e7071ebc.tar.bz2 pyramid-9d05d137864df98bc1e3657f862921d2e7071ebc.zip | |
More simplification to the Authorization chapter
- Clarify the Adding A Root Factory section, include
a related modification to __init__.py
- Added Add routes for /login and /logout section
- Added yellow higlighting in various listings
- Consolidate all the Seeing our changes at the end
- Use a 'do, then explain' pattern
Diffstat (limited to 'docs')
| -rw-r--r-- | docs/tutorials/wiki2/authorization.rst | 138 |
1 files changed, 90 insertions, 48 deletions
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 55c2ab7d3..c6c79086a 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -14,10 +14,12 @@ the server to view pages. We will do the following steps: -* Add a :term:`root factory` with an :term:`ACL` (``models.py``). +* Add a :term:`root factory` with an :term:`ACL` (``models.py``, + ``__init__.py``). * Add an :term:`authentication policy` and an :term:`authorization policy` (``__init__.py``). * Add an authentication policy callback (new ``security.py`` module). +* Add routes for /login and /logout (``__init__.py``). * Add ``login`` and ``logout`` views (``views.py``). * Add :term:`permission` declarations to the ``edit_page`` and ``add_page`` views (``views.py``). @@ -33,28 +35,40 @@ The source code for this tutorial stage can be browsed at Adding A Root Factory ~~~~~~~~~~~~~~~~~~~~~ -Open ``models.py`` and add the following statements: +Open ``tutorial/tutorial/models.py`` and add the following import +statement at the head: .. literalinclude:: src/authorization/tutorial/models.py - :lines: 1-4,35-39 + :lines: 1-4 :linenos: :language: python -We're going to start to use a custom :term:`root factory` within our -``__init__.py`` file. The objects generated by the root factory will -be used as the :term:`context` of each request to our application. -Those context objects will be decorated with security -declarations. When we use a custom root factory to generate -our contexts, we can begin to make use of the declarative security -features of :app:`Pyramid`. +Add the following class definition: -We'll modify our ``__init__.py``, passing in a :term:`root factory` to our -:term:`Configurator` constructor. We'll point it at the new class we created -inside our ``models.py`` file. +.. literalinclude:: src/authorization/tutorial/models.py + :lines: 35-39 + :linenos: + :language: python + +The ``RootFactory`` class is a :term:`root factory` that will be used by +:app:`Pyramid` to construct the :term:`context` of each request to +our application. The context is attached to the request +object passed to our view callables as the ``context`` attribute, +and will be decorated with security declarations. By using a custom +root factory to generate our contexts, we can use the +declarative security features of :app:`Pyramid`. + +Open ``tutorial/tutorial/__init__.py`` and add a ``root_factory`` +parameter to our :term:`Configurator` constructor, that points to +the class we created above: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 19-20 + :linenos: + :emphasize-lines: 2 + :language: python -The ``RootFactory`` class we've just added will be used by :app:`Pyramid` to -construct a ``context`` object. The context is attached to the request -object passed to our view callables as the ``context`` attribute. +(Only the highlighted line needs to be added.) The context object generated by our root factory will possess an ``__acl__`` attribute that allows :data:`pyramid.security.Everyone` (a special principal) @@ -71,15 +85,9 @@ information about what an :term:`ACL` represents. the ``factory`` argument to :meth:`pyramid.config.Configurator.add_route` for more info. -We'll pass the ``RootFactory`` we created in the step above in as the -``root_factory`` argument to a :term:`Configurator`. - Add an Authorization Policy and an Authentication Policy ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We're going to be making several changes to our ``__init__.py`` file which -will help us configure an authorization policy. - For any :app:`Pyramid` application to perform authorization, we need to add a ``security.py`` module (we'll do that shortly) and we'll need to change our ``__init__.py`` file to add an :term:`authentication policy` and an @@ -100,8 +108,11 @@ Now add those policies to the configuration: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 16-22 :linenos: + :emphasize-lines: 1-3,6-7 :language: python +(Only the highlighted lines need to be added.) + Note that the :class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor accepts two arguments: ``secret`` and ``callback``. ``secret`` is a string @@ -110,31 +121,18 @@ represented by this policy: it is required. The ``callback`` is a ``groupfinder`` function in the current directory's ``security.py`` file. We haven't added that module yet, but we're about to. -Viewing Your Changes --------------------- - -When we're done configuring a root factory, adding a authentication and -authorization policies, and adding routes for ``/login`` and ``/logout``, -your application's ``__init__.py`` will look like this: - -.. literalinclude:: src/authorization/tutorial/__init__.py - :linenos: - :emphasize-lines: 2-3,7,16-18,20-22,25-26 - :language: python - Adding an authentication policy callback ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add a ``tutorial/security.py`` module within your package (in the same -directory as :file:`__init__.py`, :file:`views.py`, etc.) with the +Create a new ``tutorial/tutorial/security.py`` module with the following content: .. literalinclude:: src/authorization/tutorial/security.py :linenos: :language: python -The ``groupfinder`` function defined here is an :term:`authentication policy` -"callback"; it is a callable that accepts a userid and a request. If +``groupfinder()`` is an :term:`authentication policy` +"callback"; it is a function that accepts a userid and a request. If the userid exists in the system, the callback will 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 @@ -153,6 +151,16 @@ the root factory, and the permission associated with the ``add_page`` and ``edit_page`` views, the ``editor`` user should be able to add and edit pages. +Add routes for /login and /logout +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Go back to ``tutorial/tutorial/__init__.py`` and add these two +routes: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 25-26 + :linenos: + :language: python + Adding Login and Logout Views ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -197,13 +205,16 @@ We'll need to import some stuff to service the needs of these two functions: the ``pyramid.view.forbidden_view_config`` class, a number of values from the ``pyramid.security`` module, and a value from our newly added ``tutorial.security`` package. Add the following import statements to the -head of the ``views.py`` file: +head of ``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py :lines: 9-18,24-25 :linenos: + :emphasize-lines: 3,7-8,12 :language: python +(Only the highlighted lines need to be added.) + Add permission declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -212,10 +223,13 @@ decorator for ``add_page()`` and ``edit_page()``, for example: .. code-block:: python :linenos: + :emphasize-lines: 2 @view_config(route_name='add_page', renderer='templates/edit.pt', permission='edit') +(Only the highlighted line needs to be added.) + The result is that only users who possess the ``edit`` permission at the time of the request may invoke those two views. @@ -228,18 +242,36 @@ routes. Return a logged_in flag to the renderer ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Change the return value of the ``view_page``, -``edit_page`` and ``add_page`` view callables in ``views.py`` -to pass a ``logged_in`` value to the template, e.g.: +Add the following import statement to the head of +``tutorial/tutorial/views.py``: + +.. code-block:: python + :linenos: + + from pyramid.security import ( + authenticated_userid, + ) + + +Add a ``logged_in`` parameter to the return value of +``view_page()``, ``edit_page()`` and ``add_page()``, +like this: .. code-block:: python :linenos: + :emphasize-lines: 3 return dict(page = page, content = content, logged_in = authenticated_userid(request), edit_url = edit_url) +(Only the highlighted line needs to be added.) + +:meth:`~pyramid.security.authenticated_userid()` will return None +if the user is not authenticated, or some user id it the user +is authenticated. + Adding the ``login.pt`` Template ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -255,10 +287,6 @@ added to ``views.py``. Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -We'll 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. - Open ``tutorial/tutorial/templates/edit.pt`` and ``tutorial/tutorial/templates/view.pt`` and add this within the ``<div id="right" class="app-welcome align-right">`` div: @@ -269,8 +297,22 @@ Open ``tutorial/tutorial/templates/edit.pt`` and <a href="${request.application_url}/logout">Logout</a> </span> -Seeing Our Changes To ``views.py`` and our Templates -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +The attribute ``tal:condition="logged_in"`` will make the element be +included when ``logged_in`` is any user id. The link will invoke +the logout view. The above element will not be included if ``logged_in`` +is ``None``, such as when a user is not authenticated. + +Seeing Our Changes +~~~~~~~~~~~~~~~~~~ + +Our ``__init__.py`` module will look something like this when we're done: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :linenos: + :emphasize-lines: 2-3,7,16-18,20-22,25-26 + :language: python + +(Only the highlighted lines need to be added.) Our ``views.py`` module will look something like this when we're done: |
