Django: Restrict staff user to give more permissions to a group than his own - django

I've created a Django app having multiple types of users.
There is one Superuser who can access all the data and do the modification stuff. There are few staff users, who have limited access, mostly of view but can add new users and groups.
Below is the group permission for the staff user. He can add a new group but cannot change, view or delete existing.
But when I try to create a new group, he can assign all the possible permissions to the new group, even though he doesn't have those permissions himself. Below is the view he can see when creating a new group.
How can I only show those permissions which the staff user himself have and not to show complete options?
I am using Django 2.1

This worked for me:
Create groups with various permissions
Prevent add or delete groups
#other imports
from django.contrib.auth.models import User
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
class UserAdmin(BaseUserAdmin):
list_display = ('username', 'email', 'is_staff')
list_filter = ('is_staff',)
#this displays after initial user creation for additional information
fieldsets = (
(None, {'fields': ('username', 'email', 'password')}),
('Personal info', {'fields': ('first_name',)}),
('Permissions', {'fields': ('is_staff', 'is_active', 'groups')}),
)
# add_fieldsets is not a standard ModelAdmin attribute. UserAdmin
# overrides get_fieldsets to use this attribute when creating a user.
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('username', 'email', 'password1', 'password2')}
),
)
search_fields = ('username',)
ordering = ('username',)
#unregister the default user admin
admin.site.unregister(User)
# Now register the new UserAdmin...
admin.site.register(User, UserAdmin)
This way, the user can not get additional permissions

Related

User password is not hashed when creating through Django admin panel

I have inherited the user class to make custom authentication. I do not get password hashing this way. It just stores as plain text in MySQL database. I have created staff through admin panel and unable to login as staff. Furthermore I have also created auth API endpoints using DRF and Djoser and am unable to login with the user profiles created through Django admin panel.
Here is my code.
models.py
from django.contrib.auth.models import AbstractUser
class User(AbstractUser):
pass
admin.py
from .models import User
class UserAdmin(admin.ModelAdmin):
pass
admin.site.register(User, UserAdmin)
I have seen old replies in Stack Overflow suggesting changing the parent class to django.contrib.auth.admin.UserAdmin . When I try this the add user template form only has 3 fields. Username, Password and Password Confirmation.
admin.py
from django.contrib.auth.admin import UserAdmin as DefaultUserAdmin
from .models import User
class UserAdmin(DefaultUserAdmin):
pass
admin.site.register(User, UserAdmin)
How do I solve this problem.
I wrote a custom UserAdmin as well so i guess i can help you a little bit with that
try this one:
#admin.register(User)
class UserAdmin(UserAdmin):
"""Define admin model for custom User model with no email field."""
fieldsets = (
(None, {'fields': ('email', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser')}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2'),
}),
)
list_display = ('email', 'is_staff')
search_fields = ('email',)
ordering = ('email',)
And i also think that there`s problems in your models.py bcs you dont have userManager
UserManager uses when you`re creating user so i guess problem in that

Django admin site user password change

Django admin site used to have a form to change the password for a user that wasn't the logged in user. You would look at the user's update page, and by the password field, there was a change password link. You would click it, and it would take you to a different page for changing the password. I used to take advantage of that page to allow changing of a user's password, without having to open the admin. In Django 4, it seems to now be missing. In fact, I can't figure out how one would change a user's password other than their own, without writing my own view.
I have 2 questions:
Is there a way in the admin site now to change a different user's password?
If this view is gone, what is now the best way for a superuser to have a view that can change passwords for a user?
Edit:
This is what I see. There is no link to change the password where there used to be.
Are you sure you have checked it right? When you select an user it appears by default in the upper part, just after some semi-blinded parameters of the password.
The problem was when I am using AbstractBaseUser, and the admin site registration I was using admin.ModelAdmin instead of UserAdmin.
from django.contrib.auth import get_user_model
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
class EmployeeAdmin(UserAdmin):
ordering = ['email', ]
list_display = ['email', ]
fieldsets = (
(None, {'fields': ('email', 'password')}),
('Info', {'fields': ('first_name', 'last_name', 'phone',)}),
('Address', {'fields': ('address', 'city', 'state', 'zip_code')}),
('Schedule', {'fields': ('time_off',)}),
('Permissions', {'fields': ('is_active', 'is_staff', 'is_superuser',
'groups', 'user_permissions')}),
('Important dates', {'fields': ('last_login', 'date_joined')}),
)
add_fieldsets = (
("User Details", {'fields': ('email', 'password1', 'password2')}),
("Permission", {'fields': ('is_active', 'is_staff', 'is_admin')}),
)
admin.site.register(get_user_model(), EmployeeAdmin)

Django-admin won't allow me to modify user permissions and groups

