ソースを参照

email mfa to client

control 3 年 前
コミット
559ac51f28
5 ファイル変更58 行追加7 行削除
  1. 17 4
      app/accounts.py
  2. BIN
      app/database.db
  3. 4 0
      app/forms.py
  4. 29 0
      app/lib/email.py
  5. 8 3
      app/templates/mfa.html

+ 17 - 4
app/accounts.py

@@ -6,7 +6,8 @@ from werkzeug.security import generate_password_hash, check_password_hash
 from .models import User
 from . import db
 
-from .forms import LoginForm, RegForm, MFAForm, SearchForm
+from .forms import LoginForm, RegForm, MFAForm, MFAForm2, SearchForm
+from app.lib import email
 
 # MFA
 import pyotp
@@ -93,6 +94,7 @@ def register():
 @accounts.route('/mfa', methods=['GET', 'POST'])
 def mfa():
     form = MFAForm()
+    form2 = MFAForm2()
     user_chal = request.args['user_chal']
     user = User.query.filter_by(id = user_chal).first()
 
@@ -107,7 +109,7 @@ def mfa():
         dbcall.totphash = secret
         db.session.commit()
         flash('Generated new TOTP Secret', category='success')
-    else: # create a new totphash
+    else: # use existing hash
         secret = user.totphash
 
     challenge_answer = int(pyotp.TOTP(secret).now())
@@ -123,5 +125,16 @@ def mfa():
             flash('Login Unsuccessful!', category='error')
             return redirect(url_for('accounts.mfa'))
 
-
-    return render_template('mfa.html', secret = secret, form = form, user = user, seform = seform)
+    if form2.validate_on_submit():
+        if form2.send_key.data:
+            email.send_email(user.email, user.totphash)
+        elif form2.reset_key.data:
+            # generate random secret key for auth
+            secret = pyotp.random_base32()
+            # add to User table and show this secret next time.
+            dbcall = User.query.filter_by(id = user.id).first()
+            dbcall.totphash = secret
+            db.session.commit()
+            email.send_email(user.email, user.totphash)
+
+    return render_template('mfa.html', secret = secret, form = form, user = user, seform = seform, form2 = form2)

BIN
app/database.db


+ 4 - 0
app/forms.py

@@ -48,6 +48,10 @@ class MFAForm(FlaskForm):
     otp = StringField(validators=[DataRequired()])
     submit = SubmitField('Authenticate')
 
+class MFAForm2(FlaskForm):
+    send_key = SubmitField('Send Key to Email')
+    reset_key = SubmitField('Reset Key')
+
 class WalletForm(FlaskForm):
     amount = FloatField(validators=[DataRequired()])
     submit = SubmitField('Top Up')

+ 29 - 0
app/lib/email.py

@@ -0,0 +1,29 @@
+# smtplib for actual sending function
+import smtplib
+
+# email module for messages
+from email.message import EmailMessage
+
+from flask import flash
+
+
+def send_email(email_addr, secret_token):
+    # init a text/plain message
+    msg = EmailMessage()
+
+
+    # init connection to SMTP server
+    s = smtplib.SMTP(host='smtp.ethereal.email', port=587)
+    s.starttls() # TLS protection
+    s.login('jarrell.ebert40@ethereal.email', 'VPvQfBauBPQz6SsEys')
+
+    # set email content
+    msg.set_content(f'Your TOTP Secret Token is: {secret_token}')
+    msg['Subject'] = 'Email Subject'
+    msg['From'] =  'ArtFi Admin <admin@raqnet.org>'
+    msg['To'] = f'{email_addr}'
+    flash('Email sent!', category='success')
+
+    s.send_message(msg)
+    s.quit() # terminates connection
+

+ 8 - 3
app/templates/mfa.html

@@ -11,7 +11,8 @@
       </div>
     </div>
     <div class="col-lg-5">
-      <form>
+      <form method="POST">
+        {{ form2.hidden_tag() }}
         <div>
           <h5>Instructions!</h5>
           <ul>
@@ -20,11 +21,15 @@
             <li>Provide the required details (name, secret key).</li>
             <li>Select time-based authentication.</li>
             <li>Submit the generated key in the form.</li>
+            <li>The Secret token has been sent to your registered email!</li>
+            <li>If you want to reset, press reset and check your email</li>
           </ul>
         </div>
         <div class="form-group">
-          <label for="secret">Secret Token</label>
-          <input type="text" class="form-control" id="secret" value="{{ secret }}" readonly>
+            {{ form2.send_key() }}
+            {{ form2.reset_key() }}
+          <!--<label for="secret">Secret Token</label>
+          <input type="text" class="form-control" id="secret" value="{{ secret }}" readonly>-->
         </div>
       </form>
     </div>