Bläddra i källkod

feat(api): require minimum password length (8 characters), fixes #317

Peter Thomassen 5 år sedan
förälder
incheckning
cf4c011bda
3 ändrade filer med 28 tillägg och 0 borttagningar
  1. 6 0
      api/api/settings.py
  2. 6 0
      api/desecapi/serializers.py
  3. 16 0
      api/desecapi/tests/test_user_management.py

+ 6 - 0
api/api/settings.py

@@ -195,6 +195,12 @@ SEPA = {
 }
 
 # user management
+AUTH_PASSWORD_VALIDATORS = [
+    {
+        'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+        'OPTIONS': {'min_length': 8}
+    },
+]
 MINIMUM_TTL_DEFAULT = int(os.environ['DESECSTACK_MINIMUM_TTL_DEFAULT'])
 AUTH_USER_MODEL = 'desecapi.User'
 LIMIT_USER_DOMAIN_COUNT_DEFAULT = 5

+ 6 - 0
api/desecapi/serializers.py

@@ -4,6 +4,7 @@ import re
 from base64 import urlsafe_b64decode, urlsafe_b64encode, b64encode
 
 from captcha.image import ImageCaptcha
+from django.contrib.auth.password_validation import validate_password
 from django.core.validators import MinValueValidator
 from django.db import IntegrityError, OperationalError
 from django.db.models import Model, Q
@@ -563,6 +564,11 @@ class UserSerializer(serializers.ModelSerializer):
             }
         }
 
+    def validate_password(self, value):
+        if value is not None:
+            validate_password(value)
+        return value
+
     def create(self, validated_data):
         return models.User.objects.create_user(**validated_data)
 

+ 16 - 0
api/desecapi/tests/test_user_management.py

@@ -242,6 +242,14 @@ class UserManagementTestCase(DesecTestCase, PublicSuffixMockMixin):
         )
         self.assertEqual(response.data['password'][0].code, 'blank')
 
+    def assertRegistrationFailurePasswordMinLengthResponse(self, response):
+        self.assertContains(
+            response=response,
+            text="This password is too short. It must contain at least 8 characters.",
+            status_code=status.HTTP_400_BAD_REQUEST
+        )
+        self.assertEqual(response.data['password'][0].code, 'password_too_short')
+
     def assertRegistrationFailureDomainUnavailableResponse(self, response, domain):
         self.assertContains(
             response=response,
@@ -533,6 +541,14 @@ class NoUserAccountTestCase(UserLifeCycleTestCase):
         self.assertNoEmailSent()
         self.assertUserDoesNotExist(email)
 
+    def test_registration_password_min_length(self):
+        email = self.random_username()
+        self.assertRegistrationFailurePasswordMinLengthResponse(
+            response=self.register_user(email=email, password='asdf123')[2]
+        )
+        self.assertNoEmailSent()
+        self.assertUserDoesNotExist(email)
+
     def test_no_login_with_unusable_password(self):
         email, password = self._test_registration(password=None)
         response = self.client.login_user(email, password)