diff --git a/wqflask/wqflask/user_manager.py b/wqflask/wqflask/user_manager.py
index 1df2c153..766f49df 100644
--- a/wqflask/wqflask/user_manager.py
+++ b/wqflask/wqflask/user_manager.py
@@ -17,6 +17,8 @@ import hashlib
import hmac
import base64
+import urlparse
+
import simplejson as json
from sqlalchemy import orm
@@ -140,7 +142,7 @@ class RegisterUser(object):
print("No errors!")
- self.set_password(password)
+ set_password(password, user)
self.user.registration_info = json.dumps(basic_info(), sort_keys=True)
@@ -156,48 +158,49 @@ class RegisterUser(object):
self.thank_you_mode = True
- def set_password(self, password):
- pwfields = Bunch()
+def set_password(password, user):
+ pwfields = Bunch()
+
+ pwfields.algorithm = "pbkdf2"
+ pwfields.hashfunc = "sha256"
+ #hashfunc = getattr(hashlib, pwfields.hashfunc)
- pwfields.algorithm = "pbkdf2"
- pwfields.hashfunc = "sha256"
- #hashfunc = getattr(hashlib, pwfields.hashfunc)
+ # Encoding it to base64 makes storing it in json much easier
+ pwfields.salt = base64.b64encode(os.urandom(32))
- # Encoding it to base64 makes storing it in json much easier
- pwfields.salt = base64.b64encode(os.urandom(32))
+ # https://forums.lastpass.com/viewtopic.php?t=84104
+ pwfields.iterations = 100000
+ pwfields.keylength = 32
- # https://forums.lastpass.com/viewtopic.php?t=84104
- pwfields.iterations = 100000
- pwfields.keylength = 32
+ pwfields.created_ts = timestamp()
+ # One more check on password length
+ assert len(password) >= 6, "Password shouldn't be so short here"
- pwfields.created_ts = timestamp()
- # One more check on password length
- assert len(password) >= 6, "Password shouldn't be so short here"
+ print("pwfields:", vars(pwfields))
+ print("locals:", locals())
- print("pwfields:", vars(pwfields))
- print("locals:", locals())
+ enc_password = Password(password,
+ pwfields.salt,
+ pwfields.iterations,
+ pwfields.keylength,
+ pwfields.hashfunc)
- enc_password = Password(password,
- pwfields.salt,
- pwfields.iterations,
- pwfields.keylength,
- pwfields.hashfunc)
+ pwfields.password = enc_password.password
+ pwfields.encrypt_time = enc_password.encrypt_time
- pwfields.password = enc_password.password
- pwfields.encrypt_time = enc_password.encrypt_time
+ user.password = json.dumps(pwfields.__dict__,
+ sort_keys=True,
+ )
- self.user.password = json.dumps(pwfields.__dict__,
- sort_keys=True,
- )
class VerificationEmail(object):
template_name = "email/verification.txt"
- key_preface = "verification_code"
+ key_prefix = "verification_code"
subject = "GeneNetwork email verification"
def __init__(self, user):
verification_code = str(uuid.uuid4())
- key = self.key_preface + "verification_code:" + verification_code
+ key = self.key_prefix + ":" + verification_code
data = json.dumps(dict(id=user.id,
timestamp=timestamp())
@@ -214,7 +217,7 @@ class VerificationEmail(object):
class ForgotPasswordEmail(VerificationEmail):
template_name = "email/forgot_password.txt"
- key_preface = "forgot_password_code"
+ key_prefix = "forgot_password_code"
subject = "GeneNetwork password reset"
@@ -239,16 +242,71 @@ def basic_info():
@app.route("/manage/verify_email")
def verify_email():
- print("in verify_email request.url is:", request.url)
- verify_url_hmac(request.url)
- verification_code = request.args['code']
- data = Redis.get("verification_code:" + verification_code)
- data = json.loads(data)
- print("data is:", data)
- user = model.User.query.get(data['id'])
+ user = DecodeUser(VerificationEmail.key_prefix).user
user.confirmed = json.dumps(basic_info(), sort_keys=True)
db_session.commit()
+@app.route("/n/password_reset")
+def password_reset():
+ print("in password_reset request.url is:", request.url)
+
+ # We do this mainly just to assert that it's in proper form for displaying next page
+ # Really not necessary but doesn't hurt
+ user_encode = DecodeUser(ForgotPasswordEmail.key_prefix).reencode_standalone()
+
+ return render_template("new_security/password_reset.html", user_encode=user_encode)
+
+@app.route("/n/password_reset_step2", methods=('POST',))
+def password_reset_step2():
+ print("in password_reset request.url is:", request.url)
+
+ errors = []
+
+ user_encode = request.form['user_encode']
+ verification_code, separator, hmac = user_encode.partition(':')
+
+ hmac_verified = actual_hmac_creation(verification_code)
+ print("locals are:", locals())
+
+
+ assert hmac == hmac_verified, "Someone has been naughty"
+
+ user = DecodeUser.actual_get_user(ForgotPasswordEmail.key_prefix, verification_code)
+ print("user is:", user)
+
+ password = request.form['password']
+
+ set_password(password, user)
+ db_session.commit()
+
+ flash("Password changed successfully. You can now sign in.", "alert-info")
+ response = make_response(redirect(url_for('login')))
+
+ return response
+
+class DecodeUser(object):
+
+ def __init__(self, code_prefix):
+ verify_url_hmac(request.url)
+
+ #params = urlparse.parse_qs(url)
+
+ self.verification_code = request.args['code']
+ self.user = self.actual_get_user(code_prefix, self.verification_code)
+
+ def reencode_standalone(self):
+ hmac = actual_hmac_creation(self.verification_code)
+ return self.verification_code + ":" + hmac
+
+ @staticmethod
+ def actual_get_user(code_prefix, verification_code):
+ data = Redis.get(code_prefix + ":" + verification_code)
+ print("in get_coded_user, data is:", data)
+ data = json.loads(data)
+ print("data is:", data)
+ return model.User.query.get(data['id'])
+
+@app.route("/n/login", methods=('GET', 'POST'))
def login():
params = request.form if request.form else request.args
print("in login params are:", params)
@@ -282,7 +340,7 @@ def login():
user_id = user.id,
user_email_address = user.email_address)
- flash("Thank you for logging in.", "alert-success")
+ flash("Thank you for logging in {}.".format(user.full_name), "alert-success")
key = "session_id:" + login_rec.session_id
print("Key when signing:", key)
@@ -324,10 +382,63 @@ def forgot_password_submit():
email_address))
return redirect(url_for("login"))
ForgotPasswordEmail(user)
+ return render_template("new_security/forgot_password_step2.html",
+ subject=ForgotPasswordEmail.subject)
+
+
+
+@app.route("/manage/users")
+def manage_users():
+ template_vars = UsersManager()
+ return render_template("admin/user_manager.html", **template_vars.__dict__)
+
+@app.route("/manage/user")
+def manage_user():
+ template_vars = UserManager(request.args)
+ return render_template("admin/ind_user_manager.html", **template_vars.__dict__)
+
+@app.route("/manage/groups")
+def manage_groups():
+ template_vars = GroupsManager(request.args)
+ return render_template("admin/group_manager.html", **template_vars.__dict__)
+
+
+@app.route("/n/register", methods=('GET', 'POST'))
+def register():
+ params = None
+ errors = None
+
+ #if request.form:
+ # params = request.form
+ #else:
+ # params = request.args
+
+ params = request.form if request.form else request.args
+
+ if params:
+ print("Attempting to register the user...")
+ result = RegisterUser(params)
+ errors = result.errors
+
+ if result.thank_you_mode:
+ assert not errors, "Errors while in thank you mode? That seems wrong..."
+ return render_template("new_security/registered.html",
+ subject=VerificationEmail.subject)
+
+ return render_template("new_security/register_user.html", values=params, errors=errors)
+
+
+
+
+#@app.route("/n/login", methods=('GET', 'POST'))
+#def login():
+# return user_manager.login()
+#
+#@app.route("/manage/verify")
+#def verify():
+# user_manager.verify_email()
+# return render_template("new_security/verified.html")
-@app.route("/n/password_reset")
-def password_reset():
- pass
################################# Sign and unsign #####################################
diff --git a/wqflask/wqflask/views.py b/wqflask/wqflask/views.py
index deccf459..a060ba3c 100644
--- a/wqflask/wqflask/views.py
+++ b/wqflask/wqflask/views.py
@@ -51,7 +51,7 @@ from wqflask import user_manager
@app.before_request
def connect_db():
g.db = sqlalchemy.create_engine(app.config['DB_URI'])
-
+
#@app.before_request
#def trace_it():
# from wqflask import tracer
@@ -277,68 +277,6 @@ def get_temp_data():
###################################################################################################
-@app.route("/manage/users")
-def manage_users():
- template_vars = user_manager.UsersManager()
- return render_template("admin/user_manager.html", **template_vars.__dict__)
-
-@app.route("/manage/user")
-def manage_user():
- template_vars = user_manager.UserManager(request.args)
- return render_template("admin/ind_user_manager.html", **template_vars.__dict__)
-
-@app.route("/manage/groups")
-def manage_groups():
- template_vars = user_manager.GroupsManager(request.args)
- return render_template("admin/group_manager.html", **template_vars.__dict__)
-
-
-@app.route("/n/register", methods=('GET', 'POST'))
-def register():
- params = None
- errors = None
-
- #if request.form:
- # params = request.form
- #else:
- # params = request.args
-
- params = request.form if request.form else request.args
-
- if params:
- print("Attempting to register the user...")
- result = user_manager.RegisterUser(params)
- errors = result.errors
-
- if result.thank_you_mode:
- assert not errors, "Errors while in thank you mode? That seems wrong..."
- return render_template("new_security/registered.html")
-
- return render_template("new_security/register_user.html", values=params, errors=errors)
-
-#@app.route("/n/register_submit", methods=('POST',))
-#def register_submit():
-# print("request.args are: ", request.args)
-# result = user_manager.RegisterUser(request.form)
-# if result.errors:
-# print("Redirecting")
-# # 307 preserves the post on the redirect (maybe)
-# errors = result.errors
-# #errors = json.dumps(errors)
-# print("request.args are: ", request.args)
-# return render_template("new_security/register_user.html", errors=errors, values=request.form)
-# #return redirect(url_for('new_register', errors=errors), code=307)
-
-
-@app.route("/n/login", methods=('GET', 'POST'))
-def login():
- return user_manager.login()
-
-@app.route("/manage/verify")
-def verify():
- user_manager.verify_email()
- return render_template("new_security/verified.html")
-
##########################################################################
--
cgit v1.2.3
From ad94850e0916346af8cdb72c77f4ef7889d6ee95 Mon Sep 17 00:00:00 2001
From: Sam
Date: Wed, 16 Oct 2013 17:49:38 -0500
Subject: security code cleanup
---
.../new_security/forgot_password_step2.html | 11 +---
.../wqflask/templates/new_security/registered.html | 13 +---
.../wqflask/templates/new_security/thank_you.html | 18 ++----
.../wqflask/templates/new_security/verified.html | 32 ---------
wqflask/wqflask/templates/security/_macros.html | 39 -----------
wqflask/wqflask/templates/security/_menu.html | 15 -----
wqflask/wqflask/templates/security/_messages.html | 9 ---
wqflask/wqflask/templates/security/_scripts.html | 3 -
.../templates/security/change_password.html | 11 ----
.../templates/security/email/change_notice.html | 4 --
.../templates/security/email/change_notice.txt | 5 --
.../security/email/confirmation_instructions.html | 5 --
.../security/email/confirmation_instructions.txt | 5 --
.../security/email/login_instructions.html | 5 --
.../security/email/login_instructions.txt | 5 --
.../security/email/reset_instructions.html | 1 -
.../security/email/reset_instructions.txt | 3 -
.../templates/security/email/reset_notice.html | 1 -
.../templates/security/email/reset_notice.txt | 1 -
.../wqflask/templates/security/email/welcome.html | 9 ---
.../wqflask/templates/security/email/welcome.txt | 9 ---
.../templates/security/forgot_password.html | 9 ---
wqflask/wqflask/templates/security/login_user.html | 72 ---------------------
.../wqflask/templates/security/register_user.html | 75 ----------------------
.../wqflask/templates/security/reset_password.html | 15 -----
.../templates/security/send_confirmation.html | 34 ----------
wqflask/wqflask/templates/security/send_login.html | 9 ---
wqflask/wqflask/templates/security/thank_you.html | 8 ---
wqflask/wqflask/user_manager.py | 37 ++++-------
29 files changed, 23 insertions(+), 440 deletions(-)
delete mode 100644 wqflask/wqflask/templates/new_security/verified.html
delete mode 100644 wqflask/wqflask/templates/security/_macros.html
delete mode 100644 wqflask/wqflask/templates/security/_menu.html
delete mode 100644 wqflask/wqflask/templates/security/_messages.html
delete mode 100644 wqflask/wqflask/templates/security/_scripts.html
delete mode 100644 wqflask/wqflask/templates/security/change_password.html
delete mode 100644 wqflask/wqflask/templates/security/email/change_notice.html
delete mode 100644 wqflask/wqflask/templates/security/email/change_notice.txt
delete mode 100644 wqflask/wqflask/templates/security/email/confirmation_instructions.html
delete mode 100644 wqflask/wqflask/templates/security/email/confirmation_instructions.txt
delete mode 100644 wqflask/wqflask/templates/security/email/login_instructions.html
delete mode 100644 wqflask/wqflask/templates/security/email/login_instructions.txt
delete mode 100644 wqflask/wqflask/templates/security/email/reset_instructions.html
delete mode 100644 wqflask/wqflask/templates/security/email/reset_instructions.txt
delete mode 100644 wqflask/wqflask/templates/security/email/reset_notice.html
delete mode 100644 wqflask/wqflask/templates/security/email/reset_notice.txt
delete mode 100644 wqflask/wqflask/templates/security/email/welcome.html
delete mode 100644 wqflask/wqflask/templates/security/email/welcome.txt
delete mode 100644 wqflask/wqflask/templates/security/forgot_password.html
delete mode 100644 wqflask/wqflask/templates/security/login_user.html
delete mode 100644 wqflask/wqflask/templates/security/register_user.html
delete mode 100644 wqflask/wqflask/templates/security/reset_password.html
delete mode 100644 wqflask/wqflask/templates/security/send_confirmation.html
delete mode 100644 wqflask/wqflask/templates/security/send_login.html
delete mode 100644 wqflask/wqflask/templates/security/thank_you.html
diff --git a/wqflask/wqflask/templates/new_security/forgot_password_step2.html b/wqflask/wqflask/templates/new_security/forgot_password_step2.html
index 1295e589..888dcad4 100644
--- a/wqflask/wqflask/templates/new_security/forgot_password_step2.html
+++ b/wqflask/wqflask/templates/new_security/forgot_password_step2.html
@@ -1,14 +1,9 @@
{% extends "base.html" %}
{% block title %}Register{% endblock %}
{% block content %}
-
-
-
Password Reset
-
- Check your email.
-
-
-
+
+ {{ header("Password Reset", "Check your email.") }}
+