Optionally allow accounts without security questions to reset password

Add a SECURITY_QUESTIONS_REQUIRED setting that defaults to True, but if
set to False then a user who has not set security questions will still
be allowed to reset their password. This is convenient for the OE Layer
index because there are a number of existing accounts, none of which
will have security questions set.

Signed-off-by: Paul Eggleton <paul.eggleton@linux.intel.com>
This commit is contained in:
Paul Eggleton 2019-07-17 15:15:07 +12:00
parent 40c728181a
commit fe4acbbb9b
4 changed files with 33 additions and 6 deletions

View File

@ -257,6 +257,9 @@ REMOVE_LAYER_DEPENDENCIES = False
# the login page) # the login page)
FORCE_REVIEW_HTTPS = True FORCE_REVIEW_HTTPS = True
# False to allow accounts without security questions to reset their password
SECURITY_QUESTIONS_REQUIRED = True
# Settings for layer submission feature # Settings for layer submission feature
SUBMIT_EMAIL_FROM = 'noreply@' + os.getenv('HOSTNAME', 'layers.test') SUBMIT_EMAIL_FROM = 'noreply@' + os.getenv('HOSTNAME', 'layers.test')
SUBMIT_EMAIL_SUBJECT = 'OE Layerindex layer submission' SUBMIT_EMAIL_SUBJECT = 'OE Layerindex layer submission'

View File

@ -11,7 +11,8 @@ from django.contrib.auth.hashers import check_password
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django_registration.forms import RegistrationForm from django_registration.forms import RegistrationForm
from layerindex.models import SecurityQuestion from layerindex.models import SecurityQuestion, UserProfile
import settings
class CaptchaRegistrationForm(RegistrationForm): class CaptchaRegistrationForm(RegistrationForm):
@ -84,9 +85,24 @@ class SecurityQuestionPasswordResetForm(SetPasswordForm):
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super(SecurityQuestionPasswordResetForm, self ).__init__(*args, **kwargs) super(SecurityQuestionPasswordResetForm, self ).__init__(*args, **kwargs)
self.fields['security_question_1'].initial=SecurityQuestion.objects.all()[0] security_questions = True
self.fields['security_question_2'].initial=SecurityQuestion.objects.all()[1] try:
self.fields['security_question_3'].initial=SecurityQuestion.objects.all()[2] self.user.userprofile
except UserProfile.DoesNotExist:
if not getattr(settings, 'SECURITY_QUESTIONS_REQUIRED', True):
security_questions = False
if security_questions:
self.fields['security_question_1'].initial = SecurityQuestion.objects.all()[0]
self.fields['security_question_2'].initial = SecurityQuestion.objects.all()[1]
self.fields['security_question_3'].initial = SecurityQuestion.objects.all()[2]
else:
del self.fields['security_question_1']
del self.fields['answer_1']
del self.fields['security_question_2']
del self.fields['answer_2']
del self.fields['security_question_3']
del self.fields['answer_3']
def clean_answer_util(self, question, answer): def clean_answer_util(self, question, answer):
form_security_question = self.cleaned_data[question] form_security_question = self.cleaned_data[question]
@ -117,7 +133,11 @@ class SecurityQuestionPasswordResetForm(SetPasswordForm):
def clean(self): def clean(self):
# We require three correct security question answers. The user gets # We require three correct security question answers. The user gets
# three attempts before their account is locked out. # three attempts before their account is locked out.
answer_attempts = self.user.userprofile.answer_attempts try:
answer_attempts = self.user.userprofile.answer_attempts
except UserProfile.DoesNotExist:
if not getattr(settings, 'SECURITY_QUESTIONS_REQUIRED', True):
return
if self.correct_answers < 3: if self.correct_answers < 3:
if answer_attempts < 2: if answer_attempts < 2:
self.user.userprofile.answer_attempts = self.user.userprofile.answer_attempts + 1 self.user.userprofile.answer_attempts = self.user.userprofile.answer_attempts + 1

View File

@ -109,7 +109,8 @@ class PasswordResetSecurityQuestions(PasswordResetConfirmView):
try: try:
self.user.userprofile self.user.userprofile
except UserProfile.DoesNotExist: except UserProfile.DoesNotExist:
return HttpResponseRedirect(reverse('password_reset_fail')) if getattr(settings, 'SECURITY_QUESTIONS_REQUIRED', True):
return HttpResponseRedirect(reverse('password_reset_fail'))
if not self.user.is_active: if not self.user.is_active:
return HttpResponseRedirect(reverse('account_lockout')) return HttpResponseRedirect(reverse('account_lockout'))

View File

@ -252,6 +252,9 @@ REMOVE_LAYER_DEPENDENCIES = False
# the login page) # the login page)
FORCE_REVIEW_HTTPS = False FORCE_REVIEW_HTTPS = False
# False to allow accounts without security questions to reset their password
SECURITY_QUESTIONS_REQUIRED = True
# Settings for layer submission feature # Settings for layer submission feature
SUBMIT_EMAIL_FROM = 'noreply@example.com' SUBMIT_EMAIL_FROM = 'noreply@example.com'
SUBMIT_EMAIL_SUBJECT = 'OE Layerindex layer submission' SUBMIT_EMAIL_SUBJECT = 'OE Layerindex layer submission'