|
@@ -0,0 +1,150 @@
|
|
|
|
|
+from flask import (Blueprint, render_template, redirect, url_for,
|
|
|
|
|
+ abort, flash)
|
|
|
|
|
+from flask.ext.login import login_user, logout_user, login_required
|
|
|
|
|
+from itsdangerous import URLSafeTimedSerializer
|
|
|
|
|
+from app import app, models, db
|
|
|
|
|
+from app.forms import user as user_forms
|
|
|
|
|
+from app.toolbox import email
|
|
|
|
|
+
|
|
|
|
|
+# Serializer for generating random tokens
|
|
|
|
|
+ts = URLSafeTimedSerializer(app.config['SECRET_KEY'])
|
|
|
|
|
+
|
|
|
|
|
+# Create a user blueprint
|
|
|
|
|
+user = Blueprint('user', __name__, url_prefix='/user')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/signup', methods=['GET', 'POST'])
|
|
|
|
|
+def signup():
|
|
|
|
|
+ form = user_forms.SignUp()
|
|
|
|
|
+ if form.validate_on_submit():
|
|
|
|
|
+ # Create a user who hasn't validated his email address
|
|
|
|
|
+ user = models.User(
|
|
|
|
|
+ name=form.name.data,
|
|
|
|
|
+ surname=form.surname.data,
|
|
|
|
|
+ phone=form.phone.data,
|
|
|
|
|
+ email=form.email.data,
|
|
|
|
|
+ confirmation=False,
|
|
|
|
|
+ password=form.password.data,
|
|
|
|
|
+ )
|
|
|
|
|
+ # Insert the user in the database
|
|
|
|
|
+ db.session.add(user)
|
|
|
|
|
+ db.session.commit()
|
|
|
|
|
+ # Subject of the confirmation email
|
|
|
|
|
+ subject = 'Please confirm your email address.'
|
|
|
|
|
+ # Generate a random token
|
|
|
|
|
+ token = ts.dumps(user.email, salt='email-confirm-key')
|
|
|
|
|
+ # Build a confirm link with token
|
|
|
|
|
+ confirmUrl = url_for('user.confirm', token=token, _external=True)
|
|
|
|
|
+ # Render an HTML template to send by email
|
|
|
|
|
+ html = render_template('email/confirm.html',
|
|
|
|
|
+ confirm_url=confirmUrl)
|
|
|
|
|
+ # Send the email to user
|
|
|
|
|
+ email.send(user.email, subject, html)
|
|
|
|
|
+ # Send back to the home page
|
|
|
|
|
+ flash('Check your emails to confirm your email address.', 'positive')
|
|
|
|
|
+ return redirect(url_for('index'))
|
|
|
|
|
+ return render_template('user/signup.html', form=form, title='Sign up')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/confirm/<token>', methods=['GET', 'POST'])
|
|
|
|
|
+def confirm(token):
|
|
|
|
|
+ try:
|
|
|
|
|
+ email = ts.loads(token, salt='email-confirm-key', max_age=86400)
|
|
|
|
|
+ # The token can either expire or be invalid
|
|
|
|
|
+ except:
|
|
|
|
|
+ abort(404)
|
|
|
|
|
+ # Get the user from the database
|
|
|
|
|
+ user = models.User.query.filter_by(email=email).first()
|
|
|
|
|
+ # The user has confirmed his or her email address
|
|
|
|
|
+ user.confirmation = True
|
|
|
|
|
+ # Update the database with the user
|
|
|
|
|
+ db.session.commit()
|
|
|
|
|
+ # Send to the signin page
|
|
|
|
|
+ flash(
|
|
|
|
|
+ 'Your email address has been confirmed, you can sign in.', 'positive')
|
|
|
|
|
+ return redirect(url_for('user.signin'))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/signin', methods=['GET', 'POST'])
|
|
|
|
|
+def signin():
|
|
|
|
|
+ form = user_forms.Login()
|
|
|
|
|
+ if form.validate_on_submit():
|
|
|
|
|
+ user = models.User.query.filter_by(email=form.email.data).first()
|
|
|
|
|
+ # Check the user exists
|
|
|
|
|
+ if user is not None:
|
|
|
|
|
+ # Check the password is correct
|
|
|
|
|
+ if user.check_password(form.password.data):
|
|
|
|
|
+ login_user(user)
|
|
|
|
|
+ # Send back to the home page
|
|
|
|
|
+ flash('Succesfully signed in.', 'positive')
|
|
|
|
|
+ return redirect(url_for('index'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ flash('The password you have entered is wrong.', 'negative')
|
|
|
|
|
+ return redirect(url_for('user.signin'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ flash('Unknown email address.', 'negative')
|
|
|
|
|
+ return redirect(url_for('user.signin'))
|
|
|
|
|
+ return render_template('user/signin.html', form=form, title='Sign in')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/signout')
|
|
|
|
|
+def signout():
|
|
|
|
|
+ logout_user()
|
|
|
|
|
+ flash('Succesfully signed out.', 'positive')
|
|
|
|
|
+ return redirect(url_for('index'))
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/account')
|
|
|
|
|
+@login_required
|
|
|
|
|
+def account():
|
|
|
|
|
+ return render_template('user/account.html', title='Account')
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/forgot', methods=['GET', 'POST'])
|
|
|
|
|
+def forgot():
|
|
|
|
|
+ form = user_forms.Forgot()
|
|
|
|
|
+ if form.validate_on_submit():
|
|
|
|
|
+ user = models.User.query.filter_by(email=form.email.data).first()
|
|
|
|
|
+ # Check the user exists
|
|
|
|
|
+ if user is not None:
|
|
|
|
|
+ # Subject of the confirmation email
|
|
|
|
|
+ subject = 'Reset your password.'
|
|
|
|
|
+ # Generate a random token
|
|
|
|
|
+ token = ts.dumps(user.email, salt='password-reset-key')
|
|
|
|
|
+ # Build a reset link with token
|
|
|
|
|
+ resetUrl = url_for('user.reset', token=token, _external=True)
|
|
|
|
|
+ # Render an HTML template to send by email
|
|
|
|
|
+ html = render_template('email/reset.html', reset_url=resetUrl)
|
|
|
|
|
+ # Send the email to user
|
|
|
|
|
+ email.send(user.email, subject, html)
|
|
|
|
|
+ # Send back to the home page
|
|
|
|
|
+ flash('Check your emails to reset your password.', 'positive')
|
|
|
|
|
+ return redirect(url_for('index'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ flash('Unknown email address.', 'negative')
|
|
|
|
|
+ return redirect(url_for('user.forgot'))
|
|
|
|
|
+ return render_template('user/forgot.html', form=form)
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+@user.route('/reset/<token>', methods=['GET', 'POST'])
|
|
|
|
|
+def reset(token):
|
|
|
|
|
+ try:
|
|
|
|
|
+ email = ts.loads(token, salt='password-reset-key', max_age=86400)
|
|
|
|
|
+ # The token can either expire or be invalid
|
|
|
|
|
+ except:
|
|
|
|
|
+ abort(404)
|
|
|
|
|
+ form = user_forms.Reset()
|
|
|
|
|
+ if form.validate_on_submit():
|
|
|
|
|
+ user = models.User.query.filter_by(email=email).first()
|
|
|
|
|
+ # Check the user exists
|
|
|
|
|
+ if user is not None:
|
|
|
|
|
+ user.password = form.password.data
|
|
|
|
|
+ # Update the database with the user
|
|
|
|
|
+ db.session.commit()
|
|
|
|
|
+ # Send to the signin page
|
|
|
|
|
+ flash('Your password has been reset, you can sign in.', 'positive')
|
|
|
|
|
+ return redirect(url_for('user.signin'))
|
|
|
|
|
+ else:
|
|
|
|
|
+ flash('Unknown email address.', 'negative')
|
|
|
|
|
+ return redirect(url_for('user.forgot'))
|
|
|
|
|
+ return render_template('user/reset.html', form=form, token=token)
|