diff options
| author | Chris McDonough <chrism@plope.com> | 2012-04-08 17:07:28 -0400 |
|---|---|---|
| committer | Chris McDonough <chrism@plope.com> | 2012-04-08 17:07:28 -0400 |
| commit | 5ceefa60dc548d95f5a96a2a149c3ad52bedf87c (patch) | |
| tree | 82299bed8dd3a404474ef8d07aaaf670e05870b4 /docs/tutorials/wiki | |
| parent | d806f9babf869d1eaf0ec19fb6d0b3a14c5ae92d (diff) | |
| parent | 35870f66ea9ea0a7264175cf2e434d2193a7c22c (diff) | |
| download | pyramid-5ceefa60dc548d95f5a96a2a149c3ad52bedf87c.tar.gz pyramid-5ceefa60dc548d95f5a96a2a149c3ad52bedf87c.tar.bz2 pyramid-5ceefa60dc548d95f5a96a2a149c3ad52bedf87c.zip | |
Merge branch 'master' of github.com:Pylons/pyramid
Diffstat (limited to 'docs/tutorials/wiki')
| -rw-r--r-- | docs/tutorials/wiki/authorization.rst | 481 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/authorization/tutorial/models.py | 6 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/authorization/tutorial/views.py | 22 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/tests/tutorial/models.py | 6 | ||||
| -rw-r--r-- | docs/tutorials/wiki/src/tests/tutorial/views.py | 22 |
5 files changed, 308 insertions, 229 deletions
diff --git a/docs/tutorials/wiki/authorization.rst b/docs/tutorials/wiki/authorization.rst index e599e7086..9e0bf0f09 100644 --- a/docs/tutorials/wiki/authorization.rst +++ b/docs/tutorials/wiki/authorization.rst @@ -2,121 +2,186 @@ Adding Authorization ==================== -Our application currently allows anyone with access to the server to view, -edit, and add pages to our wiki. For purposes of demonstration we'll change -our application to allow 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. :app:`Pyramid` provides -facilities for :term:`authorization` and :term:`authentication`. We'll make -use of both features to provide security to our application. - -We will add an :term:`authentication policy` and an -:term:`authorization policy` to our :term:`application -registry`, add a ``security.py`` module and give our :term:`root` -resource an :term:`ACL`. - -Then we will add ``login`` and ``logout`` views, and modify the -existing views to make them return a ``logged_in`` flag to the -renderer and add :term:`permission` declarations to their ``view_config`` -decorators. - -Finally, we will add a ``login.pt`` template and change the existing -``view.pt`` and ``edit.pt`` to show a "Logout" link when not logged in. - -The source code for this tutorial stage can be browsed via +: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. + +We will implement the access control with the following steps: + +* Add users and groups (``security.py``, a new module). +* Add an :term:`ACL` (``models.py``). +* Add an :term:`authentication policy` and an :term:`authorization policy` + (``__init__.py``). +* Add :term:`permission` declarations to the ``edit_page`` and ``add_page`` + views (``views.py``). + +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``). +* Add a "Logout" link to be shown when logged in and viewing or editing a page + (``view.pt``, ``edit.pt``). + +The source code for this tutorial stage can be browsed at `http://github.com/Pylons/pyramid/tree/1.3-branch/docs/tutorials/wiki/src/authorization/ <http://github.com/Pylons/pyramid/tree/1.3-branch/docs/tutorials/wiki/src/authorization/>`_. -Add Authentication and Authorization Policies -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Access Control +-------------- -We'll change our package's ``__init__.py`` file to enable an -``AuthTktAuthenticationPolicy`` and an ``ACLAuthorizationPolicy`` to enable -declarative security checking. We need to import the new policies: +Add users and groups +~~~~~~~~~~~~~~~~~~~~ -.. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 4-5,8 +Create a new ``tutorial/tutorial/security.py`` module with the +following content: + +.. literalinclude:: src/authorization/tutorial/security.py :linenos: :language: python -Then, we'll add those policies to the configuration: +The ``groupfinder`` function accepts a userid and a request and +returns one of these values: -.. literalinclude:: src/authorization/tutorial/__init__.py - :lines: 17-22 +- 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', 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. + +Add an ACL +~~~~~~~~~~ + +Open ``tutorial/tutorial/models.py`` and add the following import +statement at the head: + +.. literalinclude:: src/authorization/tutorial/models.py + :lines: 4-7 :linenos: :language: python -Note that the creation of an ``AuthTktAuthenticationPolicy`` requires two -arguments: ``secret`` and ``callback``. ``secret`` is a string representing -an encryption key used by the "authentication ticket" machinery represented -by this policy: it is required. The ``callback`` is a reference to a -``groupfinder`` function in the ``tutorial`` package's ``security.py`` file. -We haven't added that module yet, but we're about to. +Add the following lines to the ``Wiki`` class: + +.. literalinclude:: src/authorization/tutorial/models.py + :lines: 9-13 + :linenos: + :emphasize-lines: 4-5 + :language: python -When you're done, your ``__init__.py`` will -look like so: +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. 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. + +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 only need *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. + +Add Authentication and Authorization Policies +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Open ``tutorial/__init__.py`` and +add these import statements: .. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 4-5,8 :linenos: :language: python -Add ``security.py`` -~~~~~~~~~~~~~~~~~~~ - -Add a ``security.py`` module within your package (in the same -directory as ``__init__.py``, ``views.py``, etc.) with the following -content: +Now add those policies to the configuration: -.. literalinclude:: src/authorization/tutorial/security.py +.. literalinclude:: src/authorization/tutorial/__init__.py + :lines: 17-22 :linenos: + :emphasize-lines: 1-3,5-6 :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 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 callback will return -``None``. 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. Note that the ``editor`` user is a member of the ``group:editors`` -group in our dummy group data (the ``GROUPS`` data structure). - -Give Our Root Resource an ACL -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(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 need to give our root resource object an :term:`ACL`. This ACL will be -sufficient to provide enough information to the :app:`Pyramid` security -machinery to challenge a user who doesn't have appropriate credentials when -he attempts to invoke the ``add_page`` or ``edit_page`` views. +Note that the +:class:`pyramid.authentication.AuthTktAuthenticationPolicy` constructor +accepts two arguments: ``secret`` and ``callback``. ``secret`` is a string +representing an encryption key used by the "authentication ticket" machinery +represented by this policy: it is required. The ``callback`` is the +``groupfinder()`` function that we created before. -We need to perform some imports at module scope in our ``models.py`` file: +Add permission declarations +~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add a ``permission='edit'`` parameter to the ``@view_config`` +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.) - from pyramid.security import Allow - from pyramid.security import Everyone +The result is that only users who possess the ``edit`` +permission at the time of the request may invoke those two views. -Our root resource object is a ``Wiki`` instance. We'll add the following -line at class scope to our ``Wiki`` class: +Add a ``permission='view'`` parameter to the ``@view_config`` +decorator for ``view_wiki()`` and ``view_page()``, like this: .. code-block:: python :linenos: + :emphasize-lines: 2 - __acl__ = [ (Allow, Everyone, 'view'), - (Allow, 'group:editors', 'edit') ] + @view_config(route_name='view_page', renderer='templates/view.pt', + permission='view') -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 only need *one* -ACL for the entire system, however, because our security requirements are -simple, so this feature is not demonstrated. +(Only the highlighted line needs to be added.) -Our resulting ``models.py`` file will now look like so: +This allows anyone to invoke these two views. -.. literalinclude:: src/authorization/tutorial/models.py - :linenos: - :language: python +We are done with the changes needed to control access. The +changes that follow will add the login and logout feature. + +Login, Logout +------------- Add Login and Logout Views ~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -124,124 +189,103 @@ 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 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 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 add these views to the existing ``views.py`` file we have in our -project. Here's what the ``login`` view callable will look like: +Add the following import statements to the +head of ``tutorial/tutorial/views.py``: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 86-113 + :lines: 6-13,15-17 :linenos: + :emphasize-lines: 3,6-9,11 :language: python -Here's what the ``logout`` view callable will look like: +(Only the highlighted lines need to be added.) + +: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: .. literalinclude:: src/authorization/tutorial/views.py - :lines: 115-119 + :lines: 87-120 :linenos: :language: python -Note that the ``login`` view callable has *two* view configuration -decorators. The order of these decorators is unimportant. Each just adds a -different :term:`view configuration` for the ``login`` view callable. - -The first view configuration decorator configures the ``login`` view callable -so it will be invoked when someone visits ``/login`` (when the context is a -Wiki and the view name is ``login``). The second decorator, named -``forbidden_view_config`` specifies a :term:`forbidden view`. This -configures our login view to be presented to the user when :app:`Pyramid` -detects that a view invocation can not be authorized. Because we've -configured a forbidden view, the ``login`` view callable will be invoked -whenever one of our users tries to execute a view callable that they are not -allowed to invoke as determined by the :term:`authorization policy` in use. -In our application, for example, this means that if a user has not logged in, -and he tries to add or edit a Wiki page, he will be shown the login form. -Before being allowed to continue on to the add or edit form, he will have to -provide credentials that give him permission to add or edit via this login -form. - -Note that we're relying on some additional imports within the bodies of these -views (e.g. ``remember`` and ``forget``). We'll see a rendering of the -entire views.py file a little later here to show you where those come from. - -Change Existing Views -~~~~~~~~~~~~~~~~~~~~~ - -In order to indicate whether the current user is logged in, we need to change -each of our ``view_page``, ``edit_page`` and ``add_page`` views in -``views.py`` to pass a "logged in" parameter into its template. We'll add -something like this to each view body: +``login()`` is decorated with two decorators: -.. code-block:: python +- 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 + an :term:`forbidden view`. ``login()`` will be invoked + when a users tries to execute a view callable that + they are not allowed to. For example, if a user has not logged in + and tries to add or edit a Wiki page, he will be shown the + login form before being allowed to continue on. + +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``. + +Add the ``login.pt`` Template +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Create ``tutorial/tutorial/templates/login.pt`` with the following +content: + +.. literalinclude:: src/authorization/tutorial/templates/login.pt + :language: xml + +The above template is referred to within the login view we just +added to ``views.py``. + +Return a logged_in flag to the renderer +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Add the following line to the import at the head of +``tutorial/tutorial/views.py``: + +.. literalinclude:: src/authorization/tutorial/views.py + :lines: 11-15 :linenos: + :emphasize-lines: 4 + :language: python - from pyramid.security import authenticated_userid - logged_in = authenticated_userid(request) +(Only the highlighted line needs to be added.) -We'll then change the return value of each view that has an associated -``renderer`` to pass the resulting ``logged_in`` value to the -template. For example: +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: 4 - return dict(page = context, + return dict(page = page, content = content, - logged_in = logged_in, - edit_url = edit_url) - -Add ``permission`` Declarations to our ``view_config`` Decorators -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -To protect each of our views with a particular permission, we need to pass a -``permission`` argument to each of our :class:`pyramid.view.view_config` -decorators. To do so, within ``views.py``: - -- We add ``permission='view'`` to the decorator attached to the - ``view_wiki`` and ``view_page`` view functions. This makes the - assertion that only users who possess the ``view`` permission - against the context resource at the time of the request may - invoke these views. We've granted - :data:`pyramid.security.Everyone` the view permission at the - root model via its ACL, so everyone will be able to invoke the - ``view_wiki`` and ``view_page`` views. - -- We add ``permission='edit'`` to the decorator attached to the - ``add_page`` and ``edit_page`` view functions. This makes the - assertion that only users who possess the effective ``edit`` - permission against the context resource at the time of the - request may invoke these views. We've granted the - ``group:editors`` principal the ``edit`` permission at the - root model via its ACL, so only a user whom is a member of - the group named ``group:editors`` will able to invoke the - ``add_page`` or ``edit_page`` views. We've likewise given - the ``editor`` user membership to this group via the - ``security.py`` file by mapping him to the ``group:editors`` - group in the ``GROUPS`` data structure (``GROUPS - = {'editor':['group:editors']}``); the ``groupfinder`` - function consults the ``GROUPS`` data structure. This means - that the ``editor`` user can add and edit pages. + edit_url = edit_url, + logged_in = authenticated_userid(request)) -Add the ``login.pt`` Template -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ - -Add a ``login.pt`` template to your templates directory. It's -referred to within the login view we just added to ``views.py``. +(Only the highlighted line needs to be added.) -.. literalinclude:: src/authorization/tutorial/templates/login.pt - :language: xml +:meth:`~pyramid.security.authenticated_userid()` will return None +if the user is not authenticated, or some user id it the user +is authenticated. -Change ``view.pt`` and ``edit.pt`` +Add a "Logout" link when logged in ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -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 id="right" -class="app-welcome align-right">`` div: +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: .. code-block:: xml @@ -249,57 +293,96 @@ class="app-welcome align-right">`` div: <a href="${request.application_url}/logout">Logout</a> </span> -See 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 ``tutorial/tutorial/__init__.py`` will look something like this +when we're done: + +.. literalinclude:: src/authorization/tutorial/__init__.py + :linenos: + :emphasize-lines: 4-5,8,17-19,21-22 + :language: python + +(Only the highlighted lines need to be added.) + +Our ``tutorial/tutorial/models.py`` will look something like this +when we're done: + +.. literalinclude:: src/authorization/tutorial/models.py + :linenos: + :emphasize-lines: 4-7,12-13 + :language: python -Our ``views.py`` module will look something like this when we're done: +(Only the highlighted lines need to be added.) + +Our ``tutorial/tutorial/views.py`` will look something like this +when we're done: .. literalinclude:: src/authorization/tutorial/views.py :linenos: + :emphasize-lines: 8,11-15,17,24,29,48,52,68,72,80,82-120 :language: python -Our ``edit.pt`` template will look something like this when we're done: +(Only the highlighted lines need to be added.) + +Our ``tutorial/tutorial/templates/edit.pt`` template will look +something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/edit.pt :linenos: + :emphasize-lines: 41-43 :language: xml -Our ``view.pt`` template will look something like this when we're done: +(Only the highlighted lines need to be added.) + +Our ``tutorial/tutorial/templates/view.pt`` template will look +something like this when we're done: .. literalinclude:: src/authorization/tutorial/templates/view.pt :linenos: + :emphasize-lines: 41-43 :language: xml -View the Application in a Browser -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +(Only the highlighted lines need to be added.) -We can finally examine our application in a browser. The views we'll try are -as follows: +Viewing the Application in a Browser +------------------------------------ -- Visiting ``http://localhost:6543/`` in a browser invokes the ``view_wiki`` - view. This always redirects to the ``view_page`` view of the ``FrontPage`` - page resource. It is executable by any user. +We can finally examine our application in a browser (See +:ref:`wiki-start-the-application`). Launch a browser and visit +each of the following URLs, check that the result is as expected: -- Visiting ``http://localhost:6543/FrontPage/`` in a browser invokes the - ``view_page`` view of the ``FrontPage`` Page resource. This is because +- ``http://localhost:6543/`` invokes the + ``view_wiki`` view. This always redirects to the ``view_page`` view + of the ``FrontPage`` Page resource. It is executable by any user. + +- ``http://localhost:6543/FrontPage`` invokes + the ``view_page`` view of the ``FrontPage`` Page resource. This is because it's the :term:`default view` (a view without a ``name``) for ``Page`` resources. It is executable by any user. -- Visiting ``http://localhost:6543/FrontPage/edit_page`` in a browser invokes - the edit view for the ``FrontPage`` Page resource. It is executable by - only the ``editor`` user. If a different user (or the anonymous user) - invokes it, a login form will be displayed. Supplying the credentials with - the username ``editor``, password ``editor`` will show the edit page form - being displayed. +- ``http://localhost:6543/FrontPage/edit_page`` + invokes the edit view for the FrontPage object. It is executable by + only the ``editor`` user. If a different user (or the anonymous + user) invokes it, a login form will be displayed. Supplying the + credentials with the username ``editor``, password ``editor`` will + display the edit page form. -- Visiting ``http://localhost:6543/add_page/SomePageName`` in a - browser invokes the add view for a page. It is executable by only +- ``http://localhost:6543/add_page/SomePageName`` + invokes the add view for a page. It is executable by only the ``editor`` user. If a different user (or the anonymous user) invokes it, a login form will be displayed. Supplying the credentials with the username ``editor``, password ``editor`` will - show the edit page form being displayed. + display the edit page form. -- After logging in (as a result of hitting an edit or add page and - submitting the login form with the ``editor`` credentials), we'll see - a Logout link in the upper right hand corner. When we click it, - we're logged out, and redirected back to the front page. +- After logging in (as a result of hitting an edit or add page + and submitting the login form with the ``editor`` + credentials), we'll see a Logout link in the upper right hand + corner. When we click it, we're logged out, and redirected + back to the front page. diff --git a/docs/tutorials/wiki/src/authorization/tutorial/models.py b/docs/tutorials/wiki/src/authorization/tutorial/models.py index 0a31c38be..582ff0d7e 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/models.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/models.py @@ -1,8 +1,10 @@ from persistent import Persistent from persistent.mapping import PersistentMapping -from pyramid.security import Allow -from pyramid.security import Everyone +from pyramid.security import ( + Allow, + Everyone, + ) class Wiki(PersistentMapping): __name__ = None diff --git a/docs/tutorials/wiki/src/authorization/tutorial/views.py b/docs/tutorials/wiki/src/authorization/tutorial/views.py index fcbe6fe25..21f12b31d 100644 --- a/docs/tutorials/wiki/src/authorization/tutorial/views.py +++ b/docs/tutorials/wiki/src/authorization/tutorial/views.py @@ -9,9 +9,9 @@ from pyramid.view import ( ) from pyramid.security import ( - authenticated_userid, remember, forget, + authenticated_userid, ) from .security import USERS @@ -20,12 +20,13 @@ from .models import Page # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") -@view_config(context='.models.Wiki', permission='view') +@view_config(context='.models.Wiki', + permission='view') def view_wiki(context, request): return HTTPFound(location=request.resource_url(context, 'FrontPage')) -@view_config(context='.models.Page', - renderer='templates/view.pt', permission='view') +@view_config(context='.models.Page', renderer='templates/view.pt', + permission='view') def view_page(context, request): wiki = context.__parent__ @@ -43,10 +44,8 @@ def view_page(context, request): content = wikiwords.sub(check, content) edit_url = request.resource_url(context, 'edit_page') - logged_in = authenticated_userid(request) - return dict(page = context, content = content, edit_url = edit_url, - logged_in = logged_in) + logged_in = authenticated_userid(request)) @view_config(name='add_page', context='.models.Wiki', renderer='templates/edit.pt', @@ -65,9 +64,8 @@ def add_page(context, request): page.__name__ = name page.__parent__ = context - logged_in = authenticated_userid(request) - - return dict(page = page, save_url = save_url, logged_in = logged_in) + return dict(page = page, save_url = save_url, + logged_in = authenticated_userid(request)) @view_config(name='edit_page', context='.models.Page', renderer='templates/edit.pt', @@ -77,11 +75,9 @@ def edit_page(context, request): context.data = request.params['body'] return HTTPFound(location = request.resource_url(context)) - logged_in = authenticated_userid(request) - return dict(page = context, save_url = request.resource_url(context, 'edit_page'), - logged_in = logged_in) + logged_in = authenticated_userid(request)) @view_config(context='.models.Wiki', name='login', renderer='templates/login.pt') diff --git a/docs/tutorials/wiki/src/tests/tutorial/models.py b/docs/tutorials/wiki/src/tests/tutorial/models.py index 0a31c38be..582ff0d7e 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/models.py +++ b/docs/tutorials/wiki/src/tests/tutorial/models.py @@ -1,8 +1,10 @@ from persistent import Persistent from persistent.mapping import PersistentMapping -from pyramid.security import Allow -from pyramid.security import Everyone +from pyramid.security import ( + Allow, + Everyone, + ) class Wiki(PersistentMapping): __name__ = None diff --git a/docs/tutorials/wiki/src/tests/tutorial/views.py b/docs/tutorials/wiki/src/tests/tutorial/views.py index fcbe6fe25..21f12b31d 100644 --- a/docs/tutorials/wiki/src/tests/tutorial/views.py +++ b/docs/tutorials/wiki/src/tests/tutorial/views.py @@ -9,9 +9,9 @@ from pyramid.view import ( ) from pyramid.security import ( - authenticated_userid, remember, forget, + authenticated_userid, ) from .security import USERS @@ -20,12 +20,13 @@ from .models import Page # regular expression used to find WikiWords wikiwords = re.compile(r"\b([A-Z]\w+[A-Z]+\w+)") -@view_config(context='.models.Wiki', permission='view') +@view_config(context='.models.Wiki', + permission='view') def view_wiki(context, request): return HTTPFound(location=request.resource_url(context, 'FrontPage')) -@view_config(context='.models.Page', - renderer='templates/view.pt', permission='view') +@view_config(context='.models.Page', renderer='templates/view.pt', + permission='view') def view_page(context, request): wiki = context.__parent__ @@ -43,10 +44,8 @@ def view_page(context, request): content = wikiwords.sub(check, content) edit_url = request.resource_url(context, 'edit_page') - logged_in = authenticated_userid(request) - return dict(page = context, content = content, edit_url = edit_url, - logged_in = logged_in) + logged_in = authenticated_userid(request)) @view_config(name='add_page', context='.models.Wiki', renderer='templates/edit.pt', @@ -65,9 +64,8 @@ def add_page(context, request): page.__name__ = name page.__parent__ = context - logged_in = authenticated_userid(request) - - return dict(page = page, save_url = save_url, logged_in = logged_in) + return dict(page = page, save_url = save_url, + logged_in = authenticated_userid(request)) @view_config(name='edit_page', context='.models.Page', renderer='templates/edit.pt', @@ -77,11 +75,9 @@ def edit_page(context, request): context.data = request.params['body'] return HTTPFound(location = request.resource_url(context)) - logged_in = authenticated_userid(request) - return dict(page = context, save_url = request.resource_url(context, 'edit_page'), - logged_in = logged_in) + logged_in = authenticated_userid(request)) @view_config(context='.models.Wiki', name='login', renderer='templates/login.pt') |
