Code


Version 8 (modified by jkocherhans, 8 years ago) (diff)

status change

Authorization

TOC(inline, GenericAuthorization)?

Current Status

has_permission has been implemented, and a set of tests for model-level permissions are complete. Unfortunately, subversion is all wacky and won't let me merge changes from the trunk. I don't have time to fight with it, so I'm just doing this as a patch against the trunk for now. The tests pass, but I haven't tested the admin system integration yet. Also, the registration api is subject to change and there's probably some debug code that needs to be ripped out. Consider yourself warned ;)

View Current Patch

Proposal

As part of Google's 2006 Summer of Code, Joseph Kocherhans will be implementing a more flexible authorization system for Django. The new system should allow for ACL's, role-based systems, and Django's current model-level permissions. peak.security will be used as a basic model, but things will be made more django-like where it makes sense.

Currently Django's authentication system is tied directly to the User model from django.contrib.auth. Also, there is no way to allow for row-level permissions. Authentication checks will be changed to use a new generic function:

has_permission(user, permission, object)

This function will delegate to other functions based on the type of user, permission and object that are passed to it. This will allow the use of different types of security rules depending on the type of object being accessed, as well as allowing for new user objects that don't need to fulfill the whole django.contrib.auth.models.User interface. You can even create rules that don't depend on the default permission table in the database.

Scope

The scope of this project is limited to providing the underlying support for making ACL's, etc possible, not actually implementing such policies. A policy that mimicks Django's model-level permission system will be included though.

Usage

Checking a permission

from django.contrib.auth import has_permission
if has_permission(user, permission, object):
    # do something

Adding new rules

Here's an example of the low level api for adding new security rules. In reality, this will probably happen under the covers via new Meta settings, but this will be discussed later, probably after the low level stuff has been implemented and tested.

from django.contrib.auth.models import User
from django.contrib.auth import has_permission

def default_has_permission(user, permission, object=None):
    return user.has_perm(permission)

has_permission.register(default_has_permission, User)

This is fairly close to what it would look like to implement django's current security policy. The object isn't really important in this case since Django's permissions are based on the Model you're accessing, not the actual object (See RowLevelPermissions for object-specific permissions.) We is we pass more than just User to the register method, we can register different security rules for different Models.

Implementation

has_permission will be implemented as a class with a register method and a __call__(self, user, permission, object) method.

This method is similar to Philip J. Eby's RuleDispatch and Guido van Rossum's recent work on generic/overloaded functions. See References for examples. The plan is to start out with a really naive and simple implementation, if it works and performs reasonably it should probably be left simple.

Roadmap

Task Status
Implement and test the has_permission generic function. Complete
Implement a function to mimic Django's current authorization. Complete
Update the admin system to use has_permission and test. Compete
Update other views/decorators to use has_permission and test. In Progress
Revise this page and integrate into core django docs. Not Started

References