class PasswordPoliciesAdminForm(AdminPasswordChangeForm): """Enforces password policies in the admin interface. Use this form to enforce strong passwords in the admin interface. """ error_messages = { 'password_mismatch': _("The two password fields didn't match."), 'password_used': _("The new password was used before. Please enter another one.") } password1 = PasswordPoliciesField(label=_("Password new"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH ) def clean_password1(self): """ Validates that a given password was not used before. """ password1 = self.cleaned_data.get('password1') if settings.PASSWORD_USE_HISTORY: if self.user.check_password(password1): raise forms.ValidationError( self.error_messages['password_used']) if not PasswordHistory.objects.check_password(self.user, password1): raise forms.ValidationError( self.error_messages['password_used']) return password1
class PasswordForm(PasswordPoliciesForm): """ Password form enforcing DEA password policy https://www.ict.govt.nz/guidance-and-resources/standards-compliance/authentication-standards/password-standard/6-password-minimum-requirements/ """ new_password1 = PasswordPoliciesField( label=_("New password"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH, validators=[UpperCaseLetterValidator()])
class UserCreationForm(BaseUserCreationForm): password1 = PasswordPoliciesField( label=_("New password"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH, help_text=_("Leave blank if not changing."), validators=[UpperCaseLetterValidator()], required=False, )
class CustomPasswordPoliciesForm(PasswordPoliciesForm): """ A form that lets a user set his/her password without entering the old password. """ new_password1 = PasswordPoliciesField( label=_("New password"), validators=[ LowerCaseLetterCountValidator, UpperCaseLetterCountValidator ], )
class PasswordPoliciesRegistrationForm(forms.Form): """ A form to support user registration with password policies. Has the following fields and methods:""" #: This forms error messages. error_messages = { "duplicate_username": _("A user with that username already exists."), "password_mismatch": _("The two password fields didn't match."), } username = forms.RegexField( label=_("Username"), max_length=30, regex=r"^[\w.@+-]+$", help_text= _("Required. 30 characters or fewer. Letters, digits and @/./+/-/_ only." ), error_messages={ "invalid": _("This value may contain only letters, numbers and @/./+/-/_ characters." ) }, ) password1 = PasswordPoliciesField( label=_("Password"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH, ) password2 = forms.CharField( label=_("Password confirmation"), widget=forms.PasswordInput, help_text=_("Enter the same password as above, for verification."), ) def clean_username(self): """ Validates that the username is not already taken.""" username = self.cleaned_data["username"] if (username and not get_user_model().objects.filter( username__iexact=username).count()): return username raise forms.ValidationError(self.error_messages["duplicate_username"]) def clean_password2(self): """ Validates that the two passwords are identical.""" password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 and password2 and password1 != password2: raise forms.ValidationError( self.error_messages["password_mismatch"]) return password2
class UserEditForm(forms.ModelForm): """ Intelligently sets up the username field if it is infact a username. If the User model has been swapped out, and the username field is an email or something else, dont touch it. """ def __init__(self, *args, **kwargs): super(UserEditForm, self).__init__(*args, **kwargs) if User.USERNAME_FIELD == 'username': field = self.fields['username'] field.regex = r"^[\w.@+-]+$" field.help_text = _("Required. 30 characters or fewer. Letters, " "digits and @/./+/-/_ only.") field.error_messages = field.error_messages.copy() field.error_messages.update({ 'invalid': _("This value may contain only letters, numbers " "and @/./+/-/_ characters.") }) @property def username_field(self): return self[User.USERNAME_FIELD] def separate_username_field(self): return User.USERNAME_FIELD not in standard_fields required_css_class = "required" error_messages = { 'duplicate_username': _("A user with that username already exists."), 'password_mismatch': _("The two password fields didn't match."), } email = forms.EmailField(required=True, label=_("Email")) first_name = forms.CharField(required=True, label=_("First Name")) last_name = forms.CharField(required=True, label=_("Last Name")) password1 = PasswordPoliciesField( label=_("New password"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH, help_text=_("Leave blank if not changing."), validators=[UpperCaseLetterValidator()], required=False, ) password2 = forms.CharField( label=_("Password confirmation"), required=False, widget=forms.PasswordInput, help_text=_("Enter the same password as above, for verification.")) is_superuser = forms.BooleanField( label=_("Administrator"), required=False, help_text=_( "Administrators have the ability to manage user accounts.")) class Meta: model = User fields = ("username", "email", "first_name", "last_name", "is_active", "is_superuser", "groups") widgets = {'groups': forms.CheckboxSelectMultiple} def clean_username(self): # Since User.username is unique, this check is redundant, # but it sets a nicer error message than the ORM. See #13147. username = self.cleaned_data["username"] try: User._default_manager.exclude(id=self.instance.id).get( username=username) except User.DoesNotExist: return username raise forms.ValidationError(self.error_messages['duplicate_username']) def clean_password2(self): password1 = self.cleaned_data.get("password1") password2 = self.cleaned_data.get("password2") if password1 != password2: raise forms.ValidationError( self.error_messages['password_mismatch']) return password2 def save(self, commit=True): user = super(UserEditForm, self).save(commit=False) # users can access django-admin if they are a superuser user.is_staff = user.is_superuser if self.cleaned_data["password1"]: user.set_password(self.cleaned_data["password1"]) if commit: user.save() self.save_m2m() return user
class PasswordPoliciesForm(forms.Form): """ A form that lets a user set his/her password without entering the old password. Has the following fields and methods: """ #: This forms error messages. error_messages = { 'password_mismatch': _("The two password fields didn't match."), 'password_used': _("The new password was used before. " "Please enter another one."), } new_password1 = PasswordPoliciesField(label=_("New password"), max_length=settings.PASSWORD_MAX_LENGTH, min_length=settings.PASSWORD_MIN_LENGTH) new_password2 = forms.CharField(label=_("New password confirmation"), widget=forms.PasswordInput) def __init__(self, user, *args, **kwargs): """ Initializes the form. :arg user: A :class:`~django.contrib.auth.models.User` instance. """ self.user = user super(PasswordPoliciesForm, self).__init__(*args, **kwargs) def clean_new_password1(self): """ Validates that a given password was not used before. """ new_password1 = self.cleaned_data.get('new_password1') if settings.PASSWORD_USE_HISTORY: if self.user.check_password(new_password1): raise forms.ValidationError( self.error_messages['password_used']) if not PasswordHistory.objects.check_password(self.user, new_password1): raise forms.ValidationError( self.error_messages['password_used']) return new_password1 def clean_new_password2(self): """ Validates that the two new passwords match. """ password1 = self.cleaned_data.get('new_password1') password2 = self.cleaned_data.get('new_password2') if password1 and password2: if password1 != password2: raise forms.ValidationError( self.error_messages['password_mismatch']) return password2 def save(self, commit=True): """ Sets the user's password to the new one and creates an entry in the user's password history, if :py:attr:`~password_policies.conf.Settings.PASSWORD_USE_HISTORY` is set to ``True``. """ new_password = self.cleaned_data['new_password1'] self.user.set_password(new_password) if commit: self.user.save() if settings.PASSWORD_USE_HISTORY: password = make_password(new_password) PasswordHistory.objects.create(password=password, user=self.user) PasswordHistory.objects.delete_expired(self.user) PasswordChangeRequired.objects.filter(user=self.user).delete() return self.user