From 49222eeeef69d780f1155505a991f3785c38c6ee Mon Sep 17 00:00:00 2001 From: Patrick Jentsch Date: Mon, 8 Jul 2019 15:13:32 +0200 Subject: [PATCH] Add password reset functionality. --- app/auth/forms.py | 7 +++++++ app/auth/views.py | 17 ++++++++++++++--- app/models.py | 14 ++++++++++++++ app/templates/auth/reset_password.html.j2 | 17 +++++++++++++++++ data_dev.sqlite | Bin 32768 -> 32768 bytes 5 files changed, 52 insertions(+), 3 deletions(-) diff --git a/app/auth/forms.py b/app/auth/forms.py index 3a71b095..d23e4e2d 100644 --- a/app/auth/forms.py +++ b/app/auth/forms.py @@ -35,6 +35,13 @@ class RegistrationForm(FlaskForm): raise ValidationError('Username already in use.') +class PasswordResetForm(FlaskForm): + password = PasswordField('New Password', validators=[ + DataRequired(), EqualTo('password2', message='Passwords must match')]) + password2 = PasswordField('Confirm password', validators=[DataRequired()]) + submit = SubmitField('Reset Password') + + class PasswordResetRequestForm(FlaskForm): email = StringField('Email', validators=[DataRequired(), Length(1, 64), Email()]) diff --git a/app/auth/views.py b/app/auth/views.py index 04afc1e6..5ecb5713 100644 --- a/app/auth/views.py +++ b/app/auth/views.py @@ -2,7 +2,7 @@ from flask import flash, redirect, render_template, request, url_for from flask_login import current_user, login_required, login_user, logout_user from . import auth from .. import db -from .forms import LoginForm, PasswordResetRequestForm, RegistrationForm +from .forms import LoginForm, PasswordResetForm, PasswordResetRequestForm, RegistrationForm from ..email import send_email from ..models import User @@ -64,6 +64,17 @@ def password_reset_request(): title='Password Reset') -@auth.route('/reset/') +@auth.route('/reset/', methods=['GET', 'POST']) def password_reset(token): - return 'test' + if not current_user.is_anonymous: + return redirect(url_for('main.index')) + form = PasswordResetForm() + if form.validate_on_submit(): + if User.reset_password(token, form.password.data): + db.session.commit() + flash('Your password has been updated.') + return redirect(url_for('auth.login')) + else: + return redirect(url_for('main.index')) + return render_template('auth/reset_password.html.j2', form=form, + title='Password Reset') diff --git a/app/models.py b/app/models.py index d7d33b85..1a34dd64 100644 --- a/app/models.py +++ b/app/models.py @@ -32,6 +32,20 @@ class User(UserMixin, db.Model): s = Serializer(current_app.config['SECRET_KEY'], expiration) return s.dumps({'reset': self.id}).decode('utf-8') + @staticmethod + def reset_password(token, new_password): + s = Serializer(current_app.config['SECRET_KEY']) + try: + data = s.loads(token.encode('utf-8')) + except: + return False + user = User.query.get(data.get('reset')) + if user is None: + return False + user.password = new_password + db.session.add(user) + return True + @property def password(self): raise AttributeError('password is not a readable attribute') diff --git a/app/templates/auth/reset_password.html.j2 b/app/templates/auth/reset_password.html.j2 index bb9cfe74..e545e464 100644 --- a/app/templates/auth/reset_password.html.j2 +++ b/app/templates/auth/reset_password.html.j2 @@ -7,10 +7,27 @@ Reset Your Password
{{ form.hidden_tag() }} + {% if form.email is defined %}
{{ form.email(class='validate', type='email') }} {{ form.email.label }}
+ {% endif %} + {% if form.password is defined %} +
+ {{ form.password(class='validate', type='password') }} + {{ form.password.label }} + {% for error in form.password.errors %} + {{ error }} + {% endfor %} +
+ {% endif %} + {% if form.password2 is defined %} +
+ {{ form.password2(class='validate', type='password') }} + {{ form.password2.label }} +
+ {% endif %}
{{ form.submit(class='btn right') }}
diff --git a/data_dev.sqlite b/data_dev.sqlite index 75d6c1549dd45cb57958eab66cc0bea1a30ac0cc..2f7bde00ac842344510abc2641c436f33afb700a 100644 GIT binary patch delta 100 zcmZo@U}|V!njp={J5k1&m6t)!z-nVkaJ;9VX-;LHd%llKiiL@}S&ETaYO0y3iGi_^ ziHU(>s*!;~vSDgcVq$7)l4VkwQBsPzp}9#)YO;}qp^;&-p`oR*ftitInuVqLq67s1 DcS0MS delta 100 zcmZo@U}|V!njp={Gf~Ewm4`u3X2Zsm;CN5}d^59