How to prevent staff users from editing/deleting superuser in django - django

I want to be able to allow certain staff users the rights to add other users and staff but what seems weird to me is that 1) a staff member can just change their own privileges to superuser or just make a new user and grant superuser privileges to them. 2) delete a superuser or revoke their superuser status
Some staff users should be able to modify/create/delete users but they should not be able to delete super users nor assign permissions to themselves or other users that they do not have the permission themselves.
This has always been logic I have incorporated into my user systems that I've written in PHP and I was just wondering if there was a way to change these settings in Django as I really like Python/Django (I'm just beginning to learn it) and can see myself migrating away from PHP. But part of the beauty for me lied in the admin panel and if that is something that cannot be changed, that's kind of cringe-worthy.
It reminds me of a restaurant POS system that I used to use when I was a GM. As the GM, I had powers that shift managers did not have. However, the shift managers could add a fingerprint to my profile (theirs) and then just log in as me and do anything they wanted to. I always felt this was a severe security breach and even took disciplinary action on an employee for doing this. It also allowed the shift managers to create new employees with titles that were above theirs which created the same problem as they could just create a new GM or Area Manager, login, do whatever they wanted, and see all kinds of things that they shouldn't (like their colleagues' salaries), and then hide (not delete) the user. (this is how he got caught)
If anyone has a fix or any ideas and suggestions, I'd love to hear them and keep learning this exciting new language. Thanks in advance!

Django admin is a basic CRUD system, it is not recommended to use in that way. Django views (your custom views) give you more power to control the process.
First of all, Django Permissions might be a good start point. Create Groups for user types and assign desired permissions for each group. Do not give permission for non-superusers to change group or permissions.
Second thing is using Django Signals to check data before saving it. For example, a pre_save signal for User creation can be used to check if is_superuser, is_staff values of the user are set by non-superuser. You can add added_by value to the user model and verify your checks using this value.
Also, using custom forms for Django admin is also possible and might be the simplest solution for it. Just make a custom form for creating and editing users and verify changes in the form directly before allowing the view to save anything. It is also possible to inform user that they don't have access for changes they made and also notify the management about the attempt.

Related

How to add more features to user permission in django?

I am new to django. I want to edit default user auth_permissions. More precisely I want to add an integer field in addition to "label", "code" features to distinct permission types (like strong, moderate and etc.). So far I could not find anything like this. I tried to make custom permissions, but could not add them to the permission database. Anyone could help me?
Per Object permission
When i first got into django i also tried relying on the permissions framework within django, I also found the permissions were too broad and inefficient, which lead me to researching django-guardian, I tried to submit an edit to the Django project itself to make more object-base permissions with no success, they said as per object permissions were too personalised for the framework.
The thing is, after getting to work in the industry i realised how people do these permissions in the industry (which honestly was something that bugged me), they mainly create custom login middlewares to keep track of authentication types and add the checks on the view itself. So basically you will have to check in the view who the user is and if you want to give them permission to whatever.
When in MIT they kept asking me to make some weird permissions and I created a table called ExtraordinaryPermissions, this had a ForeignKey to the user and could be used to check within the views what objects the user had access to
It is troublesome, but as-per-object permissions are handed this way in the industry
good luck

How to activate users manually

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.

TikiWiki user management

How do I manage users of our tikiwiki?
The tiki process on the server is ran under my name. I am the user of the tikiwiki, but I am not sure I am an admin user.
Most likely not but question one is: How do I find that out?
(my Admin Menu is empty)
Some user contacted me saying her account is "Locked". It so happened that there is no one else to restore it, but me.
Can anyone help where to look? I only used my tikiwiki account to limited extent. Just wrote couple of articles. But never administered.
There is always a built in user in Tiki called "admin" and that is in a group called "Admins" which has permission to do everything, so it sounds like your user isn't in that group.
If the admin user was set up with a valid email account (and you know it and have access to it) then you can get the password reset and a link to make a new one will be emailed to that address. If you can access the installer or the database then there are various other options on how to recover the admin login here: https://doc.tiki.org/Lost+admin+password
Once you have done this and can administer the Tiki again you should add your usual user to the Admins group.
To unlock another user's account you will need to either access the user admin list (once you have admin login again) or if you can get to the database you should be able to clear the relevant field in the database directly using phpmyadmin or similar as a last resort (ask again if you need this much detail).

Does Django store information about who has edited and/or created a record, and if so, where?

Django has an authentication and authorization scheme baked in ('django.contrib.auth') as well as modelforms to generate forms for easy input of data into the database.
I'd like to be able to record who created a record, leveraging django.contrib.auth, with the explicit purpose of limiting editing of that same record to just that user and/or people with an "edit" permission. I know that I could use the #user_passes_test decorator to restrict access to editing my record in some fashion, but I don't know what I would compare the request.user.name to in order to determine if the current user originally created that record.
How much of this do I need to roll on my own? Do I need to capture the name author, save it to the model, and then read it - or is there something already in the framework that would do this for me?
And, if I was to attempt to save the author in a field, how would I go about doing that in such a way as to not let the user edit their own credentials?
There are a couple of apps to do something similar, please check https://www.djangopackages.com/grids/g/model-audit/
About the last questions, to prevent the user not to edit its own credentials, you can mark the field with editable=False so it wont appear in the admin or ModelForms.

django staff users manage their own users only

In my Django app a user can register to the site and receive staff_user privileges from the admin.
After that the staff user can create and manage some other users (normal users) using default django admin site.
Now, I would like to let the staff user see and manage only the users he created from the admin site, I don't want him to see other users created by another staff user.
how can I do that? I imagine I need to modify admin.py right?
Don't modify the admin site.
In general, you have the following tools available:
Create groups
Add users to groups
Create custom permissions on your models, to indicate certain actions
https://docs.djangoproject.com/en/1.4/topics/auth/#custom-permissions
However, what you are asking: Now, I would like to let the staff user see and manage only the users he created from the admin site is not possible in django-admin.
The Django-admin site is only intended as a glorified development tool for fully trusted users, not as a customizable app for end users.
If your project requires an admin site with any of the following ...
Customized administraion functionality.
Exposure to any user that is not completely trusted.
... then I'm afraid you have to create your own custom app.
You can replace the stock UserAdmin with your own which overrides queryset() and does the filtering. The bigger issue is what to filter by. The default User model does not store a "created_by" in the model instance. So you would need to add this information whenever a User is added.
How best to do this depends on your Django version.
Django 1.5 introduced a "Configurable User model" which makes this very easy.
https://docs.djangoproject.com/en/dev/releases/1.5/#configurable-user-model
In earlier versions you would either have to monkeypatch the User model, or store that information in a separate "user profile" attached 1:1 to the User.
https://docs.djangoproject.com/en/dev/topics/auth/customizing/#extending-the-existing-user-model
Regarding the trusting of users (which wasn't a topic but I feel the need to comment on thnee's answer) in the Django admin, check out the links in my answer here: Should I use Django's Admin feature?