Code


Version 4 (modified by indirecthit@…, 8 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.

Implementation

The priority of permissions would work: User/Group Object Type Permissions -> User/Group Row Level Permission. Meaning it would check each of those permissions in order to determine if the user has the correct permissions to do the activity they wish to do.

The method I am considering would use a seperate table to contain the row level permissions. Within that table would be the object id, user/group id, permissions (e.g. read, write, delete, etc.). There will most likely be a seperate table for each object type.

A reason for doing it this way, is that it allows a many-to-many relationship between instances of objects and users/groups. Therefore, one or more users/groups can have different permissions on the same object. Another reason, is that it will not affect the current columns within the object's table.

By default, these permissions will be disabled, but the developer will be able to enable the row level permissions using the meta attribute for each type of object.

The row level permissions will allow custom permissions.

The row level permissions can be modified using an API or by the administration interface.

Another possible method of doing this would be a similiar method to the current unix permissions. This method is not as flexible as the above method, and will most likely modify the object's table directly which might cause problems.

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 ongoing discussion on django-developers group. I'm researching some of the suggestions to determine the best route, as I do this I'll make changes above.

  • 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."