accounts.py 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. from hmac import new
  2. from unicodedata import category
  3. from flask import Blueprint, render_template, request, flash, redirect, url_for
  4. from flask_login import login_user, login_required, logout_user, current_user
  5. from werkzeug.security import generate_password_hash, check_password_hash
  6. from .models import User
  7. from . import db
  8. from .forms import LoginForm, RegForm, MFAForm, MFAForm2, SearchForm
  9. from app.lib import email
  10. # MFA
  11. import pyotp
  12. accounts = Blueprint('accounts', __name__)
  13. @accounts.route('/login', methods=['GET', 'POST'])
  14. def login():
  15. form = LoginForm()
  16. seform = SearchForm()
  17. if form.validate_on_submit():
  18. email = form.email.data
  19. challenge_passwd = form.passwd.data
  20. # Check fo user in User table
  21. user = User.query.filter_by(email=email).first()
  22. # If there's a user
  23. if user:
  24. if check_password_hash(user.password, challenge_passwd):
  25. return redirect(url_for('accounts.mfa', user_chal = user.id)) # passes user to mfa
  26. else:
  27. flash('Unsucessful Login!', category='error')
  28. else:
  29. flash('Unsucessful Login!', category='error')
  30. return render_template('login.html', user = current_user, form = form, seform = SearchForm())
  31. @accounts.route('/logout')
  32. @login_required
  33. def logout():
  34. logout_user()
  35. return redirect(url_for('accounts.login'))
  36. @accounts.route('/register', methods=['GET', 'POST'])
  37. def register():
  38. pass_list = list()
  39. form = RegForm()
  40. seform = SearchForm()
  41. if form.validate_on_submit():
  42. email = form.email.data
  43. username = form.username.data
  44. passwd_1 = form.passwd_1.data
  45. passwd_2 = form.passwd_2.data
  46. # Basic User Input Checks
  47. email_check = User.query.filter_by(email=email).first()
  48. if len(email) < 1:
  49. flash('Your Email must be longer than 0 characters.', category='error')
  50. elif email_check:
  51. flash('This Email is already taken', category='error')
  52. else:
  53. pass_list.append('p')
  54. if len(username) < 1:
  55. flash('Username must be something', category='error')
  56. else:
  57. pass_list.append('p')
  58. if len(passwd_1) < 8 or len(passwd_2) < 8:
  59. flash('Your Password must be longer than or equal to 8 characters.', category='error')
  60. else:
  61. if passwd_1 != passwd_2:
  62. flash('Your Passwords must match!', category='error')
  63. else:
  64. if len(pass_list) == 2:
  65. new_user = User(email=email,
  66. username=username,
  67. password=generate_password_hash(passwd_2, method='sha256')
  68. )
  69. db.session.add(new_user)
  70. db.session.commit()
  71. flash('Account Registration Successful!', category='success')
  72. return redirect(url_for('dashboards.market'))
  73. else:
  74. flash('Registration Failed', category='error')
  75. return render_template("register.html", user = current_user, form = form, seform = seform)
  76. @accounts.route('/mfa', methods=['GET', 'POST'])
  77. def mfa():
  78. form = MFAForm()
  79. form2 = MFAForm2()
  80. user_chal = request.args['user_chal']
  81. user = User.query.filter_by(id = user_chal).first()
  82. seform = SearchForm()
  83. # check for existing totphash
  84. if not user.totphash:
  85. # generate random secret key for auth
  86. secret = pyotp.random_base32()
  87. # add to User table and show this secret next time.
  88. dbcall = User.query.filter_by(id = user.id).first()
  89. dbcall.totphash = secret
  90. db.session.commit()
  91. flash('Generated new TOTP Secret', category='success')
  92. else: # use existing hash
  93. secret = user.totphash
  94. challenge_answer = int(pyotp.TOTP(secret).now())
  95. if form.validate_on_submit():
  96. otp = int(form.otp.data)
  97. # checks MFA
  98. if challenge_answer == otp:
  99. flash('Login Successful!', category='sucess')
  100. login_user(user, remember=True)
  101. return redirect(url_for('dashboards.market'))
  102. else:
  103. flash('Login Unsuccessful!', category='error')
  104. return redirect(url_for('accounts.mfa'))
  105. if form2.validate_on_submit():
  106. if form2.send_key.data:
  107. email.send_email(user.email, user.totphash)
  108. elif form2.reset_key.data:
  109. # generate random secret key for auth
  110. secret = pyotp.random_base32()
  111. # add to User table and show this secret next time.
  112. dbcall = User.query.filter_by(id = user.id).first()
  113. dbcall.totphash = secret
  114. db.session.commit()
  115. email.send_email(user.email, user.totphash)
  116. return render_template('mfa.html', secret = secret, form = form, user = user, seform = seform, form2 = form2)