byceps/byceps

View on GitHub
byceps/blueprints/common/authn/password/forms.py

Summary

Maintainability
A
0 mins
Test Coverage
A
96%
"""
byceps.blueprints.common.authn.password.forms
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

:Copyright: 2014-2024 Jochen Kupperschmidt
:License: Revised BSD (see `LICENSE` file for details)
"""

from flask import g
from flask_babel import lazy_gettext
from wtforms import PasswordField, StringField
from wtforms.validators import EqualTo, InputRequired, Length, ValidationError

from byceps.services.authn.password import authn_password_service
from byceps.util.l10n import LocalizedForm


MINIMUM_PASSWORD_LENGTH = 10
MAXIMUM_PASSWORD_LENGTH = 100


class NewPasswordLength(Length):
    def __init__(self) -> None:
        super().__init__(
            min=MINIMUM_PASSWORD_LENGTH, max=MAXIMUM_PASSWORD_LENGTH
        )


class PasswordConfirmationMatches(EqualTo):
    def __init__(self, companion_field_name: str) -> None:
        super().__init__(
            companion_field_name,
            message=lazy_gettext(
                'The new password and its confirmation must match.'
            ),
        )


class RequestResetForm(LocalizedForm):
    screen_name = StringField(lazy_gettext('Username'), [InputRequired()])


class ResetForm(LocalizedForm):
    new_password = PasswordField(
        lazy_gettext('New password'),
        [
            InputRequired(),
            NewPasswordLength(),
        ],
    )
    new_password_confirmation = PasswordField(
        lazy_gettext('New password (confirmation)'),
        [
            InputRequired(),
            PasswordConfirmationMatches('new_password'),
        ],
    )


class UpdateForm(ResetForm):
    old_password = PasswordField(
        lazy_gettext('Current password'), [InputRequired()]
    )

    @staticmethod
    def validate_old_password(form, field):
        user_id = g.user.id
        password = field.data

        if not authn_password_service.is_password_valid_for_user(
            user_id, password
        ):
            raise ValidationError(
                lazy_gettext('The password does not match the current one.')
            )