This is a pre-production deployment of Warehouse. Changes made here affect the production instance of PyPI (pypi.python.org).
Help us improve Python packaging - Donate today!

A pyramid authorization (not authentication) suite

Project Description

Warning

This package is still in the design/planning stage, so there is no code available yet. Check back soon.

The \(pyramid_authz\) Python package provides helper routines to make the authorization component of access control easier. Note that this package does NOT address authentication in any way (there are many other packages for that). Authentication is the process of determining who the request is coming from, authorization is the process of determining what that identity is allowed to do.

This package exposes a postgres-like approach to access control, which basically means that access control is broken down into “roles” and “privileges”.

In short:

  1. A \(Privilege\) is the permission to perform an action;
  2. A \(Role\) is a collection of privileges;
  3. Roles can inherit from other roles;
  4. Any database object can be made to be a role; and
  5. Access to a resource or action is always based on privileges, never on roles, i.e. your code should always ask “does this user have this privilege”, not “is this user a member of this role”.

For more information on postgres’ approach, please see http://www.postgresql.org/docs/9.0/static/user-manag.html.

Installation

$ pip install pyramid_authz

Usage

Require static privilege user.valid:

from pyramid_authz import privilege

# restrict the 'core' view to authenticated users
@view_config(route_name='core')
@privilege('user.valid')
def core(request):
  ...

Require dynamic privilege for path route /blog/{blog_id}/{page_id} which depends on which blog, which page, and what method is being requested:

from pyramid_authz import privilege, Method, PathParam

# restrict the 'blog.page' view to users that have the blog-
# and method-specific privilege
@view_config(route_name='blog.page')
def blog(request):
  blog_id = request.matchdict['blog_id']
  page_id = request.matchdict['page_id']

  priv = privilege(blog_id=blog_id, page_id=page_id, method=request.method)

  # check
  if not priv.allow(request):
    raise HTTPForbidden()

  # same as check, but also raises the exception all-in-one
  priv.require(request)

  # same, but raise 404 instead 401/403
  priv.require(request, failto=HTTPNotFound)

  ...

Same thing, but using the declarative helpers \(PathParam\) (which returns the specified request.matchdict[{PARAMNAME}] path component) and \(Method\) (which returns the value of request.method):

\(Method\) (
# same thing, but specified declaratively:

from pyramid_authz import privilege, PathParam, Method

@view_config(route_name='blog.page')
@privilege(
  blog_id = PathParam('blog_id'),
  page_id = PathParam('page_id'),
  method  = RequestMethod,
)
def blog(request):
  ...
Release History

Release History

This version
History Node

0.1.0

Supported By

WebFaction WebFaction Technical Writing Elastic Elastic Search Pingdom Pingdom Monitoring Dyn Dyn DNS Sentry Sentry Error Logging CloudAMQP CloudAMQP RabbitMQ Heroku Heroku PaaS Kabu Creative Kabu Creative UX & Design Fastly Fastly CDN DigiCert DigiCert EV Certificate Rackspace Rackspace Cloud Servers DreamHost DreamHost Log Hosting