Skip to content

Commit

Permalink
Reset password functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
kristallizer committed Jun 7, 2014
1 parent aee3d66 commit 0eddd76
Show file tree
Hide file tree
Showing 7 changed files with 118 additions and 5 deletions.
61 changes: 60 additions & 1 deletion app.py
Original file line number Diff line number Diff line change
@@ -1,20 +1,26 @@
import ast
import StringIO
import base64
from urllib import urlencode
from requests import get, post
import json
from itsdangerous import URLSafeTimedSerializer

from flask import Flask, request, render_template, url_for, redirect, flash, \
session
from flask_mail import Mail, Message
import dotenv
from getenv import env
import drest

from api import MetpetAPI
from forms import LoginForm
from forms import LoginForm, RequestPasswordResetForm, PasswordResetForm
from utilities import paginate_model


app = Flask(__name__)
app.config.from_object('config')
mail = Mail(app)


@app.route('/')
Expand Down Expand Up @@ -110,6 +116,59 @@ def logout():
return redirect(url_for('search'))


@app.route('/request-password-reset', methods=['GET', 'POST'])
def request_reset_password():
form = RequestPasswordResetForm()

if form.validate_on_submit():
payload = {'email': form.email.data}
response = post(env('API_HOST') + '/reset-password/', data=payload)
if response.status_code == 200:
data = json.loads(response.text)
message = Message("Metpetdb: Reset Password",
sender='[email protected]',
recipients = ['[email protected]'])
reset_url = url_for('reset_password', token=data['reset_token'],
_external=True)
message.body = render_template('reset_password_email.html',
reset_url=reset_url)
mail.send(message)
flash('Please check your email for a link to reset your password')
return redirect(url_for('login'))
else:
flash("Invalid email. Please try again.")

return render_template('request_password_reset.html', form=form)


@app.route('/reset-password/<string:token>', methods=['GET', 'POST'])
def reset_password(token):
form = PasswordResetForm()
if form.validate_on_submit():
payload = {'token': form.token.data,
'password': form.password.data}
response = post(env('API_HOST') + '/reset-password/', data=payload)
if response.status_code == 200:
print(response.text)
data = json.loads(response.text)
session['email'] = data['email']
session['api_key'] = data['api_key']
flash('Password reset successful!')
return redirect(url_for('search'))
else:
flash('Password reset failed. Please try again.')
return redirect(url_for('request_reset_password'))

if token:
response = get(env('API_HOST') + '/reset-password/' + token)
if response.status_code == 200:
form = PasswordResetForm(token=token)
return render_template('reset_password.html', form=form)

flash('Password reset failed. Please try again.')
return redirect(url_for('request_reset_password'))


@app.route('/samples/')
def samples():
email = session.get('email', None)
Expand Down
6 changes: 6 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,9 @@

CSRF_ENABLED = True
SECRET_KEY = env('SECRET_KEY')

MAIL_SERVER = env('MAIL_SERVER')
MAIL_PORT = env('MAIL_PORT')
MAIL_USE_TLS = env('MAIL_USE_TLS')
MAIL_USERNAME = env('MAIL_USERNAME')
MAIL_PASSWORD = env('MAIL_PASSWORD')
17 changes: 14 additions & 3 deletions forms.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,18 @@
from flask.ext.wtf import Form
from wtforms import TextField, PasswordField
from wtforms.validators import Required
from wtforms import TextField, PasswordField, HiddenField
from wtforms.validators import Required, Email, EqualTo

class LoginForm(Form):
email = TextField('email', validators = [Required()])
email = TextField('email', validators = [Required(), Email()])
password = PasswordField('password')

class RequestPasswordResetForm(Form):
email = TextField('email', validators = [Required(), Email()])

class PasswordResetForm(Form):
token = HiddenField()
password = PasswordField('password', validators = [
Required(),
EqualTo('confirm', message='Passwords must match')
])
confirm = PasswordField('confirm')
5 changes: 4 additions & 1 deletion templates/login.html
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ <h1>Login</h1>
{% endfor %}<br>
</p>
<p>Password: {{form.password(size=80)}} </p>
<input type="submit" value="Sign In"></p>
<p>
<span><input type="submit" value="Sign In"></span>&nbsp;&nbsp;&nbsp;
<span><a href="{{ url_for('request_reset_password') }}">Reset Password</a></span>
</p>
</form>
{% endblock %}
16 changes: 16 additions & 0 deletions templates/request_password_reset.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!-- extend from base layout -->
{% extends "base.html" %}

{% block body %}
<h1>Reset Password</h1>
<form action="" method="post" name="reset_password">
{{form.hidden_tag()}}
<p>
Email: {{form.email(size=80)}}
{% for error in form.errors.email %}
<span style="color: red;">{{error}}</span>
{% endfor %}<br>
</p>
<input type="submit" value="Reset Password"></p>
</form>
{% endblock %}
13 changes: 13 additions & 0 deletions templates/reset_password.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!-- extend from base layout -->
{% extends "base.html" %}

{% block body %}
<h1>Reset Password</h1>
<form action="" method="post" name="request_reset_password">
{{form.hidden_tag()}}
<p>New password: {{form.password}} </p>
<p>Confirm new password: {{form.confirm}} </p>

<input type="submit" value="Reset Password"></p>
</form>
{% endblock %}
5 changes: 5 additions & 0 deletions templates/reset_password_email.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
Hello,

Click this link to reset your Metpetdb password: {{ reset_url }}

This link will be valid for 24 hours.

0 comments on commit 0eddd76

Please sign in to comment.