User experience updates for authentication.
modified: remarkbox/routes.py modified: remarkbox/templates/verification-challenge.j2 modified: remarkbox/views/authentication.py
This commit is contained in:
parent
9561b35942
commit
67ec8333d2
3 changed files with 17 additions and 123 deletions
|
|
@ -65,6 +65,8 @@ def includeme(config):
|
|||
|
||||
# embed routes:
|
||||
config.add_route("embed-join-or-log-in", "/embed/ns/{namespace}/join-or-log-in")
|
||||
config.add_route("embed-verification-challenge", "/embed/ns/{namespace}/verification-challenge")
|
||||
|
||||
config.add_route("embed-log-out", "/embed/ns/{namespace}/log-out")
|
||||
|
||||
config.add_route("embed-namespace-nodes", "/embed/ns/{namespace}/nodes")
|
||||
|
|
@ -96,7 +98,7 @@ def includeme(config):
|
|||
# basic routes:
|
||||
config.add_route("basic-join-or-log-in", "/join-or-log-in")
|
||||
|
||||
config.add_route("verification-challenge", "/verification-challenge")
|
||||
config.add_route("basic-verification-challenge", "/verification-challenge")
|
||||
|
||||
config.add_route("basic-namespace-nodes", "/ns/{namespace}/nodes")
|
||||
config.add_route("basic-namespace-settings", "/ns/{namespace}/settings")
|
||||
|
|
|
|||
|
|
@ -1,13 +1,12 @@
|
|||
{% extends request.base_funnel_template -%}
|
||||
{% block title %}verify code | {{ request.domain }}{% endblock -%}
|
||||
{% block content %}
|
||||
<section class="one-column">
|
||||
<section class="log-in-form well">
|
||||
<h2>Verification Code</h2>
|
||||
<b>Please enter code to log in.<b>
|
||||
<br>
|
||||
<br>
|
||||
<form method="post" action="/verification-challenge">
|
||||
<section class="join-or-log-in">
|
||||
<b>Verification Code</b>
|
||||
<br/>
|
||||
Please enter code to log in.
|
||||
<br/>
|
||||
<form method="post" action="{{ request.link_prefix }}/verification-challenge">
|
||||
<input
|
||||
name = "email"
|
||||
type = "hidden"
|
||||
|
|
@ -27,13 +26,11 @@
|
|||
required
|
||||
autofocus />
|
||||
|
||||
<br/>
|
||||
<br/>
|
||||
|
||||
<input type="submit" name="submit" id="submit" value="verify code" required />
|
||||
<p>
|
||||
<input type="submit" name="submit" id="submit" class="rb-submit red-button button-max-width send-log-in-email" value="verify code" required />
|
||||
<p/>
|
||||
|
||||
</form>
|
||||
<br/>
|
||||
</section>
|
||||
|
||||
</section>
|
||||
{%- endblock -%}
|
||||
|
|
|
|||
|
|
@ -22,112 +22,6 @@ def log_out(request):
|
|||
request.session["authenticated_user_id"] = None
|
||||
return HTTPFound(uri)
|
||||
|
||||
'''
|
||||
|
||||
# disable CSRF checking for iframe embedded version of this view.
|
||||
# If a client has 3rd party cookies disabled this security feature causes
|
||||
# more trouble then it helps, essentially blocking unauthenticated users.
|
||||
# disable CSRF checking for basic mode since we only set the
|
||||
# CSRF token for logged in users.
|
||||
@view_config(route_name="basic-join-or-log-in", renderer="join-or-log-in.j2", require_csrf=False)
|
||||
@view_config(route_name="embed-join-or-log-in", renderer="join-or-log-in.j2", require_csrf=False)
|
||||
def join_or_log_in(request):
|
||||
"""
|
||||
This view handles user registration, verification, and log in.
|
||||
It uses "password-less" authentication by sending OTP (one-time-password)
|
||||
links to the user's email address.
|
||||
"""
|
||||
_email_regex = re.compile("^[^@]+@[^@]+\.[^.@]+$")
|
||||
|
||||
# get the raw OTP (one-time-password) from posted parameters.
|
||||
raw_otp = request.params.get("raw-otp", "")
|
||||
|
||||
# get the email_id from posted parameters.
|
||||
email_id = request.params.get("email-id", "")
|
||||
|
||||
if email_id and _email_regex.match(email_id) is None:
|
||||
# posted email does not pass regex, set it to None.
|
||||
email_id = ""
|
||||
request.session.flash(("That email address is invalid.", "error"))
|
||||
|
||||
if request.spam:
|
||||
return request.spam
|
||||
|
||||
if request.user is not None:
|
||||
|
||||
if request.user.authenticated:
|
||||
# user already authenticated, return early.
|
||||
return HTTPFound(get_referer_or_home(request))
|
||||
|
||||
user = request.user
|
||||
|
||||
if raw_otp and user.check_password(raw_otp):
|
||||
# success: the user was verified.
|
||||
user.verified = True
|
||||
msg = ("Welcome {}".format(user.name), "success")
|
||||
request.session["authenticated_user_id"] = str(user.id)
|
||||
request.session.flash(msg)
|
||||
|
||||
# attempt to verify all nodes_pending_verify in user's session.
|
||||
verify_pending_nodes_in_session(request, user)
|
||||
|
||||
# Idempotent operation. Make certain a user has at least one reply_watcher.
|
||||
user.create_default_reply_watcher()
|
||||
|
||||
request.dbsession.add(user)
|
||||
request.dbsession.flush()
|
||||
|
||||
return HTTPFound("/")
|
||||
|
||||
if user.throttle_password():
|
||||
msg = (
|
||||
"We already sent a link to {}. Click it to log in.".format(user.email),
|
||||
"info",
|
||||
)
|
||||
|
||||
else:
|
||||
# generate a new one-time-password and save to database
|
||||
raw_otp = user.new_password()
|
||||
request.dbsession.add(user)
|
||||
request.dbsession.flush()
|
||||
|
||||
# email user the one-time-password and flash message.
|
||||
send_otp_email(request, user.email, raw_otp)
|
||||
|
||||
msg = (
|
||||
"We just sent a link to {}. Click it to log in.".format(user.email),
|
||||
"info",
|
||||
)
|
||||
|
||||
request.session.flash(msg)
|
||||
|
||||
if request.mode == "basic":
|
||||
return HTTPFound(return_to)
|
||||
|
||||
if request.mode == "embed":
|
||||
# determine if fragment is a valid node.id.
|
||||
if "#" in return_to:
|
||||
node = get_node_by_id(request.dbsession, return_to.split("#")[-1])
|
||||
if node is not None:
|
||||
if node.root.uri:
|
||||
return HTTPFound(
|
||||
get_embed_route_uri(request, node.root.uri.data, node.id)
|
||||
)
|
||||
|
||||
# determine if return_to is a valid uri in database.
|
||||
root = get_node_by_uri(request.dbsession, return_to.split("#")[0])
|
||||
if root is not None:
|
||||
# embeded external site, uses embed routes.
|
||||
return HTTPFound(get_embed_route_uri(request, root.uri.data))
|
||||
|
||||
return {
|
||||
# 'the_title' : 'join or log in',
|
||||
"title": "join or log in",
|
||||
"return_to": return_to,
|
||||
}
|
||||
|
||||
'''
|
||||
|
||||
|
||||
#@view_config(route_name="join-or-log-in", renderer="join-or-log-in.j2")
|
||||
@view_config(route_name="basic-join-or-log-in", renderer="join-or-log-in.j2", require_csrf=False)
|
||||
|
|
@ -184,14 +78,15 @@ def join_or_log_in(request):
|
|||
|
||||
request.session.flash(msg)
|
||||
|
||||
return HTTPFound("/verification-challenge?email={}".format(email))
|
||||
return HTTPFound("{}/verification-challenge?email={}".format(request.link_prefix, email))
|
||||
|
||||
return {
|
||||
"title": "join or log in",
|
||||
}
|
||||
|
||||
|
||||
@view_config(route_name="verification-challenge", renderer="verification-challenge.j2", require_csrf=False)
|
||||
@view_config(route_name="basic-verification-challenge", renderer="verification-challenge.j2", require_csrf=False)
|
||||
@view_config(route_name="embed-verification-challenge", renderer="verification-challenge.j2", require_csrf=False)
|
||||
def verification_challenge(request):
|
||||
|
||||
# get the raw OTP (one-time-password) from posted parameters.
|
||||
|
|
@ -222,7 +117,7 @@ def verification_challenge(request):
|
|||
request.dbsession.add(user)
|
||||
request.dbsession.flush()
|
||||
|
||||
#return HTTPFound("/")
|
||||
return HTTPFound("{}/u/settings".format(request.link_prefix))
|
||||
|
||||
else:
|
||||
msg = ("Invalid Verification Code", "error")
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue