Exemplo n.º 1
0
def tfa_init_verify_post_(request):
    # Extract parameters from the form
    verify_checkbox = 'verify' in request.params
    tfasecret = _get_totp_code_from_session()
    tfarecoverycodes = _get_recovery_codes_from_session()

    # Does the user want to proceed with enabling 2FA?
    if verify_checkbox and tfa.store_recovery_codes(request.userid,
                                                    tfarecoverycodes):
        # Strip any spaces from the TOTP code (some authenticators display the digits like '123 456')
        tfaresponse = request.params['tfaresponse'].replace(' ', '')

        # TOTP+2FA Secret validates (activate & redirect to status page)
        if tfa.activate(request.userid, tfasecret, tfaresponse):
            # Invalidate all other login sessions
            invalidate_other_sessions(request.userid)
            # Clean up the stored session variables
            _cleanup_session()
            raise HTTPSeeOther(location="/control/2fa/status")
        # TOTP+2FA Secret did not validate
        else:
            return Response(
                define.webpage(request.userid,
                               "control/2fa/init_verify.html",
                               [tfarecoverycodes.split(','), "2fa"],
                               title="Enable 2FA: Final Step"))
    # The user didn't check the verification checkbox (despite HTML5's client-side check); regenerate codes & redisplay
    elif not verify_checkbox:
        return Response(
            define.webpage(request.userid,
                           "control/2fa/init_verify.html",
                           [tfarecoverycodes.split(','), "verify"],
                           title="Enable 2FA: Final Step"))
Exemplo n.º 2
0
def tfa_generate_recovery_codes_verify_password_post_(request):
    userid, status = login.authenticate_bcrypt(define.get_display_name(request.userid),
                                               request.params['password'], request=None)
    # The user's password failed to authenticate
    if status == "invalid":
        return Response(define.webpage(
            request.userid,
            "control/2fa/generate_recovery_codes_verify_password.html",
            ["password"],
            title="Generate Recovery Codes: Verify Password"
        ))
    # The user has authenticated, so continue with generating the new recovery codes.
    else:
        # Edge case prevention: Stop the user from having two Weasyl sessions open and trying
        #   to proceed through the generation process with two sets of recovery codes.
        invalidate_other_sessions(request.userid)
        # Edge case prevention: Do we have existing (and recent) codes on this session? Prevent
        #   a user from confusing themselves if they visit the request page twice.
        sess = request.weasyl_session
        gen_rec_codes = True
        if '2fa_recovery_codes_timestamp' in sess.additional_data:
            # Are the codes on the current session < 30 minutes old?
            tstamp = sess.additional_data['2fa_recovery_codes_timestamp']
            if arrow.now().timestamp - tstamp < 1800:
                # We have recent codes on the session, use them instead of generating fresh codes.
                recovery_codes = sess.additional_data['2fa_recovery_codes'].split(',')
                gen_rec_codes = False
        if gen_rec_codes:
            # Either this is a fresh request to generate codes, or the timelimit was exceeded.
            recovery_codes = tfa.generate_recovery_codes()
            _set_recovery_codes_on_session(','.join(recovery_codes))
        return Response(define.webpage(request.userid, "control/2fa/generate_recovery_codes.html", [
            recovery_codes,
            None
        ], title="Generate Recovery Codes: Save New Recovery Codes"))
Exemplo n.º 3
0
def tfa_init_verify_post_(request):
    # Extract parameters from the form
    verify_checkbox = 'verify' in request.params
    tfasecret = _get_totp_code_from_session()
    tfaresponse = request.params['tfaresponse']
    tfarecoverycodes = _get_recovery_codes_from_session()

    # Does the user want to proceed with enabling 2FA?
    if verify_checkbox and tfa.store_recovery_codes(request.userid, tfarecoverycodes):
        # Strip any spaces from the TOTP code (some authenticators display the digits like '123 456')
        tfaresponse = request.params['tfaresponse'].replace(' ', '')

        # TOTP+2FA Secret validates (activate & redirect to status page)
        if tfa.activate(request.userid, tfasecret, tfaresponse):
            # Invalidate all other login sessions
            invalidate_other_sessions(request.userid)
            # Clean up the stored session variables
            _cleanup_session()
            raise HTTPSeeOther(location="/control/2fa/status")
        # TOTP+2FA Secret did not validate
        else:
            return Response(define.webpage(request.userid, "control/2fa/init_verify.html", [
                tfarecoverycodes.split(','),
                "2fa"
            ], title="Enable 2FA: Final Step"))
    # The user didn't check the verification checkbox (despite HTML5's client-side check); regenerate codes & redisplay
    elif not verify_checkbox:
        return Response(define.webpage(request.userid, "control/2fa/init_verify.html", [
            tfarecoverycodes.split(','),
            "verify"
        ], title="Enable 2FA: Final Step"))
