Is also very very nice. Basically, it consists of 2 layers – the permissions and groups. A permission is the most basic unit. A group is a collection of permissions (just like a role in DrProject right now). A user can have permissions or groups in their profile. This is all good, but there is one problem.
The problem is that each permission is tied to an application. In Pyrtl, we’ll want to have a more fine-grained access control. We want users to have possibly different permissions in different projects. One idea that I have is to use ${permission_name}_${project_name} to handle that. Basically, we’ll have a base set of groups and permissions. When a new project is created, Pyrtl will create the corresponding groups and permissions with the above schema. Then, it’s easy to add a role to the user for that project — we’ll simply assign a group ${group_name}_${project_name}, which will contain permissions from the base with the above schema.
There is two ways that I know of to create custom permissions in Django. The first way is to add a new model inside models.py as explained here. But we’ll want to do this dynamically. Here is a code snippet:
from django.contrib.auth.models import User, Permission, Group from <project_name>.<app_name> import models as app from django.contrib.contenttypes.models import ContentType # get the application name from the module appname = app.__name__.lower().split('.')[-2] # get a ContentType of the application ct, created = ContentType.objects.get_or_create(model='', app_label=appname, defaults={'name': appname}) # create a new permission for this application with codename 'foo' and human readable name 'foo permission' p, created = Permission.objects.get_or_create(codename='foo', content_type__pk=ct.id, defaults={'name': 'foo permission', 'content_type': ct}) p.save() # create a new group g = Group(name='bar') g.save() # add a permission to the group g.permissions.add(p) g.save() # create a user and add a group to the user user = User.objects.create_user('Kosta', 'kosta@foo.com', '123') user.groups.add(g) user.save()
Let’s go through it step by step.
from django.contrib.auth.models import User, Permission, Group from <project_name>.<app_name> import models as app from django.contrib.contenttypes.models import ContentType
We import the model module and give it alias ‘app’. This will be necessary to get a reference to the ContentType object that stores this module. When we create a new permission dynamically, we must pass it this object so it knows which application it’s tied with.
# get a ContentType of the application ct, created = ContentType.objects.get_or_create(model='', app_label=appname, defaults={'name': appname})
Here, we get a reference to the ContentType object that references our application.
# create a new permission for this application with codename 'foo' and human readable name 'foo permission' p, created = Permission.objects.get_or_create(codename='foo', content_type__pk=ct.id, defaults={'name': 'foo permission', 'content_type': ct}) p.save()
Now, we create a new permission object and save it to the database. We must give it a name, which I called ‘foo’ and a human readable name, which I gave ‘foo permission’. We must also pass it the ContentType object that references the application.
# create a new group g = Group(name='bar') g.save() # add a permission to the group g.permissions.add(p) g.save()
Here, we create a new group, save it so we have a public key, and add a permission to the group.
# create a user and add a group to the user user = User.objects.create_user('kosta', 'kosta@foobar.com', '123') user.groups.add(g) user.save()
Now, we create a new user (we could also query a user based on the session, but for demo purposes I’ll just create a new one), and add a group to my profile.
This is going to work, but it’s just an idea that I have. To check if the user has a permission, we just do:
user.has_perm('<app_name>.foo')
And this returns True. So, in the controller we could use reflection to check if the user has a permission in the project that’s based on the base permission.