1👍
Here’s what I ended up doing:
Models.py
from django.db import models
from django.contrib.auth.models import (AbstractUser, BaseUserManager, )
from django_auth_ldap.backend import LDAPBackend
from django.dispatch import receiver
# Create your models here.
class CustomUserManager(BaseUserManager):
def create_user(self, username, is_ldap, password, **extra_fields):
if not username:
raise ValueError(_('The username must be set'))
user = self.model(username=username,
is_ldap=is_ldap,
**extra_fields)
user.set_password(password)
user.save()
return user
def create_superuser(self, username, is_ldap, password=None, **extra_fields):
extra_fields.setdefault('is_staff', True)
extra_fields.setdefault('is_superuser', True)
extra_fields.setdefault('is_active', True)
if extra_fields.get('is_staff') is not True:
raise ValueError('Superuser must have is_staff=True.')
if extra_fields.get('is_superuser') is not True:
raise ValueError('Superuser must have is_superuser=True.')
return self.create_user(username, is_ldap, password, **extra_fields)
class CustomUser(AbstractUser):
is_ldap = models.BooleanField(default=False)
USERNAME_FIELD = 'username'
REQUIRED_FIELDS = ['is_ldap']
objects = CustomUserManager()
def __str__(self):
return self.username
@receiver(models.signals.post_save, sender=CustomUser)
def user_created(sender, instance, created, **kwargs):
if created and instance.is_ldap:
user = LDAPBackend().populate_user(instance.username)
admin.py
from django import forms
from django.contrib import admin
from django.contrib.auth.models import Group
from django.contrib.auth.admin import UserAdmin as BaseUserAdmin
from django.contrib.auth.admin import UserAdmin
from django.contrib.auth.forms import ReadOnlyPasswordHashField
from django.core.exceptions import ValidationError
from .models import CustomUser
class CustomUserCreationForm(forms.ModelForm):
"""A form for creating new users. Includes all the required
fields, plus a repeated password."""
password1 = forms.CharField(label='Password', widget=forms.PasswordInput)
password2 = forms.CharField(label='Password confirmation', widget=forms.PasswordInput)
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.fields['password1'].required = False
self.fields['password2'].required = False
class Meta:
model = CustomUser
fields = ('username','is_ldap',)
def clean_password2(self):
# Check that the two password entries match
password1 = self.cleaned_data.get("password1")
password2 = self.cleaned_data.get("password2")
is_ldap = self.cleaned_data.get("is_ldap")
if is_ldap:
if password1 or password2:
raise ValidationError("Leave password fields empty for an LDAP user")
else:
if not password1 or not password2:
raise ValidationError("Passwords don't match")
elif password1 and password2 and password1 != password2:
raise ValidationError("Passwords don't match")
return password2
def save(self, commit=True):
# Save the provided password in hashed format
user = super().save(commit=False)
if self.cleaned_data['is_ldap']:
user.set_unusable_password()
else:
user.set_password(self.cleaned_data["password1"])
if commit:
user.save()
return user
class CustomUserChangeForm(forms.ModelForm):
"""A form for updating users. Includes all the fields on
the user, but replaces the password field with admin's
disabled password hash display field.
"""
password = ReadOnlyPasswordHashField()
class Meta:
model = CustomUser
fields = ('username','is_ldap',)
class CustomUserAdmin(UserAdmin):
# The forms to add and change user instances
form = CustomUserChangeForm
add_form = CustomUserCreationForm
model = CustomUser
# The fields to be used in displaying the User model.
# These override the definitions on the base UserAdmin
# that reference specific fields on auth.User.
list_display = ('username', 'first_name', 'last_name', 'is_staff', 'is_active', 'is_ldap',)
# list_filter = ('username', 'is_staff', 'is_active',)
fieldsets = (
(None, {'fields': ('username', 'is_ldap', 'password')}),
('Personal info', {'fields': ('first_name', 'last_name')}),
('Permissions', {'fields': ('is_superuser','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', 'is_ldap', 'password1', 'password2'),
}),
)
search_fields = ('username',)
ordering = ('username',)
filter_horizontal = (['groups',])
admin.site.register(CustomUser, CustomUserAdmin)
Source:stackexchange.com