When editing user model through admin interface, here's what I see:
And here's what I expect to see:
The second one allows me to modify the user permissions, the first one does not.
The User model I use on the first screenshot inherits from AbstractUser and is registered in the following way:
from django.contrib import admin
import accounts.models
admin.site.register(accounts.models.User)
In my settings:
DEBUG = True
AUTH_USER_MODEL = 'accounts.User'
What can be the problem? How do I get from the first screenshot to the second?
Had the same issue but the solution is quite simple. In your admin.py file just add 'groups', 'user_permissions' to filter_horizontal = ()
i.e
filter_horizontal = ('groups', 'user_permissions')
that is basically it.
referenced from:
https://djangobook.com/customizing-change-lists-forms/
OK, the actual problem was that I inherited not from AbstractUser but from AbstractBaseUser and forgot about PermissionsMixin (the mixin adds the apropriate fields). So I should've done something like this.
The problem in my case is that, I was inheriting only from admin.UserAdmin, I had to create a UserAdmin class that inherits from admin.ModelAdmin and add the filter_horizontal to it, I'm adding the filter every time I modify the UserAdmin, it should look like:
class UserAdmin(UserAdmin):
model = User
filter_horizontal = ('groups', 'user_permissions')
add_form = UserCreationForm
form = UserChangeForm
list_display = ('email', 'is_staff', 'is_active',)
list_filter = ('email', 'is_staff', 'is_active',)
fieldsets = (
# ('Zone label',{'fields.....'})
(None, {'fields': ('email', 'username', 'password',)}),
('Permissions', {'fields': ('is_staff', 'is_active',)}),
('Personal', {'fields': ('about',)}),
)
add_fieldsets = (
(None, {
'classes': ('wide',),
'fields': ('email', 'password1', 'password2', 'is_staff', 'is_active')}
),
)
search_fields = ('email',)
ordering = ('date_joined',)
admin.site.register(User, UserAdmin)
admin.site.unregister(User)
class UserAdmin(admin.ModelAdmin):
list_display = ['username']
filter_horizontal = ("groups", "user_permissions")
admin.site.register(User, UserAdmin)

Username still required in custom user model

I am trying to use the new functionality in Django 1.5 to make use of an email address as the username.
Everything is working fine, bar the admin site to update users, which I have had to fiddle with to make passwords not appear raw (and use the password change form etc.) using this code:-
class PlayerChangeForm(UserChangeForm):
class Meta(UserChangeForm.Meta):
model = Player
class PlayerCreationForm(UserCreationForm):
class Meta(UserCreationForm.Meta):
model = Player
class PlayerAdmin(auth.admin.UserAdmin):
form = PlayerChangeForm
add_form = PlayerCreationForm
ordering = ['first_name', 'last_name']
list_display = ('primkey', 'email', 'mobile')
list_editable = ('email', 'mobile')
list_filter = ()
fieldsets = ((None, {'fields': ('username', 'first_name', 'last_name', 'email', 'password', 'mobile')}),
('Permissions', {'fields': ('is_active', 'is_admin')}),
('Important dates', {'fields': ('last_login', )}),
)
add_fieldsets = ((None, {
'classes': ('wide',),
'fields': ('username', 'first_name', 'last_name', 'email', 'password1', 'password2')}
),
)
filter_horizontal = ()
def primkey(self, obj):
return ("%s" % (obj.get_full_name()))
primkey.short_description = 'Player'
This makes the admin page look fine but when I actually try and update a Player, it tells me there is an error on the form but doesn't indicate where.
After a bit of messing around, it turns out that it wants the username field to be set (if I add that into the admin form, it says this field is required) but surely this isn't the case as I have set my USERNAME_FIELD to be 'email'?
If I set the field to something, I can then save any changes I've made to the other fields but it doesn't save my update to the username field. But really, I don't want to have to set the username at all - I'm using the email as the username.
Any ideas about this or is this a bug in Django?
The Django Documentation states that the forms must be rewritten:
UserCreationForm
Depends on the User model. Must be re-written for any custom user model.
UserChangeForm
Depends on the User model. Must be re-written for any custom user model.
There is a related ticket: https://code.djangoproject.com/ticket/19353 but the code still expect a username field to be present.

Changing Django prebuild form to add new user

I was given a task to add a field "location" to the django prebuilt user module
I found the location of the module itself and added the location field as well as the admin modules
eg:
class UserAdmin(admin.ModelAdmin):
add_form_template = 'admin/auth/user/add_form.html'
change_user_password_template = None
fieldsets = (
(None, {'fields': ('username', 'password')}),
(_('Personal info'), {'fields': ('first_name', 'last_name', 'email', 'location')}),
(_('Permissions'), {'fields': ('is_active', 'is_staff', 'is_superuser', 'user_permissions')}),
(_('Important dates'), {'fields': ('last_login', 'date_joined')}),
(_('Groups'), {'fields': ('groups',)}),
)
I rebuilt the database hoping it would show up in the adding of new user form.
But It didn't seem to work. So I assume I forgot to change something else.
I was looking around in the html code for ages trying to find the location of where the actual "change user" form is called, but couldn't find it.
I would appreciate help from someone who dealt with the pre built django admin backend before.
Thank you!
It's not recommended to modify django's user model because it complicates things. Instead, you can add a user profile as documented here.
If you want the profile to show up in the admin side, you can attach the profile as an inline and force it by unregistering the user and then re-registering it. Here's how I do it:
from django.contrib.auth.models import User
from reversion.admin import VersionAdmin
from profiles.models import Profile
from django.contrib import admin
from django.contrib.auth.admin import UserAdmin
class ProfileInline(admin.StackedInline):
model = Profile
fk_name = 'user'
extra = 0
max_num = 1
fieldsets = [
('Company', {'fields': ['company', 'office']}),
('User Information', {'fields': ['role', 'gender', 'phone', 'mobile', 'fax', 'street', 'street2', 'city', 'state', 'zip']}),
('Site Information', {'fields': ['sites']}),
]
class NewUserAdmin(VersionAdmin):
inlines = [ProfileInline, ]
admin.site.unregister(User)
admin.site.register(User, NewUserAdmin)