from . import ldap_client from flask import ( Blueprint, render_template, flash, current_app ) from flask_wtf import FlaskForm from wtforms import ( StringField, PasswordField, SubmitField ) from wtforms.validators import ( ValidationError, DataRequired, EqualTo, Length, Regexp ) bp = Blueprint('reset', __name__, url_prefix='/reset') class ResetPasswordForm(FlaskForm): # Minimal password length minlength = 9 # Form username = StringField(label=('Login'), validators=[DataRequired(), Length(max=64)], render_kw={"onkeyup": "validate_username()"}) currentpassword = PasswordField(label=('Current password'), validators=[DataRequired()]) newpassword = PasswordField(label=('New password'), validators=[DataRequired(), Length(min=minlength), Regexp("^(?=.*[a-z])"), Regexp("^(?=.*[A-Z])"), Regexp("^(?=.*\\d)"), #Regexp( # "(?=.*[@$!%*#?&])", message="Password must contain a special character" #),], ], render_kw={"onkeyup": f"validate_form({minlength})"}) confirm_password = PasswordField( label=('Confirm Password'), validators=[DataRequired(message='* Required'), EqualTo('newpassword')], render_kw={"onkeyup": f"validate_confirm({minlength})"}) submit = SubmitField(label=('Change my password'), render_kw={"onclick": f"validate_form({minlength})"}) # Validators def validate_username(self, username): excluded_chars = " *?!'^+%&/()=}][{$#;\\\"" for char in self.username.data: if char in excluded_chars: raise ValidationError( f"Character {char} is not allowed in an username.") @bp.route('/', methods=('GET', 'POST')) def reset(): form = ResetPasswordForm() if form.validate_on_submit(): client = ldap_client.Client(address=current_app.config["LDAP_ADDR"], port=current_app.config["LDAP_PORT"], base_dn=current_app.config["BASE_DN"], tls=current_app.config["LDAP_TLS"]) bind_status = client.bind(form.username._value(), form.currentpassword._value()) if bind_status[0] == False: flash(f"Connection failed, are you sure that your login and password are correct ? ({client.link.last_error})") elif client.change_pwd(bind_status[1], form.newpassword._value()) == False: flash(f"An error occured and your password was not changed, sorry. ({client.link.last_error})") client.unbind() else: flash('Your password has been changed !') client.unbind() return render_template('reset.html', form=form)