Mortiz, have you taken a look at django-guardian, it has been out as long as 
object level hooks have been implemented; I have been using it successfully 
since version 0.2 which is about 2 years now. 

Your need to add ‘object_permissions’ to a model is an incorrect approach in my 
opinion as it would require any old apps to undergo a schema migration. Your 
generic relations concerns might be valid however I would like to mention 
Django guardian does use generic FK but so does built in django auth – so I 
think this approach is just fine. 

In the end I would humbly suggest that rather then creating a competing 
solution you instead contribute your skills and suggestions to an already 
working project.

From: Moritz S. 
Sent: Friday, April 13, 2012 7:56 PM
To: django-developers@googlegroups.com 
Subject: Implementation of Object Permissions

Hi all, 

I have been using django for a while and became happy by the time I discovered 
the auth module that supports permission handling. But this module turned out 
to only be able to handle model based permissions. I could not imagine django 
of not having such a basic functionality (in my opinion) despite of having so 
much other great abilities. So I started to search for it but eventually 
figured out that the auth model's code was prepared for implementing this but 
it haven't been done yet.
So I decided to write a patch for this on my own.
Currently I'm writing this patch but there are several design decisions to make 
so I wanted to share this with you and hear your opinions.

First of all: I think the main problem of this implementation is to link the 
objects with the corresponding permissions. With model based permissions that's 
easy because you only have to store a permission once with the models 
ContentType and relate with a ManyToManyField to them and that's it. The 
problem with object based permissions is that every object needs to have his 
own set of permissions and you can't just use ForeignKeys or ManyToManyFields 
from a permission model because in the process of creating the permission model 
(and table) you don't know about the models that will provide object 
permissions therefore you can't refer to them.
So I tried some different implementations.

At first I tried to used dynamic models (e.g. this project makes use of them: 
http://pypi.python.org/pypi/django-object-permissions): The idea is to create 
intermediate models like 'MyModel_ObjectPermissions' that stores the object 
permissions with foreign keys to the model itself, user and group.
But this has a huge disadvantage: the use of dynamic models.
In fact thinking as database specialist that is the easiest way of connecting 
the model instances to the permissions but dynamic models are very sensitive 
and kind of hacky in my opinion and I think that does not match well with 
django's ideas.

Then I found out about GenericRelations from the contenttypes framework. So you 
could possibly use a single model called 'ObjectPermissions' or something and 
link users, permissions and instances of all types of models and only had to 
use one GenericRelation. This solution eliminates the problem wit the dynamic 
models because it doesn't even make use of them. But the GenericRelations have 
another not negligible disadvantage: The databases behind django don't have 
native support for them. I thought of huge django projects handling thousands 
and thousands of object permissions. I think these GenericRelations wouldn't be 
such scalable to make use of them.

The only solution for me was to find a way to link the (unknown) model 
instances to the permissions in the reversed direction. So not use ForeignKeys, 
etc. in the permission model to refer to the unknown model but to refer from 
the model to the permission itself. That would fix the problem of not knowing 
the models while creating the permission model. So in the end I thought of 
following:
- there is a new model in the auth module called 'ObjectPermission' this model 
has ManyToManyFields to User and Group and a ForeignKey to Permission
- instead of ObjectPermission referring to the model using object permissions, 
a field called 'object_permissions' is added to the corresponding models (by 
use of the class_prepared signal) (dynamically adding fields is way better than 
use completely dynamic models in my opinion)
- the object_permissions field is a ManyToManyField, that refers to 
ObjectPermission. In fact, a 'ManyToOneField' would be sufficient but django 
only has one to many fields (the ForeignKeyField) and we can't just use this in 
the reversed direction, as I mentioned above
This picture illustrates the relations:




Furthermore I thought of slightly modifying the auth module (apart from the 
ObjectPermission model) in the following way:
- when the auth app is initialized a function is registered to listen to the 
class_prepared signal. This function adds the object_permissions field to each 
model, that has the Meta.object_permissions set to True (for this to work, this 
meta attribute has to be set in django.db.models.options)
- the User model gets the methods grant_perm and revoke_perm that takes the 
permission and as optional argument the object in order to simplify the process 
of handling permissions
- in the ModelBackend the methods has_perm, etc. have to be modified to be able 
to handle function calls with given objects (obviously)

So that was the technical part.

Now I want you to give feedback if this implementation is viable and maybe 
sometimes may get into django.


Thanks,
Moritz
-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To view this discussion on the web visit 
https://groups.google.com/d/msg/django-developers/-/WbQ6EMVuxqkJ.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.


Daniel Sokolowski
Danols Web Engineering
http://webdesign.danols.com/
Kingston, ON K7L 1H3, Canada


Notice of Confidentiality:
The information transmitted is intended only for the person or entity to which 
it is addressed and may contain confidential and/or privileged material. Any 
review re-transmission dissemination or other use of or taking of any action in 
reliance upon this information by persons or entities other than the intended 
recipient is prohibited. If you received this in error please contact the 
sender immediately by return electronic transmission and then immediately 
delete this transmission including all attachments without copying distributing 
or disclosing same.

-- 
You received this message because you are subscribed to the Google Groups 
"Django developers" group.
To post to this group, send email to django-developers@googlegroups.com.
To unsubscribe from this group, send email to 
django-developers+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/django-developers?hl=en.

Reply via email to