Exemplo n.º 4
0
def tfa_generate_recovery_codes_verify_password_post_(request):
    userid, status = login.authenticate_bcrypt(define.get_display_name(request.userid),
                                               request.params['password'], request=None)
    # The user's password failed to authenticate
    if status == "invalid":
        return Response(define.webpage(
            request.userid,
            "control/2fa/generate_recovery_codes_verify_password.html",
            ["password"],
            title="Generate Recovery Codes: Verify Password"
        ))
    # The user has authenticated, so continue with generating the new recovery codes.
    else:
        # Edge case prevention: Stop the user from having two Weasyl sessions open and trying
        #   to proceed through the generation process with two sets of recovery codes.
        invalidate_other_sessions(request.userid)
        # Edge case prevention: Do we have existing (and recent) codes on this session? Prevent
        #   a user from confusing themselves if they visit the request page twice.
        sess = request.weasyl_session
        gen_rec_codes = True
        if '2fa_recovery_codes_timestamp' in sess.additional_data:
            # Are the codes on the current session < 30 minutes old?
            tstamp = sess.additional_data['2fa_recovery_codes_timestamp']
            if arrow.now().timestamp - tstamp < 1800:
                # We have recent codes on the session, use them instead of generating fresh codes.
                recovery_codes = sess.additional_data['2fa_recovery_codes'].split(',')
                gen_rec_codes = False
        if gen_rec_codes:
            # Either this is a fresh request to generate codes, or the timelimit was exceeded.
            recovery_codes = tfa.generate_recovery_codes()
            _set_recovery_codes_on_session(','.join(recovery_codes))
        return Response(define.webpage(request.userid, "control/2fa/generate_recovery_codes.html", [
            recovery_codes,
            None
        ], title="Generate Recovery Codes: Save New Recovery Codes"))
Exemplo n.º 5
0
def force_resetpassword_(request):
    if define.common_status_check(request.userid) != "resetpassword":
        return Response(define.errorpage(request.userid, errorcode.permission))

    form = request.web_input(password="", passcheck="")

    resetpassword.force(request.userid, form)

    # Invalidate all other user sessions for this user.
    profile.invalidate_other_sessions(request.userid)

    raise HTTPSeeOther(location="/", headers=request.response.headers)
Exemplo n.º 6
0
def resetpassword_post_(request):
    form = request.web_input(token="", username="", email="", day="", month="", year="", password="", passcheck="")

    resetpassword.reset(form)

    # Invalidate all other user sessions for this user.
    profile.invalidate_other_sessions(request.userid)

    return Response(define.errorpage(
        request.userid,
        "**Success!** Your password has been reset and you may now sign in to your account.",
        [["Sign In", "/signin"], ["Return to the Home Page", "/"]]))
Exemplo n.º 7
0
def force_resetpassword_(request):
    if define.common_status_check(request.userid) != "resetpassword":
        return Response(define.errorpage(request.userid, errorcode.permission))

    form = request.web_input(password="", passcheck="")

    resetpassword.force(request.userid, form)

    # Invalidate all other user sessions for this user.
    profile.invalidate_other_sessions(request.userid)

    raise HTTPSeeOther(location="/", headers=request.response.headers)
Exemplo n.º 8
0
def force_resetpassword_(request):
    if define.common_status_check(request.userid) != "resetpassword":
        raise WeasylError('InsufficientPermissions')

    form = request.web_input(password="", passcheck="")

    resetpassword.force(request.userid, form)

    # Invalidate all other user sessions for this user.
    profile.invalidate_other_sessions(request.userid)

    raise HTTPSeeOther(location="/", headers=request.response.headers)
Exemplo n.º 9
0
def resetpassword_post_(request):
    form = request.web_input(token="", username="", email="", day="", month="", year="", password="", passcheck="")

    resetpassword.reset(form)

    # Invalidate all other user sessions for this user.
    profile.invalidate_other_sessions(request.userid)

    return Response(define.errorpage(
        request.userid,
        "**Success!** Your password has been reset and you may now sign in to your account.",
        [["Sign In", "/signin"], ["Return to the Home Page", "/"]]))
Exemplo n.º 10
0
def resetpassword_post_(request):
    expect_userid = int(request.POST['userid'])

    resetpassword.reset(
        token=request.POST['token'],
        password=request.POST['password'],
        passcheck=request.POST['passcheck'],
        expect_userid=expect_userid,
        address=request.client_addr,
    )

    # Invalidate user sessions for this user.
    profile.invalidate_other_sessions(expect_userid)

    return Response(define.errorpage(
        request.userid,
        "**Success!** Your password has been reset and you may now sign in to your account.",
        [["Sign In", "/signin"], ["Return to the Home Page", "/"]]))