diff options
| author | Chris McDonough <chrism@agendaless.com> | 2009-05-30 06:54:31 +0000 |
|---|---|---|
| committer | Chris McDonough <chrism@agendaless.com> | 2009-05-30 06:54:31 +0000 |
| commit | b0a3958409901788da67ad5bf9f8ff4e664c6516 (patch) | |
| tree | 4534d2d96b9444a4663c41b03f0f108cf0ed5335 /docs/tutorials/bfgwiki/authorization.rst | |
| parent | c92023b5bd630a91f2ae1dc8812349d920105343 (diff) | |
| download | pyramid-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.rst | 235 |
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 ---------------------------------------------------- |
