Skip to content Skip to sidebar Skip to footer

Django Permissions For Different Clients

I'm working on a Django project which will take on firms as clients and each client will be allowed to create multiple users. These users can then be assigned different permissions

Solution 1:

I really don't like your solution - it is similar to old database designs where schema chnges were expected by design !!! Please, whatever the cost DON'T do it. Forgetting about django, 40 years of database design has tought us that the schema of the database should never change (unless of course the requirements change or your design was not correct). I could provide an answer similar to this: RegEx match open tags except XHTML self-contained tags to emphasize how important is to not change your database schema.

So, you will have a django app which houses the user model as you say and a CustomPermission model which will give an interface to the admininstrator so that he will add permissions for eah client (the administrator will add the permissions for the client, not the developer). Each CustomPermission will just have a name and a ForeignKey to the client it applies.

Now you can create a UserCustomPermission model which will have a ForeignKey to the User and another ForeignKey to the CustomPermission (actually there is a many-to-many relation between User and CustomPermission.

Now, what you need to implement is how the permissions you assign will be assigned to actual allowed and forbidded actions. You don't say anything about this in your question. Just to give you a direction, I really like (and use all the time) the django-rules-light application (https://github.com/yourlabs/django-rules-light) which can be used to define your business rules.

Probably my answer doesn't actually solve your problem, or maybe I didn't understand something, but I believe that you will get a starting point -- also feel free to update your question and I'll update my answer accordingly.

Answer to the update

As you can understand, I don't like 1 and 3: For every new client you will need to create a new database ? Why not put all your client streams in the same table and use a foreign key to the client they belong to ?

(HERE BE DRAGONS)

I thought a nice solution - I wouldn't do it, but if want so much to put your users and their permissions in different databases then you can use the seperate sub-domain in your advance: Use database routing (https://docs.djangoproject.com/en/1.3/topics/db/multi-db/#database-routers) to select each client's database depending on the sub-domain. So, you will define all your client's databases in your settings.py:

DATABASES = {
    'default': {
        'NAME': 'app_data',
        'ENGINE': 'django.db.backends.postgresql_psycopg2',
        'USER': 'postgres_user',
        'PASSWORD': 's3krit'
    },
    'client1': {
        'NAME': 'client2',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'client2',
        'PASSWORD': 'priv4te'
    },
    'client2': {
        'NAME': 'client1',
        'ENGINE': 'django.db.backends.mysql',
        'USER': 'client1',
        'PASSWORD': 'priv4te'
    }
}

And then you will create a SubDomainDatabaseRouter class that will use the correct database depending on your sub-domain. Because the request settings are not available in that class you have to put them there by using middleware and thread locals. Take a look at the following snippet

https://djangosnippets.org/snippets/2037/

So in your RouterMiddleware you will check to see the subdomain and depending on that you will set a client_cfg option with the name of the client. Your SubDomainDatabaseRouter will use the correct database depending on the client_cfg. To use it just add

DATABASE_ROUTERS = ['my.package.SubDomainDatabaseRouter']

By using this you will have a completely different database for each client. I need to emphasize again that you will have a hell maintaining it - let's suppose you have 100 clients and need to add a field to a table. Then what ? Please don't blame me :)

(END OF DRAGONS)


Post a Comment for "Django Permissions For Different Clients"