Reputation: 825
I have a User model which extends AbstractBaseUser
class User(AbstractBaseUser):
email = models.EmailField(max_length=255, unique=True, default='[email protected]')
forename = models.CharField(max_length=20, default='')
surname = models.CharField(max_length=20, default='')
account_expiry = models.DateField(default=datetime.now() + timedelta(days=365))
In all of my views I authenticate using the LoginRequiredMixin e.g.
class IndexView(LoginRequiredMixin, generic.TemplateView):
I want to authenticate users not just by email and password, but also by checking that the account expiry date has not been reached.
My question is - what is the best (simplest?) way to achieve this. Do I write my own custom authentication backend as described here? Or should I be looking to write a custom Mixin or Middleware?
Upvotes: 2
Views: 2478
Reputation: 825
So in the end my solution was to create my own custom middleware.
I found How to Create a Custom Django Middleware a useful starting point, but it wouldn't work for me because I am using Django 2.0.1. The official docs explained how to update the solution and I also found this SO post useful.
So my code looks like:
class AccountExpiry:
def __init__(self, get_response):
self.get_response = get_response
def __call__(self, request):
current_user = request.user
response = self.get_response(request)
expiry_path = reverse('accounts:account-expired')
if current_user.is_anonymous is False:
if current_user.admin is False and current_user.staff is False:
if request.path not in [expiry_path]:
expiry_date = current_user.school.account_expiry
todays_date = datetime.today().date()
if todays_date > expiry_date:
return HttpResponseRedirect(expiry_path)
return response
(note that account_expiry is actually a field in a related table (school) and not in the user model as per my original question above).
I updated settings MIDDLEWARE= to include
'common.middleware.AccountExpiry',
and it works as I want it to.
Upvotes: 7
Reputation: 1723
You could reimplement the is_authenticated
property of AbstractBaseUser
to return False
when the account has expired.
To prevent expired users from logging in you could also override check_password
to return False when the account has expired.
Upvotes: 1