More on repoze.urispace

I blogged yesterday about the fact that I had docs online for the repoze.urispace package, but didn't do much to motivate readers' interest: repoze.urispace should be interesting if you have an application which needs policies which vary based on "where" in the site the request is addressed. Examples might include: fine- grained security, theme selection, caching policies, etc.

Overview

People who develop with Zope have come to call such policies "placeful", and they make extensive use of them:

  • Users can be authenticated only within a certain section of the site (similar to having an .htpasswd file located within a static filesystem tree served by Apache).

  • Permissions can be granted to roles at any point in the containment graph, and can be "acquired" (inherited from the container).

  • Roles can be granted to particular users or groups can also be made at any "place". The traditional security policy for Zope2 sets such grants to be acquired by default; applications can override that behavior at the class level, or by registering a non-default security policy.

  • Arbitrary, application-defined policies can be stored as attributes on objects in the graph, and thus acquired. See the Acquisition docs for details.

Even outside Zope, policies often need to depend on the "location" of the request:

  • As noted above, "placeful" authentication has long been possible with other technologies. Frameworks which do URL dispatch to find the "controller" application (e.g., Pylons/Routes, Django), can have different authentication sources for different controllers.

  • Changing the "theme" applied to a page based on the section it is served from is a frequently-implemented feature.

Integration via repoze.urispace

The repoze.urispace package attempts to make writing applications with "placeful" requirments simpler, by moving the knowledge of how policies are assigned to locations out of the application and into a centralized, declarative store, implemented in terms of the URISpace specification.

After integrating repoze.urispace, applications can apply policies on the basis of keys added to the request environment, without needing to maintain any supporting state within the application.

Such a factoring gets even more interesting when multiple applications need to keep track of "place": keeping the policy settings in a centralized store makes it easier to keep them all in sync when changes are made to the URL structure of the site.

Example: Selecting Themes Based on Place

The "Deliverance package", http://www.openplans.org/projects/deliverance/introduction makes it possible to separate out the "theming" of a web application from the implementation of its core logic. For simple sites, where all pages share the same general page structure and theme, Deliverance make changing the theme trivial, without needing to make corresponding changes to the application (assuming that the new theme keeps the same expectations as the old).

Many sites, however, need to vary the theme based on place: the sports section of a news site, for instance, may have different layout, styles, or page structure from the business section. The repoze.dvselect package provides WSGI middleware which uses repoze.urispace to manage these requirements.

Deliverance uses two artifacts, a theme page and a ruleset, to map the "application" page onto the theme. Both of those artifacts are addressed via URLs. 'repoze.dvselect' allows either or both of those URLs to vary based on place. A sample XML file for such a configuration might look like:

/static/themes/default.html

/static/rules/default.xml

 /static/themes/news.html

  /static/themes/news.html?style=world

  /static/themes/news.html?style=national

  /static/themes/news.html?style=local

 /static/themes/lifestyle.html

 /static/themes/sports.html

 /static/rules/story.xml

 /static/rules/index.xml

This URISpace file ships with example content for such a site in the docs for repoze.dvselect.

Example: Authorizing Access And Setting Application Policy

When running your own DNS server for domains you control, it is often helpful to keep a name entry for a host whose IP address changes dynamically (e.g., a home network behind a cable modem or DSL line). Updating the DNS entry for that host needs to be as simple and as secure as possible.

The repoze.dyndns application demonstrates an implementation of this application using URISpace. In particular, the URISpace configuration keeps information about two distinct policies, based on place:

  • Who is allowed to update the entry? (authorization)

  • What zone is being updated?

Note that repoze.dyndns does not do placeful identification / authentication of the request user: it expects that another piece of middleware (typically repoze.who) has performed that task.

The example configuration shipped with the docs for repoze.dyndns tracks access and zones for two different URL paths within the site:

admin

 domain1
 user

 domain2
 another

Note that the admin user is defined in the root, and thus can update any of the domains, but that user can update only domain1, while another can update only domain2.

Following Up

I'd really like to hear about other use cases where you might be able to take advantage of URISpace in your applications. You can reach me at 'tseaver atsign palladion dot com', as well as find me as 'TresEquis' on

irc://irc.freenode.net/#repoze