diff --git a/SciPost_v1/settings/base.py b/SciPost_v1/settings/base.py index 3a236b58512d1010200fe03a6e643579614ad7cc..4083889191653f3b3464621e2b8374370f43dd47 100644 --- a/SciPost_v1/settings/base.py +++ b/SciPost_v1/settings/base.py @@ -246,3 +246,31 @@ CROSSREF_LOGIN_PASSWORD = '' RECAPTCHA_PUBLIC_KEY = '6LeIxAcTAAAAAJcZVRqyHh71UMIEGNQ_MXjiZKhI' RECAPTCHA_PRIVATE_KEY = '6LeIxAcTAAAAAGG-vFI1TnRWxMZNFuojJ4WifJWe' NOCAPTCHA = True + + +# PASSWORDS + +PASSWORD_HASHERS = [ + 'django.contrib.auth.hashers.Argon2PasswordHasher', + 'django.contrib.auth.hashers.PBKDF2PasswordHasher', + 'django.contrib.auth.hashers.PBKDF2SHA1PasswordHasher', + 'django.contrib.auth.hashers.BCryptSHA256PasswordHasher', + 'django.contrib.auth.hashers.BCryptPasswordHasher', +] +AUTH_PASSWORD_VALIDATORS = [ + { + 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', + 'OPTIONS': { + 'min_length': 8, + } + }, + { + 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', + }, + { + 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + }, +] diff --git a/requirements.txt b/requirements.txt index 8a82ef7057d72bccf77dc2a8d9aeec140e2861bf..fe99a6a6fd57b124ee6a3bc066c10aa7087b4092 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,5 @@ alabaster==0.7.9 +argon2-cffi==16.3.0 Babel==2.3.4 Django==1.10.3 django_ajax_selects==1.5.2 diff --git a/scipost/forms.py b/scipost/forms.py index 7d830980a558b50c03ae13a09758c4875e4a4852..ebe43602d9e47d5de0a7d793a62d2dcfcc1d2347 100644 --- a/scipost/forms.py +++ b/scipost/forms.py @@ -4,6 +4,7 @@ import random from django import forms from django.contrib.auth.models import User, Group +from django.contrib.auth.password_validation import validate_password from django_countries import countries from django_countries.widgets import CountrySelectWidget @@ -67,9 +68,23 @@ class RegistrationForm(forms.Form): captcha = ReCaptchaField(attrs={'theme': 'clean'}, label='*Please verify to continue:') def clean_password_verif(self): + password = self.cleaned_data.get('password', '') + user = User( + username=self.cleaned_data['username'], + first_name=self.cleaned_data['first_name'], + last_name=self.cleaned_data['last_name'], + email=self.cleaned_data['email'] + ) + validate_password(password, user) + # raise + # return 'piemel' + + # def clean_password_verif(self): + # t = self.cleaned_data if self.cleaned_data['password'] != self.cleaned_data['password_verif']: self.add_error('password', 'Your passwords must match') self.add_error('password_verif', 'Your passwords must match') + return self.cleaned_data.get('password', '') def clean_username(self): if User.objects.filter(username=self.cleaned_data['username']).exists(): @@ -228,6 +243,15 @@ class PasswordChangeForm(forms.Form): password_new = forms.CharField(label='New password', widget=forms.PasswordInput()) password_verif = forms.CharField(label='Reenter new password', widget=forms.PasswordInput()) + def __init__(self, *args, **kwargs): + self.current_user = kwargs.pop('current_user', None) + super().__init__(*args, **kwargs) + + def clean_password_new(self): + password = self.cleaned_data['password_new'] + validate_password(password, self.current_user) + return password + AUTHORSHIP_CLAIM_CHOICES = ( ('-', '-'), diff --git a/scipost/views.py b/scipost/views.py index 728cc1755b43ef6de564c15e29fb14ff2cb9dcbb..cef2c9c6e9d82fa468bcc12a7c1a5b220190a874 100644 --- a/scipost/views.py +++ b/scipost/views.py @@ -889,7 +889,7 @@ def personal_page(request): @login_required def change_password(request): - form = PasswordChangeForm(request.POST or None) + form = PasswordChangeForm(request.POST or None, current_user=request.user) ack = False if form.is_valid(): if not request.user.check_password(form.cleaned_data['password_prev']):