Exemplo n.º 1
0
def test_verify_success_if_correct_information_supplied():
    # Subtests:
    #  a) Verify 'authbcrypt' table has new hash
    #  b) Verify 'forgotpassword' row is removed.
    #  > Requirement: Get token set from request()
    user_id = db_utils.create_user(email_addr=email_addr, username=user_name)
    password = '******'
    form_for_request = Bag(email=email_addr,
                           username=user_name,
                           day=arrow.now().day,
                           month=arrow.now().month,
                           year=arrow.now().year)
    resetpassword.request(form_for_request)
    pw_reset_token = d.engine.scalar(
        "SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    # Force update link_time (required)
    resetpassword.prepare(pw_reset_token)
    form = Bag(email=email_addr,
               username=user_name,
               day=arrow.now().day,
               month=arrow.now().month,
               year=arrow.now().year,
               token=pw_reset_token,
               password=password,
               passcheck=password)
    resetpassword.reset(form)
    # 'forgotpassword' row should not exist after a successful reset
    row_does_not_exist = d.engine.execute(
        "SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    assert row_does_not_exist.first() is None
    bcrypt_hash = d.engine.scalar(
        "SELECT hashsum FROM authbcrypt WHERE userid = %(id)s", id=user_id)
    assert bcrypt.checkpw(password.encode('utf-8'),
                          bcrypt_hash.encode('utf-8'))
Exemplo n.º 2
0
def test_emailIncorrect_WeasylError_if_email_address_doesnt_match_stored_email(
):
    # Two parts: Set forgot password record; attempt reset with incorrect email
    #  Requirement: Get token set from request()
    user_id = db_utils.create_user(email_addr=email_addr, username=user_name)
    password = '******'
    form_for_request = Bag(email=email_addr,
                           username=user_name,
                           day=arrow.now().day,
                           month=arrow.now().month,
                           year=arrow.now().year)
    resetpassword.request(form_for_request)
    pw_reset_token = d.engine.scalar(
        "SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    # Force update link_time (required)
    resetpassword.prepare(pw_reset_token)
    email_addr_mismatch = "*****@*****.**"
    form_for_reset = Bag(email=email_addr_mismatch,
                         username=user_name,
                         day=arrow.now().day,
                         month=arrow.now().month,
                         year=arrow.now().year,
                         token=pw_reset_token,
                         password=password,
                         passcheck=password)
    with pytest.raises(WeasylError) as err:
        resetpassword.reset(form_for_reset)
    assert 'emailIncorrect' == err.value.value
Exemplo n.º 3
0
def test_password_reset_fails_if_attempted_from_different_ip_address():
    # Two parts: Set forgot password record; attempt reset with incorrect IP Address in forgotpassword table vs. requesting IP
    #  Requirement: Get token set from request()
    user_id = db_utils.create_user(email_addr=email_addr, username=user_name)
    password = '******'
    form_for_request = Bag(email=email_addr,
                           username=user_name,
                           day=arrow.now().day,
                           month=arrow.now().month,
                           year=arrow.now().year)
    resetpassword.request(form_for_request)
    pw_reset_token = d.engine.scalar(
        "SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    # Change IP detected when request was made (required for test)
    d.engine.execute(
        "UPDATE forgotpassword SET address = %(addr)s WHERE token = %(token)s",
        addr="127.42.42.42",
        token=pw_reset_token)
    # Force update link_time (required)
    resetpassword.prepare(pw_reset_token)
    form_for_reset = Bag(email=email_addr,
                         username=user_name,
                         day=arrow.now().day,
                         month=arrow.now().month,
                         year=arrow.now().year,
                         token=pw_reset_token,
                         password=password,
                         passcheck=password)
    with pytest.raises(WeasylError) as err:
        resetpassword.reset(form_for_reset)
    assert 'addressInvalid' == err.value.value
Exemplo n.º 4
0
def test_stale_records_get_deleted_when_function_is_called():
    token_store = []
    for i in range(20):
        user_name = "testPrepare%d" % (i, )
        email_addr = "*****@*****.**" % (i, )
        user_id = db_utils.create_user(email_addr=email_addr,
                                       username=user_name)
        form_for_request = Bag(email=email_addr,
                               username=user_name,
                               day=arrow.now().day,
                               month=arrow.now().month,
                               year=arrow.now().year)
        resetpassword.request(form_for_request)
        pw_reset_token = d.engine.scalar(
            "SELECT token FROM forgotpassword WHERE userid = %(id)s",
            id=user_id)
        token_store.append(pw_reset_token)
    # All tokens should exist at this point
    for i in range(20):
        assert resetpassword.checktoken(token_store[i])
    # Set 5 tokens to be two hours old (0,5) (7200)
    for i in range(0, 5):
        d.engine.execute(
            "UPDATE forgotpassword SET set_time = %(time)s WHERE token = %(token)s",
            time=d.get_time() - 7200,
            token=token_store[i])
    # Set 5 tokens to be 30 minutes old (5,10) (1800)
    for i in range(5, 10):
        d.engine.execute(
            "UPDATE forgotpassword SET set_time = %(time)s WHERE token = %(token)s",
            time=d.get_time() - 1800,
            token=token_store[i])
    # Set 5 tokens to be 10 minutes old for the last visit time (10,15) (600)
    for i in range(10, 15):
        d.engine.execute(
            "UPDATE forgotpassword SET link_time = %(time)s WHERE token = %(token)s",
            time=d.get_time() - 600,
            token=token_store[i])
    # Set 5 tokens to be 2 minutes old for the last visit time (10,15) (120)
    for i in range(15, 20):
        d.engine.execute(
            "UPDATE forgotpassword SET link_time = %(time)s WHERE token = %(token)s",
            time=d.get_time() - 120,
            token=token_store[i])
    # This should clear all tokens >1hr old, and all tokens >5 minutes from last visit (10 total)
    resetpassword.prepare('foo')
    # This range should be cleared (set_time > 3600)
    for i in range(0, 5):
        assert not resetpassword.checktoken(token_store[i])
    # This range should still be present (set_time < 3600)
    for i in range(5, 10):
        assert resetpassword.checktoken(token_store[i])
    # This range should be cleared (link_time > 300)
    for i in range(10, 15):
        assert not resetpassword.checktoken(token_store[i])
    # This range should still be present (link_time < 300)
    for i in range(15, 20):
        assert resetpassword.checktoken(token_store[i])
Exemplo n.º 5
0
def test_link_time_field_is_updated_when_valid_token_supplied_to_function():
    user_name = "test"
    email_addr = "*****@*****.**"
    user_id = db_utils.create_user(email_addr=email_addr, username=user_name)
    form_for_request = Bag(email=email_addr, username=user_name, day=arrow.now().day,
                           month=arrow.now().month, year=arrow.now().year)
    resetpassword.request(form_for_request)
    pw_reset_token = d.engine.scalar("SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    resetpassword.prepare(pw_reset_token)
    link_time = d.engine.scalar("SELECT link_time FROM forgotpassword WHERE token = %(token)s", token=pw_reset_token)
    assert link_time >= d.get_time()
Exemplo n.º 6
0
def resetpassword_get_(request):
    form = request.web_input(token="")

    if not resetpassword.checktoken(form.token):
        return Response(define.errorpage(
            request.userid,
            "This link does not appear to be valid. If you followed this link from your email, it may have expired."))

    resetpassword.prepare(form.token)

    return Response(define.webpage(request.userid, "etc/resetpassword.html", [form.token], title="Reset Forgotten Password"))
Exemplo n.º 7
0
    def GET(self):
        form = web.input(token="")

        if not resetpassword.checktoken(form.token):
            return define.errorpage(
                self.user_id,
                "This link does not appear to be valid. If you followed this link from your email, it may have expired."
            )

        resetpassword.prepare(form.token)

        return define.webpage(self.user_id, template.etc_resetpassword,
                              [form.token])
Exemplo n.º 8
0
def test_verify_success_if_valid_information_provided():
    email_addr = "*****@*****.**"
    user_id = db_utils.create_user(email_addr=email_addr)
    form = Bag(email=email_addr)
    resetpassword.request(form)
    pw_reset_token = d.engine.scalar("SELECT token FROM forgotpassword WHERE userid = %(id)s", id=user_id)
    assert 100 == len(pw_reset_token)
    assert resetpassword.prepare(pw_reset_token)
Exemplo n.º 9
0
def test_unregistered():
    email_addr = "*****@*****.**"
    user_id = db_utils.create_user(username='******')
    token = "testtokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentest000008"
    d.engine.execute(d.meta.tables["forgotpassword"].insert(), {
        "userid": user_id,
        "token_sha256": hashlib.sha256(token.encode("ascii")).digest(),
        "email": email_addr,
    })
    assert resetpassword.prepare(token) == resetpassword.Unregistered(email=email_addr)
Exemplo n.º 10
0
def test_stale_records_get_deleted_when_function_is_called(captured_tokens):
    email_addrs = list(map("test{}@weasyl.com".format, range(10)))

    for email_addr in email_addrs:
        db_utils.create_user(email_addr=email_addr)
        resetpassword.request(email=email_addr)
    # Set 5 tokens to be two hours old (0,5)
    for i in range(0, 5):
        d.engine.execute("UPDATE forgotpassword SET created_at = now() - INTERVAL '2 hours' WHERE email = %(email)s",
                         email=email_addrs[i])
    # Set 5 tokens to be 30 minutes old (5,10)
    for i in range(5, 10):
        d.engine.execute("UPDATE forgotpassword SET created_at = now() - INTERVAL '30 minutes' WHERE email = %(email)s",
                         email=email_addrs[i])
    # This range should be invalid (created_at > 3600)
    for i in range(0, 5):
        assert not resetpassword.prepare(captured_tokens[email_addrs[i]])
    # This range should still be valid (created_at < 3600)
    for i in range(5, 10):
        assert resetpassword.prepare(captured_tokens[email_addrs[i]])
Exemplo n.º 11
0
def test_true_returned_if_token_exists():
    user_id = db_utils.create_user(username='******')
    token = "testtokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentest000001"
    d.engine.execute(d.meta.tables["forgotpassword"].insert(), {
        "userid": user_id,
        "token": token,
        "set_time": d.get_time(),
        "link_time": 0,
        "address": d.get_address(),
    })
    assert resetpassword.prepare(token)
Exemplo n.º 12
0
def test_verify_success_if_valid_information_provided(captured_tokens):
    email_addr = "*****@*****.**"
    username = "******"
    user_id = db_utils.create_user(username=username, email_addr=email_addr)
    resetpassword.request(email=email_addr)

    pw_reset_token = captured_tokens[email_addr]
    assert 25 == len(pw_reset_token)
    assert dict(resetpassword.prepare(pw_reset_token)) == {
        "userid": user_id,
        "email": email_addr,
        "username": username,
    }
Exemplo n.º 13
0
def test_case_insensitive_local_part(captured_tokens):
    email_addr = "*****@*****.**"
    username = "******"
    user_id = db_utils.create_user(username=username,
                                   email_addr=email_addr.swapcase())
    resetpassword.request(email=email_addr)

    pw_reset_token = captured_tokens[email_addr]
    assert 25 == len(pw_reset_token)
    assert dict(resetpassword.prepare(pw_reset_token)) == {
        "userid": user_id,
        "email": email_addr.swapcase(),
        "username": username,
    }
Exemplo n.º 14
0
def test_user_info_returned_if_token_exists():
    email_addr = "*****@*****.**"
    username = "******"
    user_id = db_utils.create_user(username=username, email_addr=email_addr)
    token = "testtokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentest000008"
    d.engine.execute(d.meta.tables["forgotpassword"].insert(), {
        "userid": user_id,
        "token_sha256": hashlib.sha256(token.encode("ascii")).digest(),
        "email": email_addr,
    })
    assert dict(resetpassword.prepare(token)) == {
        "userid": user_id,
        "email": email_addr,
        "username": username,
    }
Exemplo n.º 15
0
def resetpassword_get_(request):
    token = request.GET.get('token', "")
    reset_target = resetpassword.prepare(token=token)

    if reset_target is None:
        return Response(define.errorpage(
            request.userid,
            "This link does not appear to be valid. If you followed this link from your email, it may have expired."))

    if isinstance(reset_target, resetpassword.Unregistered):
        return Response(define.errorpage(
            request.userid,
            "The e-mail address **%s** is not associated with a Weasyl account." % (reset_target.email,),
            [["Sign Up", "/signup"], ["Return to the Home Page", "/"]]))

    return Response(define.webpage(request.userid, "etc/resetpassword.html", [token, reset_target], title="Reset Forgotten Password"))
Exemplo n.º 16
0
def test_none_returned_if_token_does_not_exist():
    token = "testtokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentesttokentest000000"
    assert resetpassword.prepare(token) is None