aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSam2013-10-15 18:17:02 -0500
committerSam2013-10-15 18:17:02 -0500
commit5b7d03c4af45a6e9b556368746d3ff04b6942a57 (patch)
treec8e1440ec7688af54560febcf22783b26c146fcd
parent612bc953cc82bee292a6a230b6604cc3070ea6d8 (diff)
downloadgenenetwork2-5b7d03c4af45a6e9b556368746d3ff04b6942a57.tar.gz
Password reset now works...but needs some error checking still
-rw-r--r--wqflask/wqflask/templates/new_security/password_reset.html2
-rw-r--r--wqflask/wqflask/user_manager.py191
-rw-r--r--wqflask/wqflask/views.py64
3 files changed, 154 insertions, 103 deletions
diff --git a/wqflask/wqflask/templates/new_security/password_reset.html b/wqflask/wqflask/templates/new_security/password_reset.html
index c66ddd07..cda1e477 100644
--- a/wqflask/wqflask/templates/new_security/password_reset.html
+++ b/wqflask/wqflask/templates/new_security/password_reset.html
@@ -29,8 +29,10 @@
<form class="form-horizontal" action="/n/password_reset_step2" data-validate="parsley"
method="POST" name="login_user_form">
+
<fieldset>
+ <input class="hidden" name="user_encode" value="{{ user_encode }}">
<div class="control-group">
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")
-
##########################################################################