diff options
Diffstat (limited to 'docs/tutorials/wiki2/authorization.rst')
| -rw-r--r-- | docs/tutorials/wiki2/authorization.rst | 138 |
1 files changed, 72 insertions, 66 deletions
diff --git a/docs/tutorials/wiki2/authorization.rst b/docs/tutorials/wiki2/authorization.rst index 8d30ab807..64cab30db 100644 --- a/docs/tutorials/wiki2/authorization.rst +++ b/docs/tutorials/wiki2/authorization.rst @@ -27,43 +27,35 @@ Adding A Root Factory ~~~~~~~~~~~~~~~~~~~~~ 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. In -order for :app:`Pyramid` declarative security to work properly, the -context object generated during a request must be decorated with -security declarations; when we begin to use a custom root factory to -generate our contexts, we can begin to make use of the declarative -security features of :app:`Pyramid`. +``__init__.py`` file. The objects generated by the root factory will be used +as the :term:`context` of each request to our application. We do this to +allow :app:`Pyramid` declarative security to work properly. The context +object generated by the root factory during a request will be decorated with +security declarations. When we begin to use a custom root factory to generate +our contexts, we can begin to make use of the declarative security features +of :app:`Pyramid`. We'll modify our ``__init__.py``, passing in a :term:`root factory` to our :term:`Configurator` constructor. We'll point it at a new class we create inside our ``models.py`` file. Add the following statements to your ``models.py`` file: -.. code-block:: python +.. literalinclude:: src/authorization/tutorial/models.py + :lines: 3-4,45-49 + :linenos: + :language: python - from pyramid.security import Allow - from pyramid.security import Everyone - - class RootFactory(object): - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] - def __init__(self, request): - pass - -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. - -All of our context objects will possess an ``__acl__`` attribute that -allows :data:`pyramid.security.Everyone` (a special principal) to -view all pages, while allowing only a :term:`principal` named -``group:editors`` to edit and add pages. The ``__acl__`` attribute -attached to a context is interpreted specially by :app:`Pyramid` as -an access control list during view callable execution. See -:ref:`assigning_acls` for more information about what an :term:`ACL` -represents. +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. + +The context object generated by our root factory will possess an ``__acl__`` +attribute that allows :data:`pyramid.security.Everyone` (a special principal) +to view all pages, while allowing only a :term:`principal` named +``group:editors`` to edit and add pages. The ``__acl__`` attribute attached +to a context is interpreted specially by :app:`Pyramid` as an access control +list during view callable execution. See :ref:`assigning_acls` for more +information about what an :term:`ACL` represents. .. note: Although we don't use the functionality here, the ``factory`` used to create route contexts may differ per-route as opposed to globally. See @@ -84,30 +76,10 @@ For any :app:`Pyramid` application to perform authorization, we need to add a We'll change our ``__init__.py`` file to enable an ``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to enable -declarative security checking. We'll also change ``__init__.py`` to add a -:meth:`pyramid.config.Configurator.add_view` call to points at our -``login`` :term:`view callable`, also known as a :term:`forbidden view`. -This configures our newly created login view to show up when :app:`Pyramid` -detects that a view invocation can not be authorized. Also, we'll add -``view_permission`` arguments with the value ``edit`` to the ``edit_page`` -and ``add_page`` routes. This indicates that the view callables which these -routes reference cannot be invoked without the authenticated user possessing -the ``edit`` permission with respect to the current context. - -This makes the assertion that only users who possess the effective ``edit`` -permission at the time of the request may invoke those two views. We've -granted the ``group:editors`` principal the ``edit`` permission at the root -model via its ACL, so only the a user whom is a member of the group named -``group:editors`` will able to invoke the views associated with the -``add_page`` or ``edit_page`` routes. - -Viewing Your Changes -~~~~~~~~~~~~~~~~~~~~ - -When we're done configuring a root factory, adding an authorization policy, -and adding views, your application's ``__init__.py`` will look like this: +declarative security checking. .. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 15-21 :linenos: :language: python @@ -120,12 +92,52 @@ representing a :term:`dotted Python name`, which points at the ``groupfinder`` function in the current directory's ``security.py`` file. We haven't added that module yet, but we're about to. +We'll also change ``__init__.py``, adding a call to +:meth:`pyramid.config.Configurator.add_view` that points at our ``login`` +:term:`view callable`. This is also known as a :term:`forbidden view`: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 24-26 + :linenos: + :language: python + +A forbidden view configures our newly created login view to show up when +:app:`Pyramid` detects that a view invocation can not be authorized. + +We'll also add ``view_permission`` arguments with the value ``edit`` to the +``edit_page`` and ``add_page`` routes. This indicates that the view +callables which these routes reference cannot be invoked without the +authenticated user possessing the ``edit`` permission with respect to the +current context. + +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 32-39 + :linenos: + :language: python + +Adding these ``view_permission`` arguments causes Pyramid to make the +assertion that only users who possess the effective ``edit`` permission at +the time of the request may invoke those two views. We've granted the +``group:editors`` principal the ``edit`` permission at the root model via its +ACL, so only the a user whom is a member of the group named ``group:editors`` +will able to invoke the views associated with the ``add_page`` or +``edit_page`` routes. + +Viewing Your Changes +~~~~~~~~~~~~~~~~~~~~ + +When we're done configuring a root factory, adding an authorization policy, +and adding views, your application's ``__init__.py`` will look like this: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :linenos: + :language: python Adding ``security.py`` ~~~~~~~~~~~~~~~~~~~~~~ Add a ``security.py`` module within your package (in the same directory as -"__init__.py", "views.py", etc) with the following content: +:file:`__init__.py`, :file:`views.py`, etc) with the following content: .. literalinclude:: src/authorization/tutorial/security.py :linenos: @@ -161,7 +173,7 @@ 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 add a different file (for presentation convenience) to add login -and logout view callables. Add a file named ``login.py`` to your +and the logout view callables. Add a file named ``login.py`` to your application (in the same directory as ``views.py``) with the following content: @@ -173,8 +185,8 @@ Changing Existing Views ~~~~~~~~~~~~~~~~~~~~~~~ Then we need to change each of our ``view_page``, ``edit_page`` and -``add_page`` views in ``views.py`` to pass a "logged in" parameter to -its template. We'll add something like this to each view body: +``add_page`` views in ``views.py`` to pass a "logged in" parameter to its +template. We'll add something like this to each view body: .. ignore-next-block .. code-block:: python @@ -183,8 +195,8 @@ its template. We'll add something like this to each view body: from pyramid.security import authenticated_userid logged_in = authenticated_userid(request) -We'll then change the return value of these views to pass the -`resulting `logged_in`` value to the template, e.g.: +We'll then change the return value of these views to pass the `resulting +`logged_in`` value to the template, e.g.: .. ignore-next-block .. code-block:: python @@ -202,7 +214,6 @@ 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/tutorial/templates/login.pt - :linenos: :language: xml Change ``view.pt`` and ``edit.pt`` @@ -212,11 +223,10 @@ 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. -To do so we'll add this to both templates within the ``<div -class="main_content">`` div: +To do so we'll add this to both templates within the ``<div id="right" +class="app-welcome align-right">`` div: .. code-block:: xml - :linenos: <span tal:condition="logged_in"> <a href="${request.application_url}/logout">Logout</a> @@ -261,13 +271,11 @@ Our ``views.py`` module will look something like this when we're done: Our ``edit.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt - :linenos: :language: xml Our ``view.pt`` template will look something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt - :linenos: :language: xml Revisiting the Application @@ -279,5 +287,3 @@ of hitting an edit or add page and submitting the login form with the hand corner. When we click it, we're logged out, and redirected back to the front page. - - |
