From 5f375c7603c0e240a60b884bf0ef39352c25c879 Mon Sep 17 00:00:00 2001 From: Steve Piercy Date: Wed, 27 May 2015 02:44:38 -0700 Subject: - clean up and make consistent across both wikis authorization.rst - update templates and static assets to new theme --- docs/tutorials/wiki/authorization.rst | 370 ++++++++++---------- .../src/authorization/tutorial/static/favicon.ico | Bin 1406 -> 0 bytes .../src/authorization/tutorial/static/footerbg.png | Bin 333 -> 0 bytes .../src/authorization/tutorial/static/headerbg.png | Bin 203 -> 0 bytes .../wiki/src/authorization/tutorial/static/ie6.css | 8 - .../src/authorization/tutorial/static/middlebg.png | Bin 2797 -> 0 bytes .../src/authorization/tutorial/static/pylons.css | 372 --------------------- .../tutorial/static/pyramid-16x16.png | Bin 0 -> 1319 bytes .../tutorial/static/pyramid-small.png | Bin 7044 -> 0 bytes .../src/authorization/tutorial/static/pyramid.png | Bin 33055 -> 12901 bytes .../src/authorization/tutorial/static/theme.css | 154 +++++++++ .../authorization/tutorial/static/theme.min.css | 1 + .../authorization/tutorial/static/transparent.gif | Bin 49 -> 0 bytes .../src/authorization/tutorial/templates/edit.pt | 120 ++++--- .../src/authorization/tutorial/templates/login.pt | 118 ++++--- .../src/authorization/tutorial/templates/view.pt | 121 ++++--- docs/tutorials/wiki2/authorization.rst | 289 ++++++++-------- .../src/authorization/tutorial/templates/login.pt | 2 +- 18 files changed, 676 insertions(+), 879 deletions(-) delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/favicon.ico delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/footerbg.png delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/headerbg.png delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/ie6.css delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/middlebg.png delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/pylons.css create mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-16x16.png delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/pyramid-small.png create mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/theme.css create mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/theme.min.css delete mode 100644 docs/tutorials/wiki/src/authorization/tutorial/static/transparent.gif (limited to 'docs/tutorials') diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index 6c98b6f3a..161e251bc 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -1,19 +1,20 @@ +.. _wiki_adding_authorization: + ==================== -Adding Authorization +Adding authorization ==================== :app:`Pyramid` provides facilities for :term:`authentication` and -:term:`authorization`. We'll make use of both features to provide security -to our application. Our application currently allows anyone with access to -the server to view, edit, and add pages to our wiki. We'll change that -to allow only people who are members of a *group* named ``group:editors`` -to add and edit wiki pages but we'll continue allowing -anyone with access to the server to view pages. - -We will also add a login page and a logout link on all the -pages. The login page will be shown when a user is denied -access to any of the views that require a permission, instead of -a default "403 Forbidden" page. +::term:`authorization`. We'll make use of both features to provide security +:to our application. Our application currently allows anyone with access to +:the server to view, edit, and add pages to our wiki. We'll change that to +:allow only people who are members of a *group* named ``group:editors`` to add +:and edit wiki pages but we'll continue allowing anyone with access to the +:server to view pages. + +We will also add a login page and a logout link on all the pages. The login +page will be shown when a user is denied access to any of the views that +require permission, instead of a default "403 Forbidden" page. We will implement the access control with the following steps: @@ -28,12 +29,13 @@ Then we will add the login and logout feature: * Add ``login`` and ``logout`` views (``views.py``). * Add a login template (``login.pt``). -* Make the existing views return a ``logged_in`` flag to the renderer (``views.py``). +* Make the existing views return a ``logged_in`` flag to the renderer + (``views.py``). * Add a "Logout" link to be shown when logged in and viewing or editing a page (``view.pt``, ``edit.pt``). -Access Control +Access control -------------- Add users and groups @@ -49,11 +51,9 @@ following content: The ``groupfinder`` function accepts a userid and a request and returns one of these values: -- If the userid exists in the system, it 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, it will - return ``None``. +- If the userid exists in the system, it 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, it will return ``None``. For example, ``groupfinder('editor', request )`` returns ``['group:editor']``, ``groupfinder('viewer', request)`` returns ``[]``, and ``groupfinder('admin', @@ -61,9 +61,8 @@ request)`` returns ``None``. We will use ``groupfinder()`` as an :term:`authentication policy` "callback" that will provide the :term:`principal` or principals for a user. -In a production system, user and group -data will most often come from a database, but here we use "dummy" -data to represent user and groups sources. +In a production system, user and group data will most often come from a +database, but here we use "dummy" data to represent user and groups sources. Add an ACL ~~~~~~~~~~ @@ -81,44 +80,42 @@ Add the following lines to the ``Wiki`` class: .. literalinclude:: src/authorization/tutorial/models.py :lines: 9-13 :linenos: + :lineno-start: 9 :emphasize-lines: 4-5 :language: python -We import :data:`~pyramid.security.Allow`, an action that -means that permission is allowed, and -:data:`~pyramid.security.Everyone`, a special :term:`principal` -that is associated to all requests. Both are used in the +We import :data:`~pyramid.security.Allow`, an action that means that +permission is allowed, and :data:`~pyramid.security.Everyone`, a special +:term:`principal` that is associated to all requests. Both are used in the :term:`ACE` entries that make up the ACL. -The ACL is a list that needs to be named `__acl__` and be an -attribute of a class. We define an :term:`ACL` with two -:term:`ACE` entries: the first entry allows any user the `view` -permission, and the second entry allows the ``group:editors`` -principal the `edit` permission. +The ACL is a list that needs to be named `__acl__` and be an attribute of a +class. We define an :term:`ACL` with two :term:`ACE` entries: the first entry +allows any user the `view` permission. The second entry allows the +``group:editors`` principal the `edit` permission. -The ``Wiki`` class that contains the ACL is the :term:`resource` -constructor for the :term:`root` resource, which is -a ``Wiki`` instance. The ACL is -provided to each view in the :term:`context` of the request, as -the ``context`` attribute. +The ``Wiki`` class that contains the ACL is the :term:`resource` constructor +for the :term:`root` resource, which is a ``Wiki`` instance. The ACL is +provided to each view in the :term:`context` of the request as the ``context`` +attribute. It's only happenstance that we're assigning this ACL at class scope. An ACL can be attached to an object *instance* too; this is how "row level security" can be achieved in :app:`Pyramid` applications. We actually need only *one* ACL for the entire system, however, because our security requirements are -simple, so this feature is not demonstrated. See -:ref:`assigning_acls` for more information about what an -:term:`ACL` represents. +simple, so this feature is not demonstrated. See :ref:`assigning_acls` for +more information about what an :term:`ACL` represents. -Add Authentication and Authorization Policies +Add authentication and authorization policies ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Open ``tutorial/__init__.py`` and -add these import statements: +Open ``tutorial/tutorial/__init__.py`` and add the highlighted import +statements: .. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 4-5,8 + :lines: 1-8 :linenos: + :emphasize-lines: 4-5,8 :language: python Now add those policies to the configuration: @@ -126,15 +123,16 @@ Now add those policies to the configuration: .. literalinclude:: src/authorization/tutorial/__init__.py :lines: 18-23 :linenos: + :lineno-start: 18 :emphasize-lines: 1-3,5-6 :language: python -(Only the highlighted lines need to be added.) +Only the highlighted lines need to be added. -We are enabling an ``AuthTktAuthenticationPolicy``, it is based in an -auth ticket that may be included in the request, and an -``ACLAuthorizationPolicy`` that uses an ACL to determine the allow or deny -outcome for a view. +We are enabling an ``AuthTktAuthenticationPolicy``, which is based in an auth +ticket that may be included in the request. We are also enabling an +``ACLAuthorizationPolicy``, which uses an ACL to determine the *allow* or +*deny* outcome for a view. Note that the :class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor accepts two arguments: ``secret`` and ``callback``. ``secret`` is @@ -144,235 +142,231 @@ machinery represented by this policy: it is required. The ``callback`` is the Add permission declarations ~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Open ``tutorial/tutorial/views.py``. Add a ``permission='edit'`` parameter -to the ``@view_config`` decorator for ``add_page()`` and -``edit_page()``, for example: +Open ``tutorial/tutorial/views.py`` and add a ``permission='edit'`` parameter +to the ``@view_config`` decorators for ``add_page()`` and ``edit_page()``: -.. code-block:: python - :linenos: - :emphasize-lines: 3 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 50-52 + :emphasize-lines: 2-3 + :language: python - @view_config(name='add_page', context='.models.Wiki', - renderer='templates/edit.pt', - permission='edit') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 70-72 + :emphasize-lines: 2-3 + :language: python -(Only the highlighted line, along with its preceding comma, -needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. -The result is that only users who possess the ``edit`` -permission at the time of the request may invoke those two views. +The result is that only users who possess the ``edit`` permission at the time +of the request may invoke those two views. -Add a ``permission='view'`` parameter to the ``@view_config`` -decorator for ``view_wiki()`` and ``view_page()``, like this: +Add a ``permission='view'`` parameter to the ``@view_config`` decorator for +``view_wiki()`` and ``view_page()`` as follows: -.. code-block:: python - :linenos: - :emphasize-lines: 2 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 23-24 + :emphasize-lines: 1-2 + :language: python - @view_config(context='.models.Page', renderer='templates/view.pt', - permission='view') +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 28-29 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line, along with its preceding comma, -needs to be added.) +Only the highlighted lines, along with their preceding commas, need to be +edited and added. This allows anyone to invoke these two views. -We are done with the changes needed to control access. The -changes that follow will add the login and logout feature. +We are done with the changes needed to control access. The changes that +follow will add the login and logout feature. -Login, Logout +Login, logout ------------- -Add Login and Logout Views +Add login and logout views ~~~~~~~~~~~~~~~~~~~~~~~~~~ -We'll add a ``login`` view which renders a login form and processes -the post from the login form, checking credentials. +We'll add a ``login`` view which renders a login form and processes the post +from the login form, checking credentials. -We'll also add a ``logout`` view callable 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 also add a ``logout`` view callable 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. -Add the following import statements to the -head of ``tutorial/tutorial/views.py``: +Add the following import statements to the head of +``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py :lines: 6-17 - :linenos: - :emphasize-lines: 3,6-11 + :emphasize-lines: 1-12 :language: python -(Only the highlighted lines, with other necessary modifications, -need to be added.) +All the highlighted lines need to be added or edited. -:meth:`~pyramid.view.forbidden_view_config` will be used -to customize the default 403 Forbidden page. -:meth:`~pyramid.security.remember` and -:meth:`~pyramid.security.forget` help to create and -expire an auth ticket cookie. +:meth:`~pyramid.view.forbidden_view_config` will be used to customize the +default 403 Forbidden page. :meth:`~pyramid.security.remember` and +:meth:`~pyramid.security.forget` help to create and expire an auth ticket +cookie. -Now add the ``login`` and ``logout`` views: +Now add the ``login`` and ``logout`` views at the end of the file: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 82-120 + :lines: 82-116 :linenos: + :lineno-start: 82 :language: python ``login()`` has two decorators: -- a ``@view_config`` decorator which associates it with the - ``login`` route and makes it visible when we visit ``/login``, -- a ``@forbidden_view_config`` decorator which turns it into - a :term:`forbidden view`. ``login()`` will be invoked - when a user tries to execute a view callable for which they lack - authorization. For example, if a user has not logged in - and tries to add or edit a Wiki page, they will be shown the - login form before being allowed to continue. +- a ``@view_config`` decorator which associates it with the ``login`` route + and makes it visible when we visit ``/login``, +- a ``@forbidden_view_config`` decorator which turns it into a + :term:`forbidden view`. ``login()`` will be invoked when a user tries to + execute a view callable for which they lack authorization. For example, if + a user has not logged in and tries to add or edit a Wiki page, they will be + shown the login form before being allowed to continue. -The order of these two :term:`view configuration` decorators -is unimportant. +The order of these two :term:`view configuration` decorators is unimportant. -``logout()`` is decorated with a ``@view_config`` decorator -which associates it with the ``logout`` route. It will be -invoked when we visit ``/logout``. +``logout()`` is decorated with a ``@view_config`` decorator which associates +it with the ``logout`` route. It will be invoked when we visit ``/logout``. Add the ``login.pt`` Template ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Create ``tutorial/tutorial/templates/login.pt`` with the following -content: +Create ``tutorial/tutorial/templates/login.pt`` with the following content: .. literalinclude:: src/authorization/tutorial/templates/login.pt - :language: xml + :language: html -The above template is referred in the login view that we just added -in ``views.py``. +The above template is referenced in the login view that we just added in +``views.py``. -Return a logged_in flag to the renderer -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Return a ``logged_in`` flag to the renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -Add a ``logged_in`` parameter to the return value of -``view_page()``, ``edit_page()`` and ``add_page()``, -like this: +Open ``tutorial/tutorial/views.py`` again. Add a ``logged_in`` parameter to +the return value of ``view_page()``, ``edit_page()``, and ``add_page()`` as +follows: -.. code-block:: python - :linenos: - :emphasize-lines: 4 +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 47-48 + :emphasize-lines: 1-2 + :language: python - return dict(page = page, - content = content, - edit_url = edit_url, - logged_in = request.authenticated_userid) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 67-68 + :emphasize-lines: 1-2 + :language: python -(Only the highlighted line and a trailing comma on the preceding -line need to be added.) +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 75-77 + :emphasize-lines: 2-3 + :language: python + +Only the highlighted lines need to be added or edited. The :meth:`pyramid.request.Request.authenticated_userid` will be ``None`` if -the user is not authenticated, or a user id if the user is authenticated. +the user is not authenticated, or a userid if the user is authenticated. Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Open ``tutorial/tutorial/templates/edit.pt`` and -``tutorial/tutorial/templates/view.pt`` and add this within the -``