Exemple #1
0
def test_2fa_changes_token(app):
    user = db_utils.create_user(username='******', password='******')

    resp = app.get('/')
    csrf = resp.html.find('html')['data-csrf-token']

    assert tfa.store_recovery_codes(user,
                                    ','.join(tfa.generate_recovery_codes()))
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)
    tfa_response = totp.now()
    assert tfa.activate(user, tfa_secret, tfa_response)

    old_cookie = app.cookies['WZL']
    resp = app.post('/signin', {
        'token': csrf,
        'username': '******',
        'password': '******'
    })
    new_csrf = resp.html.find('html')['data-csrf-token']
    assert app.cookies['WZL'] != old_cookie
    assert new_csrf != csrf
    assert not d.engine.scalar(
        "SELECT EXISTS (SELECT 0 FROM sessions WHERE userid = %(user)s)",
        user=user)
    assert d.engine.scalar(
        "SELECT EXISTS (SELECT 0 FROM sessions WHERE additional_data->'2fa_pwd_auth_userid' = %(user)s::text)",
        user=user)
Exemple #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"))
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"))
Exemple #4
0
def test_2fa_changes_token(app):
    user = db_utils.create_user(username='******', password='******')

    resp = app.get('/')
    csrf = resp.html.find('html')['data-csrf-token']

    assert tfa.store_recovery_codes(user, ','.join(tfa.generate_recovery_codes()))
    tfa_secret = pyotp.random_base32()
    totp = pyotp.TOTP(tfa_secret)
    tfa_response = totp.now()
    assert tfa.activate(user, tfa_secret, tfa_response)

    old_cookie = app.cookies['WZL']
    resp = app.post('/signin', {'token': csrf, 'username': '******', 'password': '******'})
    new_csrf = resp.html.find('html')['data-csrf-token']
    assert app.cookies['WZL'] != old_cookie
    assert new_csrf != csrf
    assert not d.engine.scalar("SELECT EXISTS (SELECT 0 FROM sessions WHERE userid = %(user)s)", user=user)
    assert d.engine.scalar("SELECT EXISTS (SELECT 0 FROM sessions WHERE additional_data->'2fa_pwd_auth_userid' = %(user)s::text)", user=user)
Exemple #5
0
def test_generate_recovery_codes():
    codes = tfa.generate_recovery_codes()
    assert len(codes) == 10
    for code in codes:
        assert len(code) == tfa.LENGTH_RECOVERY_CODE
def test_generate_recovery_codes():
    codes = tfa.generate_recovery_codes()
    assert len(codes) == 10
    for code in codes:
        assert len(code) == tfa.LENGTH_RECOVERY_CODE