diff --git a/oneid/password_validation.py b/oneid/password_validation.py index 44c1a0ef3..f628342ce 100644 --- a/oneid/password_validation.py +++ b/oneid/password_validation.py @@ -1,11 +1,11 @@ """ -自定义规则校验集合 +自定义密码复杂度校验集合 """ import re from django.conf import settings -from django.core.exceptions import ValidationError from django.utils.translation import ugettext_lazy as _ +from rest_framework.exceptions import ValidationError PASSWORD_COMPLEXITY = getattr(settings, "PASSWORD_COMPLEXITY", None) @@ -13,8 +13,8 @@ # pylint: disable=useless-object-inheritance # pylint: disable=too-many-branches class _ComplexityValidator(object): - """自定义密码强度校验规则""" - message = _("必须更加复杂 (%s)") + """自定义密码复杂度校验规则""" + message = _("密码必须更加复杂 (%s)") code = "password_complexity" def __init__(self, complexities): @@ -55,22 +55,23 @@ def __call__(self, value): errors.append(_("%(SPECIAL)s 个及以上的特殊字符") % self.complexities) if len(words) < self.complexities.get("WORDS", 0): errors.append(_("%(WORDS)s 个及以上不同的单词") % self.complexities) - + if len(value) < self.complexities.get("LENGTH", 0): + errors.append(_("%(LENGTH)s 长度及以上的密码") % self.complexities) if errors: raise ValidationError(self.message % (_(u'必须包含 ') + u', '.join(errors), ), code=self.code) -_complexity = _ComplexityValidator(PASSWORD_COMPLEXITY) +_COMPLEXITY = _ComplexityValidator(PASSWORD_COMPLEXITY) # pylint: disable=missing-function-docstring -class ComplexityValidator(object): +class ComplexityValidator: """ Wrapper for validators.ComplexityValidator which is compatible with the Django 1.9+ password validation API """ def __init__(self): - self.validator = _complexity + self.validator = _COMPLEXITY # pylint: disable=no-self-use def get_help_text(self): diff --git a/oneid/settings.py b/oneid/settings.py index c9679a7ea..0010c423c 100644 --- a/oneid/settings.py +++ b/oneid/settings.py @@ -148,17 +148,23 @@ # https://docs.djangoproject.com/en/1.9/ref/settings/#auth-password-validators 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', + # }, { - 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator', - }, - { - 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator', + 'NAME': 'oneid.password_validation.ComplexityValidator', }, ] @@ -316,12 +322,13 @@ # 密码复杂度规则 # 值表示至少需包含的相应元素的个数,默认全部为0 PASSWORD_COMPLEXITY = { - "UPPER": 1, # 包含大写字母的个数 - "LOWER": 1, # 包含小写字母的个数 - "LETTERS": 1, # 包含大写和小写字母的个数 - "DIGITS": 1, # 包含数字的个数 - "SPECIAL": 1, # 包含特殊字符的个数 (不是字母数字、空格或标点字符) - "WORDS": 1, # 包含单词的个数 (由空格或标点分隔的字母数字序列) + "LENGTH": 0, # 密码的长度 + "UPPER": 0, # 包含大写字母的个数 + "LOWER": 0, # 包含小写字母的个数 + "LETTERS": 0, # 包含大写和小写字母的个数 + "DIGITS": 0, # 包含数字的个数 + "SPECIAL": 0, # 包含特殊字符的个数 (不是字母数字、空格或标点字符) + "WORDS": 0, # 包含单词的个数 (由空格或标点分隔的字母数字序列) } if os.path.exists(os.path.join(BASE_DIR, 'settings_local.py')): diff --git a/siteapi/v1/serializers/ucenter.py b/siteapi/v1/serializers/ucenter.py index 9404142db..e918de305 100644 --- a/siteapi/v1/serializers/ucenter.py +++ b/siteapi/v1/serializers/ucenter.py @@ -1,6 +1,7 @@ ''' serializers for ucenter ''' +from django.contrib.auth.password_validation import validate_password from rest_framework import serializers from rest_framework.exceptions import ValidationError from common.django.drf.serializer import DynamicFieldsModelSerializer @@ -104,6 +105,12 @@ def update(self, instance, validated_data): user.save(update_fields=['require_reset_password']) return user + @staticmethod + def validate_new_password(value): + """密码复杂度检验""" + validate_password(value) + return value + class UserRegisterSerializer(DynamicFieldsModelSerializer): ''' @@ -170,6 +177,12 @@ def create(self, validated_data): cli.set_user_password(user, password) return user + @staticmethod + def validate_password(value): + """密码复杂度检验""" + validate_password(value) + return value + class UserAlterMobileSerializer(serializers.Serializer): # pylint: disable=abstract-method ''' diff --git a/siteapi/v1/serializers/user.py b/siteapi/v1/serializers/user.py index d4e3183d6..d445650fd 100644 --- a/siteapi/v1/serializers/user.py +++ b/siteapi/v1/serializers/user.py @@ -2,7 +2,7 @@ ''' serializers for user ''' - +from django.contrib.auth.password_validation import validate_password from rest_framework import serializers from rest_framework.exceptions import ValidationError @@ -498,3 +498,9 @@ def update(self, instance, validated_data): instance.require_reset_password = require_reset_password instance.save(update_fields=['require_reset_password']) return instance + + @staticmethod + def validate_password(value): + """密码复杂度检验""" + validate_password(value) + return value diff --git a/siteapi/v1/views/user.py b/siteapi/v1/views/user.py index bfb6a6602..99c10e15b 100644 --- a/siteapi/v1/views/user.py +++ b/siteapi/v1/views/user.py @@ -6,7 +6,6 @@ - UserDept ''' # pylint: disable=too-many-lines - from rest_framework import generics, status, views from rest_framework.response import Response from rest_framework.exceptions import ( @@ -17,6 +16,7 @@ from rest_framework.permissions import IsAuthenticated, SAFE_METHODS from django.db import transaction from django.db.models import Q +from django.contrib.auth.password_validation import validate_password from django.core.exceptions import ObjectDoesNotExist, FieldDoesNotExist from oneid_meta.models import User, Group, Dept, GroupMember, UserPerm from oneid.permissions import ( @@ -228,6 +228,7 @@ def create(self, request, *args, **kwargs): # pylint: disable=unused-argument password = user_info.pop('password', None) user = cli.create_user(user_info) if password: + validate_password(password) cli.set_user_password(user, password) user.origin = 1 # 管理员添加 user.save() diff --git a/uwsgi.ini b/uwsgi.ini index 3ed0cb650..e15a68f15 100644 --- a/uwsgi.ini +++ b/uwsgi.ini @@ -10,6 +10,6 @@ processes = %(%k + 1) thunder-lock = true harakiri = 30 -listen = 65535 +;listen = 65535 disable-logging = true