accounts.py 5.0 KB

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