What I would like to do is to set view permissions of certain parts of the site depending on the user (that is easy using permissions and guardian).
I have a set of buttons across the top of the page. For one or two buttons I want to set permissions for only a few users or groups to be able to see that button. That part is fine (using guardian).
Each button is related to a model instance. The model has a view_button permission. Is there a way to have the view_button permission be default to True if the permissions is empty? Or, is there a way of saying has_perm be True for all users?
Maybe I could just create a static method within the model that does that check for me. Is there a better way to do it?
Related
I have a Django class based view in which I am using the PermissionRequiredMixin. I would like a user who has at least one of the permissions in the permissions_required attribute to be able to access the view. From the Django documentation:
The decorator may also take an iterable of permissions, in which case
the user must have all of the permissions in order to access the view.
So, if User1 has permission, "add_polls" and User2 has "change_polls", and I have a form view that lets a user add a poll and another view that lets a user change a poll (with permissions_required="add_polls" and permissions_required="change_polls" on each of those views, respectively), it works great. But, what if I have an interim page/view that has links to both of those views with permissions_required = ("add_polls", "change_polls") that I need the user to pass through first? Now, neither user will be able to access to that page because the users only have access to one or the other permission, not both - if I understand the documentation correctly, a user will need BOTH those permissions to access the interim page. If I did give both users access to both those permissions so they could access the interim page, this would then give both users access to both the add and change polls as well which I don't want.
Will I need to write a custom authorization to handle this, or am I missing something simple?
One possible solution would be to create another privilege - something like "interim-polls" which would be the permissions_required on the interim view. User1 would be assigned "add-polls" and "interim-polls", and User2 would be assigned "change-polls" and "interim-polls".
This would work, but is there an easier or more intuitive way than to have to add additional permissions? Maybe a way to specify that only one item in the list of "permissions_required" is actually required to access the form instead of all of them? i.e. permission1 OR permission2 as opposed to permission1 AND permission2 required to access the view.
Thank you for any insight.
[Edit - adding additional information]
I'll use some pseudocode here to give an idea of the views:
class ChooseAddorEdit(LoginRequiredMixin, PermissionRequiredMixin, TemplateView):
permission_required=('app.add_item', 'app.change_item')
Display Add (links to AddItem) or Edit (links to EditItem) Links
...
class AddItemFormView(LoginRequiredMixin, PermissionRequiredMixin, CreateView):
permission_required='app.add_item'
Manages form to add an item
...
class EditItemFormView(LoginRequiredMixin, PermissionRequiredMixin, UpdateView):
permission_required='app.change_item'
Manages form to edit an item
...
The user would be required to have both permissions to access the ChooseAddorEdit view. If the user has both permissions, then that user can access both the Add and Edit views. What I would like to accomplish some users to be able to only add items and other users to be able to only edit items, but still be able to see the ChooseAddorEdit view.
As I mentioned above, this could be accomplished by adding another custom permission in the model's Meta: but is there a way to accomplish this without adding yet more individual permissions and using the ones available?
Django 1.11.2
django-registration-redux==1.6
I'm building an intranet website. And I'd like to control myself whether users are active or not. In Django admin there is such a possibility. But "Active" attribute is set to True automatically when a newly registered user confirms his/her email.
In other words what I'd like to do:
1) Let users register and reset passwords.
2) Admin of the site assigns the new user to a group. Users with the minimum permissions can only view. Special permissions allow edit, delete etc. But the user must be unable even to view anything without approval by the admin.
Now I'm planning to organize can_view permission for every model. The two above conditions will be performed by assigning the user to a group.
Well, this seems to be rather cumbersome. That "Active" attribute in admin is much more elegant. But "Active" is automatically set to True when the user confirms his/her email.
Could you give me a piece of advice here?
While it's tempting, never use is_active to deny permissions. The flag is meant to be equivalent to "deleting a user". That also means the user cannot login (with default authentication backend). So it's not an authorization guard, but an authentication guard.
That said, if you don't grant permissions, users don't have them. So if you implement can_view and set it to guard the relevant models and views, then the user can log in, but cannot see anything you don't want them to (it's convenient for a user to see that she successfully logged in though :) ).
Follow-up question from comments
It's fine to use one global permission that is checked per view. When using class based views, I recommend extending LoginRequiredMixin, tuck a few other goodies in a IntranetCommonMixin and have each view combine it with one of the generic base views. See also my answer here.
The only reason you don't want to do it, is that it's tough to code exceptions on the rule, because the first "object" that says "yes", wins.
First, sorry for my poor english.
I'm trying to make a Django system that supports different admins to get the same admin panel, but showing them different objects, that belong to the same CustomModel.
Example:
First step: --> Login
Seconds step: --> Redirect to admin panel (django.contrib.admin.site)
and.. nothing else.
The problem is that I don't know how to show in that panel the objects that corresponds to the logged admin.
Thanks! Gracias!
This is where Django Permissions enter the picture
Django comes with a simple permissions system. It provides a way to
assign permissions to specific users and groups of users.
It’s used by the Django admin site, but you’re welcome to use it in
your own code.
The Django admin site uses permissions as follows:
Access to view the “add” form and add an object is limited to users
with the “add” permission for that type of object. Access to view the
change list, view the “change” form and change an object is limited to
users with the “change” permission for that type of object. Access to
delete an object is limited to users with the “delete” permission for
that type of object.
If you give a staff user permissions to work with only a certain type of object, that's all that he will see in the admin area.
If you have lots of different admin, you can put them into groups and grant permissions for the groups.
So as of right now I just have a page that I use locally to change objects. How can I go about creating a page that is only visible to the admin user. Using roles you can restrict access to certain objects but Im not sure the best way to include a page in your application that is only visible to certain users. Thanks for any help
Create an AccessRole (or similar) class that you can use for this, then show or hide the link/button (from menu or whatever) to open that page. Users who are not members of the Admin role does not see the button/link/menu option.
In the AccessRole class, you have a "users" column where you store an array of users that are members of the role, and a "name" column for the role name (Admin, Editor, Reader etc).
When your application starts, you check if the user is a member of the Admin role (which should be temporarily stored locally).
I have added row level permissions with django-guardian to my project.
From the set-up it seems everything worked fine:
Guardian specific tables have been created (guardian_groupobjectpermission, guardian_userobjectpermission)
Models with GuardedModelAdmin show the "Object permissions" feature next to "History"
It lets me assign "Add", "Change", "Delete" permissions for users/groups
But assigning (resp. not assigning) permissions shows no impact at all on the admin interface. Every user is allowed to do everything with all objects.
I have tried with
user_can_access_owned_objects_only = True
but this only affects the ability to view objects. Once a user sees it, he can also change and delete it. Regardless what is set in the permissions.
And I followed another discussion suggesting this in the ModelAdmin
def queryset(self, request):
if request.user.is_superuser:
return get_objects_for_user(user=request.user, perms=['change_program'], klass=Program)
But this has a similar effect as above, it only limits the visible items.
I would have hoped to see the admin "save" and "delete" buttons (and functions) listening to django-guardian. Is this a misunderstanding? Or did I simply not walk down the entire road yet?
Thanks for any hint!
R
Guardian allows you to create your own permissions to assign to user/object combinations, but limiting access to resources based on those object permissions still requires you to write code in your views. As such, there is no automatic enforcing within the Admin views. The admin integration is for allowing users with access to the admin interface to manage object-level permissions, see the guardian docs:
http://django-guardian.readthedocs.org/en/latest/userguide/admin-integration.html