Version 7 (modified by 18 years ago) ( diff ) | ,
---|
Introduction
The summary below is a very basic idea of where I want this to go. Over the next few days, as I explore the Django source code in more depth I will be expanding upon what is written here, and making changes.
What are Row Level Permissions?
An example of row level permissions would be: "User A has read-access to article 234" or "User D has read, write access to article 234".
Why do we need this?
An example of where this would be useful is a forum or message board. With the current permission system, a user is capable of editing all the posts or unable to edit any posts. After implementing a row level permission, it can be modified so a user is capable of editing only their own personal posts.
Planned Features
- Negative permissions, e.g. "User A can not modify article 2 and 4 but can modify all other articles"
- A modified admin page for editing objects that will allow admins to add users with specific (negative and positive) row level permissions to the object being edited
- A method of adding row level permissions using an API
- Allow custom permissions for row level permissions
- Developer can enable or, by default, disable the row level permissions on an object
- Generic functions to create row level permissions in certain scenarios, e.g. the above scenerio
Implementation
The priority of permissions will be modified to follow this order: User Row Level -> Group Row Level -> User Object Type -> Group Object Type. The reason for this change is to allow negative permissions, the permissions code should check in this order, stopping at the first positive permission or negative permission. These modifications will have to be made after discussing them with Joseph Kocherhans who is implementing GenericAuthorization and other members of the development team.
The actual database structure of the row level permissions system will use a single table and generic foreign keys. The generic foreign key will be modified slightly from the code written by Luke Plant in his tagging application (http://files.lukeplant.fastmail.fm/public/python/lp_tagging_app_0.1.zip). The changes will most likely consist of changing the primary keys to be integers rather then strings.
Timeline
Task | Status |
Row Level Permission object is implemented and tested | In progress |
Developer can choose to enable row level permissions | Not started |
API for modifying row level permissions is implemented and tested | Not started |
Admin interface is modified to editing of row level permissions | Not started |
Negative row level perms | Not started |
Generic Functions to create row level perms | Not started |
Deliverables
- Modified administration interface that will allow users to modify row level permissions
- API to allow developers to modify the row level permissions
- Ability of developer to enable or disable row level permissions
- Changes to the generated SQL that will create the row level permission table
- Tests for all the above
Contact
Please contact me (indirecthit at gmail.com) or modify this page with any comments you have on what I have written above.
Suggestions
From the discussion on Django-developers group. The italicized suggestions I have decided to use or not use, the other ones I am still considering/looking into.
- Using GenericForeignKey and one table instead of having a table for each object. Suggested by Ian Holsman. As an example see: http://files.lukeplant.fastmail.fm/public/python/lp_tagging_app_0.1.zip
- Implementing negativity. ie person X is NOT allowed to see row Y. Suggested by Ian Holsman. Suggested by Honza Král to allow something like "person X can read all articles except article Y". This would most likely require a rewrite of the order of permissions, therefore doing it from most specific (row level) to least specific (object type).
- From oggie rob:
- "An alternative approach for the group-level changes: a new permission type that allows you to assign a group that can access that object. i.e. permissionA = access for every user in groupA. Then every user that belongs to groupA can access objects created by any user in groupA. You would then, obviously, add the permission to groupA only"
- "How do you deal with those permissions in the generic and admin list views? You may need to change the returned lists to show only those things that the user has created? I'm not sure. I know it would be an issue in the admin pages but the generic lists might be used in various ways (and perhaps the option to choose would be nice)."
- From Ian Holsman: "while I use integer's as my keys (which is they default Django way), others override this and use strings and other weird things. I'm not sure how my previous suggestion would work when you take that kind of thing into account."
- Generic mechanism for creating row level permissions when enabled, such as the example of the forum given above. E,g. the developer would enable this feature, and from that point on a user would have row level permissions (specified by the developer) for any object they create. Suggested by Andy Shaw.
- From Andy Shaw: "would Luke's GenericForeignKey allow for inline editing, assuming it was to be adopted? Personally I'd much rather be able to alter a row's permissions on its own admin page than have to switch table."