Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
def testNoRecoveryNoTimeout(self):
with self.settings(USER_ALLOW_EMAIL_RECOVERY=False, USER_LOCKOUT_TIMEOUT=-1):
# get ourselves locked out
self.doLockout()
post_data = dict(lusername='plain', password='plain')
response = self.client.post(reverse('users.user_login'), post_data, follow=True)
# should say nothing about 10 minutes
content = response.content.decode("utf-8")
self.assertTrue(content.find("10 minutes") == -1)
# move all our lockout events to 11 minutes in the past
ten_minutes = timedelta(minutes=10)
for failed in FailedLogin.objects.filter(user=self.plain):
failed.failed_on = failed.failed_on - ten_minutes
failed.save()
# should still have no dice on trying to log in
post_data = dict(username='plain', password='plain')
response = self.client.post(reverse('users.user_login'), post_data, follow=True)
self.assertContains(response, "cannot log")
content = response.content.decode("utf-8")
self.assertEqual(content.find(reverse('users.user_forget')), -1)
# log in as superuser
self.client.post(reverse('users.user_login'), dict(username='superuser', password='superuser'))
# go edit our 'plain' user
self.client.get(reverse('users.user_update', args=[self.plain.id]))
def testNoRecovery(self):
with self.settings(USER_ALLOW_EMAIL_RECOVERY=False):
self.doLockout()
post_data = dict(username='plain', password='plain')
response = self.client.post(reverse('users.user_login'), post_data, follow=True)
# should say something about 10 minutes
self.assertContains(response, "10 minutes")
# move all our lockout events to 11 minutes in the past
ten_minutes = timedelta(minutes=10)
for failed in FailedLogin.objects.filter(user=self.plain):
failed.failed_on = failed.failed_on - ten_minutes
failed.save()
# should now be able to log in
response = self.client.post(reverse('users.user_login'), post_data, follow=True)
self.assertTrue(response.context['user'].is_authenticated)
self.assertContains(response, "cannot log")
content = response.content.decode("utf-8")
self.assertEqual(content.find(reverse('users.user_forget')), -1)
# log in as superuser
self.client.post(reverse('users.user_login'), dict(username='superuser', password='superuser'))
# go edit our 'plain' user
self.client.get(reverse('users.user_update', args=[self.plain.id]))
# change the password
post_data = dict(new_password='Password1', username='plain', groups='1', is_active='1')
self.client.post(reverse('users.user_update', args=[self.plain.id]), post_data)
# assert our lockouts got cleared
self.assertFalse(FailedLogin.objects.filter(user=self.plain))
# the user should be able to log in now
self.client.logout()
post_data = dict(username='plain', password='Password1')
response = self.client.post(reverse('users.user_login'), post_data, follow=True)
self.assertTrue(response.context['user'].is_authenticated)
from_email = getattr(settings, 'DEFAULT_FROM_EMAIL', 'website@%s' % domain)
user_email_template = getattr(settings, "USER_FORGET_EMAIL_TEMPLATE", "smartmin/users/user_email.txt")
no_user_email_template = getattr(settings, "NO_USER_FORGET_EMAIL_TEMPLATE",
"smartmin/users/no_user_email.txt")
email_template = loader.get_template(no_user_email_template)
user = get_user_model().objects.filter(email__iexact=email).first()
context = build_email_context(self.request, user)
if user:
token = ''.join(random.choice(string.ascii_uppercase + string.digits) for x in range(32))
RecoveryToken.objects.create(token=token, user=user)
email_template = loader.get_template(user_email_template)
FailedLogin.objects.filter(user=user).delete()
context['user'] = user
context['path'] = "%s" % reverse('users.user_recover', args=[token])
send_mail(_('Password Recovery Request'), email_template.render(context), from_email,
[email], fail_silently=False)
response = super(UserCRUDL.Forget, self).form_valid(form)
return response
lockout_timeout = getattr(settings, 'USER_LOCKOUT_TIMEOUT', 10)
failed_login_limit = getattr(settings, 'USER_FAILED_LOGIN_LIMIT', 5)
user = get_user_model().objects.filter(username__iexact=form.cleaned_data.get('username')).first()
# this could be a valid login by a user
if user:
# incorrect password? create a failed login token
valid_password = user.check_password(form.cleaned_data.get('password'))
if not valid_password:
FailedLogin.objects.create(user=user)
bad_interval = timezone.now() - timedelta(minutes=lockout_timeout)
failures = FailedLogin.objects.filter(user=user)
# if the failures reset after a period of time, then limit our query to that interval
if lockout_timeout > 0:
failures = failures.filter(failed_on__gt=bad_interval)
# if there are too many failed logins, take them to the failed page
if len(failures) >= failed_login_limit:
return HttpResponseRedirect(reverse('users.user_failed'))
# delete failed logins if the password is valid
elif valid_password:
FailedLogin.objects.filter(user=user).delete()
# pass through the normal login process
if form_is_valid:
return self.form_valid(form)
FailedLogin.objects.create(user=user)
bad_interval = timezone.now() - timedelta(minutes=lockout_timeout)
failures = FailedLogin.objects.filter(user=user)
# if the failures reset after a period of time, then limit our query to that interval
if lockout_timeout > 0:
failures = failures.filter(failed_on__gt=bad_interval)
# if there are too many failed logins, take them to the failed page
if len(failures) >= failed_login_limit:
return HttpResponseRedirect(reverse('users.user_failed'))
# delete failed logins if the password is valid
elif valid_password:
FailedLogin.objects.filter(user=user).delete()
# pass through the normal login process
if form_is_valid:
return self.form_valid(form)
else:
return self.form_invalid(form)
def post_save(self, obj):
obj = super(UserCRUDL.Profile, self).post_save(obj)
if 'new_password' in self.form.cleaned_data and self.form.cleaned_data['new_password']:
FailedLogin.objects.filter(user=self.object).delete()
PasswordHistory.objects.create(user=obj, password=obj.password)
return obj