Skip to main content

A pyramid authorization (not authentication) suite

Project description

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.

Project

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):
  ...

Project details


Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page