Please suggest me the best way. I am developing a Django application, you will have 3 types of User: Administrator, Reseller and User. They must have hierarchy. The administrator can see everything. The dealer can see everything that its users did. The User only sees what he did.
How can I make these permissions with hierarchy?
You can handle it with 2 differents ways:
First solution (seems to be better in your case): using Django permissions
Here you're gonna create groups, permissions and users. A good practice is to link permissions to groups, and then to link your users to groups. This way, it's easy to change something in the future.
Second solution: create 3 different profiles that inherits from the User base class. It will be more complicated to handle thought.
I'm working on something similar. Per-line authorizations are a bit of a pain in Django. There are two projects out there that can achieve all you are asking for: django-permission and django-guardian. I needed more finely grained permissions and had to roll my own.
Related
I have a settings app inside my project, and every record in DB table that this app uses, represents particular setting.
And it is important that settings always must be consistent, so Im looking for way to protect them from accidental deletion by admin-panel users, or by buggy code.
Another cases for this feature might be - error messages stored in DB and available for editing in admin-site or templates for email messages for web-site users.
Possible solutions that I have in mind:
- Store each setting as table column or multiple columns, so the table will extends column-wise, not row-wise. Pros - simple, reliable, Cons - ugly
- DB-side solution.
- Implement some kind of permissions system which will control access for CRUD operations based on objects ownership, like file system permissions in Linux. Pros - less ugly, abstract from DB, Cons - I have no idea yet how to make easy and elegant implementation of it for Django.
Does anybody have better ideas?
The short answer is: if you don't want someone to have certain database abilities don't grant them. It appears that you are thinking there are admin panel superusers and everyone else.
Django allows much more fine grained control over Users, Permissions, Authorization, and even Admin Panel privileges. Indeed, too much control to elaborate here when the documentation does such a good job of it.
I'm not sure I completely understood your question, but here it goes:
I see two ways of protecting a model for being deleted:
Override the delete() method, and make it check a set of rules that enforce the consistency you require. E.g. if one of the consistency rules fail, you raise an exception to be properly handled.
The other is through autorization, aka permissions. You can manage permissions users have to delete particular models, as explained in this answer.
I notice that Django default permissions API does not support specific object's permissions, only permissions applied on models. However, there are third-party apps that provide this, such as this one.
In Django there is no real built-in way (that I am aware of) that prevents "accidental deletion". If you are using the admin, they do provide confirmation pages whenever you want to delete a record that can help curb the potential problem. As #msw mentioned, the user authentication system is designed to help you enforce permissions, but would not prevent accidental deletions if the individual has the proper permission to begin with...
...an alternative strategy would be to prevent deletions on the database entirely (at the web application level). You can give the "illusion" of a delete from the user's perspective by flagging and filtering out any "deleted" records to your user. That way, restoring information would be as simple as toggling/resetting the flag in the record. You would have to override the proper deletion signals as well.
I made a django application recently with multiple settings files, each setting file has its own SITE_ID and each SITE_ID is associated with site_id from the django_site table. Now, I want to create staff for certain sites only and other admins for all sites, how would I do something like that?
best wishes,
Mo - not sure whether you're still looking for an answer for this but this cross-post could be along the lines of what you're looking for.
I'm afraid I have bad news for you, you'll have to implement it on your own. What can
you do is to implement a new class say SiteUsers, it can look as follows:
class SiteUsers(models.Model):
site = models.ForeignKey(Site)
users = models.ForeignKey(User)
then you can use a kind of user_passes_test decorator to force access control. I'm not aware
of any ready to use solution.
another option would be to use groups. create set of groups for each site and sort users
to those groups. I think you'll have to have groups like:
site_1_add, site_1_delete, site_1_....
site_2_add, site_2_delete, site_2_....
however I'm afraid it does not scale so well. you will not find out unless you'll try.
anyway going either way will require a lot of admin customization. I really would need to do some research myself first.
I'm writing a web app, and I'd like to use repoze.what & repoze.who to handle my authorisation & authentication. The problem is that repoze.what seems to be hard-coded to accept a certain permissions model, that is:
Visitors to the site are either a logged in user, or anonymous.
User accounts belong to 0 or more groups.
Groups have 0 or more permissions associated with them.
So, for example, your permissions might be 'can-post-article' and 'can-post-comment', and your groups might be 'author', 'visitor', where 'author' can both post articles & post comments, while visitors can only post comments.
That model probably works for most sites. However, my site allows teams to collaborate with each other on different levels. So the security model that I need is:
Visitors are either a logged in user, or anonymous.
Users are a member of 0 or more groups.
For each group that the user is a member of, that membership will have different permissions. For example, the user might be an 'author' or group A, but a 'commenter' on group B.
The number of groups will change over time, and the memberships of those groups will also change. I can't see any easy way to integrate this permissions model into repoze.what. Am I missing something obvious?
Well, you could easily just have a "Group_A_commenter" group and "Group_B_editor" group. They don't have to be manually generated. :) Your model is really just a matter of grouping the groups.
But you should also be able to make Predicate checkers that implement your rules.
http://what.repoze.org/docs/1.0/Manual/Predicates/index.html#term-predicate
I have an answer, after a bit of fiddling.
The answer is that the only reason to use the authentication schema suggested in the repoze.what documentation is that if you do, you can use their predicates for free. Fortunately, writing & using your own predicates is a piece of cake. It seems to me that the only hard requirement is for a user object (although obviously you can call this whatever you want). In my app I have a bunch of custom predicates that check certain things like:
Is the user a member of this group? (group specified by a parameter)
Is the user logged in?
Does the user hold this particular site role?
I can then use these predicates wherever I want.
One company with many branches across the world using the same app. Each branch's supervisor, signing into the same /admin, should see and be able to manage only their records across many models (blog, galleries, subscribed users, clients list, etc.).
How to solve it best within django? I need a flexible and reliable solution, not hacks. Never came across this task, so really have no idea how to do it for the moment.
Tx
There is a nice tutorial here on Django Admin. It includes customizing the Admin to add row-level permissions (which, as i understand it, is what you want).
I'm building a simple app, a sort of project/tasks manager where I can have several projects and several tasks that are assigned to one project.
I enabled Django admin for all this sort of tasks and it's working like a charm. Also, I have some users that have projects assigned to them. So what I want now is to enable a cut down version of the admin for those users, where:
They can only manage/see tasks within their own project.
They can only delete their own tasks
some other minor restrictions.
What would be the best approach to this? Should I create another app with custom views and pages for client editing tasks or should I drop another admin instance and fine-tune it just for them?
I hope it was clear and not too subjective. Thanks.
+1 for custom app, hacking admin can take more time than just putting together your own admin from generic views.
I think that the best way to do this, either way, would be to somehow implement row-level permissions.
At the moment, the best solution for this is probably using the django-granular-permissions.
Like Dmitry I'm also for the custom app. Using generic views, modelforms et cetera will probably result in less work than modifying the admin app (which is not really made for hacking).
Also, if you keep an eye to the future, should the need for some more complex feature/restriction arise, you'll have less problems.