Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what's changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
...
Checking mergeability… Don't worry, you can still create the pull request.
  • 1 commit
  • 2 files changed
  • 0 commit comments
  • 1 contributor
Showing with 3 additions and 148 deletions.
  1. +3 −118 app.py
  2. +0 −30 templates/user.html
View
121 app.py
@@ -1,17 +1,13 @@
import os
-import StringIO
-import urlparse
import bcrypt
from twilio.rest import TwilioRestClient
from flask.ext.login import LoginManager
from flask import Flask
-from flask import Response
from flask import request
from flask import redirect
from flask import url_for
from flask import render_template
-from flask import session
from flask.ext.login import login_user
from flask.ext.login import logout_user
from flask.ext.login import current_user
@@ -19,7 +15,6 @@
from pymongo import Connection
from konfig import Konfig
-from totp_auth import TotpAuth
app = Flask(__name__)
konf = Konfig()
@@ -43,13 +38,9 @@ def __init__(self, user_id):
self.id = user_id.lower()
self.db = connection.tfa.users
self.account = self.db.find_one({'uid': self.id})
- if self.account and 'totp_secret' in self.account:
- self.totp = TotpAuth(self.account['totp_secret'])
def create(self):
- auth = TotpAuth()
- self.db.insert({'uid': self.id,
- 'totp_secret': auth.secret})
+ self.db.insert({'uid': self.id})
self.account = self.db.find_one({'uid': self.id})
def save(self):
@@ -59,23 +50,6 @@ def password_valid(self, pwd):
pwd_hash = self.account['password_hash']
return bcrypt.hashpw(pwd, pwd_hash) == pwd_hash
- def send_sms(self, ok_to_send=False):
- if 'totp_enabled_via_sms' in self.account:
- ok_to_send = True
- if ok_to_send:
- token = self.totp.generate_token()
- msg = "Use this code to log in: %s" % token
- try:
- phone_number = self.account['phone_number']
- rv = twilio.sms.messages.create(to=phone_number,
- from_=konf.twilio_from_number,
- body=msg)
- except:
- return False
- if rv:
- return rv.status != 'failed'
- return False
-
# The methods below are required by flask-login
def is_authenticated(self):
"""Always return true - we don't do any account verification"""
@@ -100,22 +74,12 @@ def main_page():
if not user.account or not user.password_valid(request.form['password']):
opts['invalid_username_or_password'] = True
return render_template('main_page.html', opts=opts)
- totp_enabled = False
- for type in ['totp_enabled_via_app', 'totp_enabled_via_sms']:
- if type in user.account:
- totp_enabled = user.account[type]
- if totp_enabled:
- session['uid'] = user.get_id()
- session['stage'] = 'password-validated'
- return redirect(url_for('verify_tfa'))
- else:
- login_user(user)
- return redirect(url_for('user'))
+ login_user(user)
+ return redirect(url_for('user'))
@app.route("/sign-up", methods=['GET', 'POST'])
def sign_up():
- # FIXME: Test for the 'ideal case', render_template otherwise
opts = {}
if request.method == 'GET':
return render_template('sign_up.html', opts=opts)
@@ -134,85 +98,6 @@ def sign_up():
return redirect(url_for('user'))
-@app.route("/verify-tfa", methods=['GET', 'POST'])
-def verify_tfa():
- user = User(session['uid'])
- opts = {'user': user}
- if request.method == 'GET':
- opts['sms_sent'] = user.send_sms()
- return render_template('verify_tfa.html', opts=opts)
- if not session['uid']:
- opts['error-no-username'] = True
- return render_template('verify_tfa.html', opts=opts)
- if session['stage'] != 'password-validated':
- opts['error-unverified-password'] = True
- return render_template('verify_tfa.html', opts=opts)
- if user.totp.valid(request.form['token']):
- login_user(user)
- session['stage'] = 'logged-in'
- return redirect(url_for('user'))
- else:
- opts['error-invalid-token'] = True
- return render_template('verify_tfa.html', opts=opts)
-
-
-@app.route("/enable-tfa-via-app", methods=['GET', 'POST'])
-@login_required
-def enable_tfa_via_app():
- opts = {'user': current_user}
- if request.method == 'GET':
- return render_template('enable_tfa_via_app.html', opts=opts)
- token = request.form['token']
- if token and current_user.totp.valid(token):
- current_user.account['totp_enabled_via_app'] = True
- current_user.save()
- return render_template('enable_tfa_via_app.html', opts=opts)
- else:
- opts['token_error'] = True
- return render_template('enable_tfa_via_app.html', opts=opts)
-
-
-@app.route('/auth-qr-code.png')
-@login_required
-def auth_qr_code():
- """generate a QR code with the users TOTP secret
-
- We do this to reduce the risk of leaking
- the secret over the wire in plaintext"""
- #FIXME: This logic should really apply site-wide
- domain = urlparse.urlparse(request.url).netloc
- if not domain:
- domain = 'example.com'
- username = "%s@%s" % (current_user.id, domain)
- qrcode = current_user.totp.qrcode(username)
- stream = StringIO.StringIO()
- qrcode.save(stream)
- image = stream.getvalue()
- return Response(image, mimetype='image/png')
-
-
-@app.route("/enable-tfa-via-sms", methods=['GET', 'POST'])
-@login_required
-def enable_tfa_via_sms():
- opts = {'user': current_user}
- if request.method == 'GET':
- return render_template('enable_tfa_via_sms.html', opts=opts)
- if 'phone_number' in request.form and request.form['phone_number']:
- current_user.account['phone_number'] = request.form['phone_number']
- current_user.save()
- opts['sms_sent'] = current_user.send_sms(ok_to_send=True)
- opts['phone_number_updated'] = True
- return render_template('enable_tfa_via_sms.html', opts=opts)
- token = request.form['token']
- if token and current_user.totp.valid(token):
- current_user.account['totp_enabled_via_sms'] = True
- current_user.save()
- return render_template('enable_tfa_via_sms.html', opts=opts)
- else:
- opts['token_error'] = True
- return render_template('enable_tfa_via_sms.html', opts=opts)
-
-
@app.route("/user")
@login_required
def user():
View
30 templates/user.html
@@ -5,42 +5,12 @@
<h1>
You are logged in.
</h1>
- <p>
- Now that you are logged in, try adding your two factor auth to your account
- via an application or via SMS.
- </p>
</div>
<div class="row">
<div class="span6">
<!-- Source: http://openclipart.org/detail/176289/top-secret-by-joshbressers-176289 -->
<img src="/static/img/top-secret.png"/>
</div>
- <div class="span6">
- <a class="btn" href="/enable-tfa-via-app">
- Enable app based authentication
- </a>
- <div>
- <p>
- For apps like "Google Authenticator".
- {% if opts['user'].account['totp_enabled_via_app'] %}
- <br>
- (Enabled)
- {% endif %}
- </p>
- </div>
- <a class="btn" href="/enable-tfa-via-sms">
- Enable SMS based authentication
- </a>
- <div>
- <p>
- For any phone that can recieve SMS messages.
- {% if opts['user'].account['totp_enabled_via_sms'] %}
- <br>
- (Enabled for {{ opts['user'].account['phone_number'] }})
- {% endif %}
- </p>
- </div>
- </div>
</div>
</div>
{% endblock %}

No commit comments for this range

Something went wrong with that request. Please try again.