user.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150
  1. from flask import (Blueprint, render_template, redirect, url_for,
  2. abort, flash)
  3. from flask.ext.login import login_user, logout_user, login_required
  4. from itsdangerous import URLSafeTimedSerializer
  5. from app import app, models, db
  6. from app.forms import user as user_forms
  7. from app.toolbox import email
  8. # Serializer for generating random tokens
  9. ts = URLSafeTimedSerializer(app.config['SECRET_KEY'])
  10. # Create a user blueprint
  11. userbp = Blueprint('userbp', __name__, url_prefix='/user')
  12. @userbp.route('/signup', methods=['GET', 'POST'])
  13. def signup():
  14. form = user_forms.SignUp()
  15. if form.validate_on_submit():
  16. # Create a user who hasn't validated his email address
  17. user = models.User(
  18. name=form.name.data,
  19. surname=form.surname.data,
  20. phone=form.phone.data,
  21. email=form.email.data,
  22. confirmation=False,
  23. password=form.password.data,
  24. )
  25. # Insert the user in the database
  26. db.session.add(user)
  27. db.session.commit()
  28. # Subject of the confirmation email
  29. subject = 'Please confirm your email address.'
  30. # Generate a random token
  31. token = ts.dumps(user.email, salt='email-confirm-key')
  32. # Build a confirm link with token
  33. confirmUrl = url_for('userbp.confirm', token=token, _external=True)
  34. # Render an HTML template to send by email
  35. html = render_template('email/confirm.html',
  36. confirm_url=confirmUrl)
  37. # Send the email to user
  38. email.send(user.email, subject, html)
  39. # Send back to the home page
  40. flash('Check your emails to confirm your email address.', 'positive')
  41. return redirect(url_for('index'))
  42. return render_template('user/signup.html', form=form, title='Sign up')
  43. @userbp.route('/confirm/<token>', methods=['GET', 'POST'])
  44. def confirm(token):
  45. try:
  46. email = ts.loads(token, salt='email-confirm-key', max_age=86400)
  47. # The token can either expire or be invalid
  48. except:
  49. abort(404)
  50. # Get the user from the database
  51. user = models.User.query.filter_by(email=email).first()
  52. # The user has confirmed his or her email address
  53. user.confirmation = True
  54. # Update the database with the user
  55. db.session.commit()
  56. # Send to the signin page
  57. flash(
  58. 'Your email address has been confirmed, you can sign in.', 'positive')
  59. return redirect(url_for('userbp.signin'))
  60. @userbp.route('/signin', methods=['GET', 'POST'])
  61. def signin():
  62. form = user_forms.Login()
  63. if form.validate_on_submit():
  64. user = models.User.query.filter_by(email=form.email.data).first()
  65. # Check the user exists
  66. if user is not None:
  67. # Check the password is correct
  68. if user.check_password(form.password.data):
  69. login_user(user)
  70. # Send back to the home page
  71. flash('Succesfully signed in.', 'positive')
  72. return redirect(url_for('index'))
  73. else:
  74. flash('The password you have entered is wrong.', 'negative')
  75. return redirect(url_for('userbp.signin'))
  76. else:
  77. flash('Unknown email address.', 'negative')
  78. return redirect(url_for('userbp.signin'))
  79. return render_template('user/signin.html', form=form, title='Sign in')
  80. @userbp.route('/signout')
  81. def signout():
  82. logout_user()
  83. flash('Succesfully signed out.', 'positive')
  84. return redirect(url_for('index'))
  85. @userbp.route('/account')
  86. @login_required
  87. def account():
  88. return render_template('user/account.html', title='Account')
  89. @userbp.route('/forgot', methods=['GET', 'POST'])
  90. def forgot():
  91. form = user_forms.Forgot()
  92. if form.validate_on_submit():
  93. user = models.User.query.filter_by(email=form.email.data).first()
  94. # Check the user exists
  95. if user is not None:
  96. # Subject of the confirmation email
  97. subject = 'Reset your password.'
  98. # Generate a random token
  99. token = ts.dumps(user.email, salt='password-reset-key')
  100. # Build a reset link with token
  101. resetUrl = url_for('userbp.reset', token=token, _external=True)
  102. # Render an HTML template to send by email
  103. html = render_template('email/reset.html', reset_url=resetUrl)
  104. # Send the email to user
  105. email.send(user.email, subject, html)
  106. # Send back to the home page
  107. flash('Check your emails to reset your password.', 'positive')
  108. return redirect(url_for('index'))
  109. else:
  110. flash('Unknown email address.', 'negative')
  111. return redirect(url_for('userbp.forgot'))
  112. return render_template('user/forgot.html', form=form)
  113. @userbp.route('/reset/<token>', methods=['GET', 'POST'])
  114. def reset(token):
  115. try:
  116. email = ts.loads(token, salt='password-reset-key', max_age=86400)
  117. # The token can either expire or be invalid
  118. except:
  119. abort(404)
  120. form = user_forms.Reset()
  121. if form.validate_on_submit():
  122. user = models.User.query.filter_by(email=email).first()
  123. # Check the user exists
  124. if user is not None:
  125. user.password = form.password.data
  126. # Update the database with the user
  127. db.session.commit()
  128. # Send to the signin page
  129. flash('Your password has been reset, you can sign in.', 'positive')
  130. return redirect(url_for('userbp.signin'))
  131. else:
  132. flash('Unknown email address.', 'negative')
  133. return redirect(url_for('userbp.forgot'))
  134. return render_template('user/reset.html', form=form, token=token)