diff --git a/core/admin/mailu/ui/views/domains.py b/core/admin/mailu/ui/views/domains.py index b39657f1..4cdd830a 100644 --- a/core/admin/mailu/ui/views/domains.py +++ b/core/admin/mailu/ui/views/domains.py @@ -1,4 +1,4 @@ -from mailu import models +from mailu import models, utils from mailu.ui import ui, forms, access from flask import current_app as app @@ -93,12 +93,8 @@ def domain_signup(domain_name=None): del form.pw del form.pw2 if form.validate_on_submit(): - if not flask_login.current_user.is_authenticated and len(form.pw.data) < 8: - flask.flash("This password is too short.", "error") - return flask.render_template('domain/signup.html', form=form) - breaches = int(form.pwned.data) - if breaches > 0: - flask.flash(f"This password appears in {breaches} data breaches! Please change it.", "error") + if msg := utils.isBadOrPwned(form): + flask.flash(msg, "error") return flask.render_template('domain/signup.html', form=form) conflicting_domain = models.Domain.query.get(form.name.data) conflicting_alternative = models.Alternative.query.get(form.name.data) diff --git a/core/admin/mailu/ui/views/users.py b/core/admin/mailu/ui/views/users.py index 3fe96109..85a5c2db 100644 --- a/core/admin/mailu/ui/views/users.py +++ b/core/admin/mailu/ui/views/users.py @@ -1,4 +1,4 @@ -from mailu import models +from mailu import models, utils from mailu.ui import ui, access, forms from flask import current_app as app @@ -28,13 +28,8 @@ def user_create(domain_name): form.quota_bytes.validators = [ wtforms.validators.NumberRange(max=domain.max_quota_bytes)] if form.validate_on_submit(): - if len(form.pw.data) < 8: - flask.flash("This password is too short.", "error") - return flask.render_template('user/create.html', - domain=domain, form=form) - breaches = int(form.pwned.data) - if breaches > 0: - flask.flash(f"This password appears in {breaches} data breaches! Please change it.", "error") + if msg := utils.isBadOrPwned(form): + flask.flash(msg, "error") return flask.render_template('user/create.html', domain=domain, form=form) if domain.has_email(form.localpart.data): @@ -69,13 +64,8 @@ def user_edit(user_email): form.quota_bytes.validators = [ wtforms.validators.NumberRange(max=max_quota_bytes)] if form.validate_on_submit(): - if len(form.pw.data) < 8: - flask.flash("This password is too short.", "error") - return flask.render_template('user/edit.html', form=form, user=user, - domain=user.domain, max_quota_bytes=max_quota_bytes) - breaches = int(form.pwned.data) - if breaches > 0: - flask.flash(f"This password appears in {breaches} data breaches! Please change it.", "error") + if msg := utils.isBadOrPwned(form): + flask.flash(msg, "error") return flask.render_template('user/edit.html', form=form, user=user, domain=user.domain, max_quota_bytes=max_quota_bytes) form.populate_obj(user) @@ -137,12 +127,8 @@ def user_password(user_email): if form.pw.data != form.pw2.data: flask.flash('Passwords do not match', 'error') else: - if len(form.pw.data) < 8: - flask.flash("This password is too short.", "error") - return flask.render_template('user/password.html', form=form, user=user) - breaches = int(form.pwned.data) - if breaches > 0: - flask.flash(f"This password appears in {breaches} data breaches! Please change it.", "error") + if msg := utils.isBadOrPwned(form): + flask.flash(msg, "error") return flask.render_template('user/password.html', form=form, user=user) flask.session.regenerate() user.set_password(form.pw.data) @@ -195,12 +181,8 @@ def user_signup(domain_name=None): if domain.has_email(form.localpart.data) or models.Alias.resolve(form.localpart.data, domain_name): flask.flash('Email is already used', 'error') else: - if len(form.pw.data) < 8: - flask.flash("This password is too short.", "error") - return flask.render_template('user/signup.html', domain=domain, form=form) - breaches = int(form.pwned.data) - if breaches > 0: - flask.flash(f"This password appears in {breaches} data breaches! Please change it.", "error") + if msg := utils.isBadOrPwned(form): + flask.flash(msg, "error") return flask.render_template('user/signup.html', domain=domain, form=form) flask.session.regenerate() user = models.User(domain=domain) diff --git a/core/admin/mailu/utils.py b/core/admin/mailu/utils.py index 7e208702..4c55e27d 100644 --- a/core/admin/mailu/utils.py +++ b/core/admin/mailu/utils.py @@ -507,3 +507,14 @@ def gen_temp_token(email, session): app.config['PERMANENT_SESSION_LIFETIME'], ) return token + +def isBadOrPwned(form): + try: + if len(form.pw.data) < 8: + return "This password is too short." + breaches = int(form.pwned.data) + except ValueError: + breaches = -1 + if breaches > 0: + return f"This password appears in {breaches} data breaches! It is not unique; please change it." + return None