Reputation: 1029
Below is my custom user model:
class CUserManager(BaseUserManager):
def _create_user(self, email, first_name, password,
is_staff, is_superuser, **extra_fields):
"""
Creates and saves a User with the given email and password.
"""
now = timezone.now()
if not email:
raise ValueError('The given email must be set')
email = self.normalize_email(email)
user = self.model(email=email,
first_name = first_name,
is_staff=is_staff, is_active=False,
is_superuser=is_superuser, last_login=now,
date_joined=now, **extra_fields)
user.set_password(password)
user.save(using=self._db)
return user
def create_user(self, email, first_name, password=None, **extra_fields):
return self._create_user(email, first_name, password, False, False,
**extra_fields)
def create_superuser(self, email, first_name, password, **extra_fields):
return self._create_user(email, first_name, password, True, True,
**extra_fields)
class CUser(AbstractBaseUser, PermissionsMixin):
email = models.EmailField(_('email address'), max_length=254, unique=True)
first_name = models.CharField(_('first name'), max_length=30)
last_name = models.CharField(_('last name'), max_length=30, blank=True)
is_staff = models.BooleanField(_('staff status'), default=False,
help_text=_('Designates whether the user can log into this admin '
'site.'))
is_active = models.BooleanField(_('active'), default=False,
help_text=_('Designates whether this user should be treated as '
'active. Unselect this instead of deleting accounts.'))
date_joined = models.DateTimeField(_('date joined'), default=timezone.now)
last_updated = models.DateTimeField(_('last updated'), default=timezone.now)
objects = CUserManager()
USERNAME_FIELD = 'email'
REQUIRED_FIELDS = ['first_name', 'last_name']
It creates a new user correctly. But when I try to authenticate the user from shell or from views, the authenticate() function doesn't work for users having is_active=False
.
>>> from django.contrib.auth import get_user_model, auhtenticate
>>> u = get_user_model()
>>> authenticate(username='[email protected]', password='abc)
The above line returns nothing if the user is inactive but returns the user object otherwise. I don't understand why its returning nothing for inactive users.
Upvotes: 3
Views: 7657
Reputation: 94
There are standard methods of doing it by customizing the auth backend. Some of them feel too cumbersome for simple applications that are to be done within deadlines. Here is a customized function that addresses this issue:
from django.contrib.auth.hashers import check_password
from users.models import CustomUser
def authenticate(username=None, password=None):
try:
# Get the corresponding user.
user = CustomUser.objects.get(username=username)
# If password, matches just return the user. Otherwise, return None.
if check_password(password, user.password):
return user
return None
except CustomUser.DoesNotExist:
# No user was found.
return None
username
parameter can be switched with any other parameter as well - like email
, et cetera, whatever the logic needs.Manager
s are not needed here.I have a special helper.py
file within each app to have such functions or classes. So that's where this goes. Just import it and use authenticate()
the usual way, except this would now work on the CustomUser
model rather than the User
model.
Upvotes: 0
Reputation:
Hi You can write Custom backend for this problem.
from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User
from apps.staffs.models import Staff(Custom User)
class StaffBackend:
# Create an authentication method
# This is called by the standard Django login procedure
def authenticate(self, username=None, password=None):
try:
# Try to find a user matching your username
user = Staff.objects.get(username=username)
# Check the password is the reverse of the username
if check_password(password, user.password):
# Yes? return the Django user object
return user
else:
# No? return None - triggers default login failed
return None
except Staff.DoesNotExist:
# No user was found, return None - triggers default login failed
return None
# Required for your backend to work properly - unchanged in most scenarios
def get_user(self, user_id):
try:
return Staff.objects.get(pk=user_id)
except Staff.DoesNotExist:
return None
Upvotes: 0
Reputation: 15390
It is happening because of how django's authentication works. By default it uses ModelBackend
which checks for is_active
https://docs.djangoproject.com/en/1.10/ref/contrib/auth/#django.contrib.auth.backends.ModelBackend.get_user_permissions
So you can create custom authentication backend which will ignore this option https://docs.djangoproject.com/en/1.10/topics/auth/customizing/#writing-an-authentication-backend
Upvotes: 2