예제 #1
0
def test_admin_can_ban_email_domain(client, user_info, test_config):
    register_user(client, user_info)
    promote_user_to_admin(client, user_info)

    rv = client.get(url_for("admin.domains", domain_type="email"))
    rv = client.post(
        url_for("do.ban_domain", domain_type="email"),
        data=dict(csrf_token=csrf_token(rv.data), domain="spam4u.com"),
        follow_redirects=True,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    log_out_current_user(client)
    rv = client.get(url_for("auth.register"))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username="******",
            password="******",
            confirm="Safe123#$@lolnot",
            email_required="*****@*****.**",
            invitecode="",
            accept_tos=True,
            captcha="xyzzy",
        )
        rv = client.post(url_for("auth.register"), data=data, follow_redirects=True)
        assert len(outbox) == 0
        assert b"do not accept emails" in rv.data
        assert b"Register" in rv.data
        assert b"Log out" not in rv.data
예제 #2
0
def test_reset_password(client, user_info):
    """A user can reset their password using a link sent to their email."""
    new_password = '******'
    assert new_password != user_info['password']
    register_user(client, user_info)
    log_out_current_user(client)

    with mail.record_messages() as outbox:
        rv = client.get(url_for('user.password_recovery'))
        rv = client.post(url_for('user.password_recovery'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   email=user_info['email'],
                                   captcha='xyzzy'))
        message = outbox.pop()
        assert message.send_to == {user_info['email']}
        soup = BeautifulSoup(message.html, 'html.parser')
        token = soup.a['href'].split('/')[-1]
        rv = client.get(url_for('user.password_reset', token=token),
                        follow_redirects=True)
        rv = client.post(url_for('do.reset'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   user=get_value(rv.data, 'user'),
                                   key=get_value(rv.data, 'key'),
                                   password=new_password,
                                   confirm=new_password))

        log_out_current_user(client)
        user_info['password'] = new_password
        log_in_user(client, user_info, expect_success=True)
예제 #3
0
def test_admin_can_ban_email_domain(client, user_info):
    register_user(client, user_info)
    promote_user_to_admin(client, user_info)

    rv = client.get(url_for('admin.domains', domain_type='email'))
    rv = client.post(url_for('do.ban_domain', domain_type='email'),
                     data=dict(csrf_token=csrf_token(rv.data),
                               domain='spam4u.com'),
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'ok'

    log_out_current_user(client)
    rv = client.get(url_for('auth.register'))
    with mail.record_messages() as outbox:
        data = dict(csrf_token=csrf_token(rv.data),
                    username='******',
                    password='******',
                    confirm='Safe123#$@lolnot',
                    email_required='*****@*****.**',
                    invitecode='',
                    accept_tos=True,
                    captcha='xyzzy')
        rv = client.post(url_for('auth.register'),
                         data=data,
                         follow_redirects=True)
        assert len(outbox) == 0
        assert b'do not accept emails' in rv.data
        assert b'Register' in rv.data
        assert b'Log out' not in rv.data
예제 #4
0
def test_admin_can_ban_and_unban_user(client, user_info, user2_info):
    register_user(client, user_info)
    register_user(client, user2_info)
    promote_user_to_admin(client, user2_info)

    username = user_info["username"]

    rv = client.get(url_for("user.view", user=username))
    client.post(
        url_for("do.ban_user", username=username),
        data=dict(csrf_token=csrf_token(rv.data)),
        follow_redirects=True,
    )

    # For now, banning makes you unable to log in.
    log_out_current_user(client)
    log_in_user(client, user_info, expect_success=False)
    log_in_user(client, user2_info)

    rv = client.get(url_for("user.view", user=username))
    client.post(
        url_for("do.unban_user", username=username),
        data=dict(csrf_token=csrf_token(rv.data)),
        follow_redirects=True,
    )

    log_out_current_user(client)
    log_in_user(client, user_info)
예제 #5
0
def test_send_and_receive_pm(client, user_info, user2_info):
    """Send and receive a private message."""
    username = user_info["username"]
    register_user(client, user_info)
    register_user(client, user2_info)

    # User2 sends User a message.
    rv = client.get(url_for("user.view", user=username))
    assert rv.status == "200 OK"
    client.post(
        url_for("do.create_sendmsg"),
        data=dict(
            csrf_token=csrf_token(rv.data),
            to=username,
            subject="Testing",
            content="Test Content",
        ),
        follow_redirects=True,
    )

    # User2 sees the message in Sent Messages.
    rv = client.get(url_for("messages.view_messages_sent"), follow_redirects=True)
    assert rv.status == "200 OK"
    assert substrings_present(rv.data, [username, "Testing", "Test Content"])

    log_out_current_user(client, verify=True)
    log_in_user(client, user_info, expect_success=True)

    # User has one new message.
    rv = client.get(url_for("home.index"), follow_redirects=True)
    assert rv.status == "200 OK"
    soup = BeautifulSoup(rv.data, "html.parser", from_encoding="utf-8")
    link = soup.find(href=url_for("messages.inbox_sort"))
    assert link.get_text().strip() == "1"

    # User sees the message on the inbox page.
    rv = client.get(url_for("messages.inbox_sort"), follow_redirects=True)
    assert rv.status == "200 OK"
    assert substrings_present(
        rv.data, [user2_info["username"], "Testing", "Test Content"]
    )

    # User marks the message as read.
    soup = BeautifulSoup(rv.data, "html.parser", from_encoding="utf-8")
    tag = soup.find(lambda tag: tag.has_attr("data-mid"))
    mid = tag.attrs["data-mid"]

    rv = client.post(
        url_for("do.read_pm", mid=mid),
        data=dict(csrf_token=csrf_token(rv.data)),
    )

    # User returns to home page; notifications count now 0.
    rv = client.get(url_for("home.index"), follow_redirects=True)
    assert rv.status == "200 OK"
    soup = BeautifulSoup(rv.data, "html.parser", from_encoding="utf-8")
    link = soup.find(href=url_for("messages.inbox_sort"))
    assert link.get_text().strip() == "0"
예제 #6
0
def test_delete_account(client, user_info):
    """A user can delete their account."""
    register_user(client, user_info)

    # The password has to be right.
    rv = client.get(url_for("user.delete_account"))
    rv = client.post(
        url_for("do.delete_user"),
        data=dict(
            csrf_token=csrf_token(rv.data),
            password="******",
            consent="YES",
        ),
        follow_redirects=True,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "error"

    # The consent must be given.
    rv = client.get(url_for("user.delete_account"))
    rv = client.post(
        url_for("do.delete_user"),
        data=dict(
            csrf_token=csrf_token(rv.data),
            password="******",
            consent="NO",
        ),
        follow_redirects=True,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "error"

    rv = client.get(url_for("user.delete_account"))
    rv = client.post(
        url_for("do.delete_user"),
        data=dict(
            csrf_token=csrf_token(rv.data),
            password=user_info["password"],
            consent="YES",
        ),
        follow_redirects=True,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Deleting your account should log you out.
    rv = client.get(url_for("home.index"))
    assert b"Log in" in rv.data

    # Try to log in to the deleted account.
    log_in_user(client, user_info, expect_success=False)
예제 #7
0
def test_resend_registration_email(client, user_info, test_config):
    """Registered but unconfirmed users can resend the registration link."""
    rv = client.get(url_for("auth.register"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        username=user_info["username"],
        password=user_info["password"],
        confirm=user_info["password"],
        email_required=user_info["email"],
        invitecode="",
        accept_tos=True,
        captcha="xyzzy",
    )

    rv = client.post(url_for("auth.register"),
                     data=data,
                     follow_redirects=True)
    assert b"spam" in rv.data  # Telling user to go check it.

    # Find the resend link.
    soup = BeautifulSoup(rv.data, "html.parser")
    links = soup.find_all(
        lambda tag: tag.name == "a" and tag.string == "Resend")
    url = links[0]["href"]

    # Request the resend form and verify the registered email is shown.
    rv = client.get(url)
    assert b"Resend account confirmation instructions" in rv.data
    soup = BeautifulSoup(rv.data, "html.parser")
    tag = soup.find_all(lambda tag: tag.get("name") == "email")[0]
    assert tag["value"] == user_info["email"]

    # Use the resend form and the resent link.
    with mail.record_messages() as outbox:
        rv = client.post(
            url,
            data=dict(
                csrf_token=csrf_token(rv.data),
                email=user_info["email"],
            ),
            follow_redirects=True,
        )
        assert b"spam" in rv.data  # Telling user to go check it.
        message = outbox.pop()
        soup = BeautifulSoup(message.html, "html.parser")
        token = soup.a["href"].split("/")[-1]
        rv = client.get(url_for("auth.login_with_token", token=token),
                        follow_redirects=True)
        assert b"Log out" in rv.data
예제 #8
0
def test_reregister(client, user_info, user2_info, test_config):
    "A user account which is unconfirmed after two days can be re-registered."
    rv = client.get(url_for("auth.register"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        username=user_info["username"],
        password=user_info["password"],
        confirm=user_info["password"],
        invitecode="",
        accept_tos=True,
        email_required=user_info["email"],
        captcha="xyzzy",
    )
    client.post(url_for("auth.register"), data=data, follow_redirects=True)

    new_user = User.get(User.name == user_info["username"])
    assert new_user.status == UserStatus.PROBATION
    new_user.joindate -= timedelta(days=3)
    new_user.save()

    rv = client.get(url_for("auth.register"))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username=user_info["username"],
            password=user_info["password"],
            confirm=user_info["password"],
            invitecode="",
            email_required=user2_info["email"],
            accept_tos=True,
        )
        rv = client.post(url_for("auth.register"), data=data, follow_redirects=True)

        assert b"spam" in rv.data  # Telling user to go check it.
        message = outbox[-1]
        assert message.send_to == {user2_info["email"]}
        soup = BeautifulSoup(message.html, "html.parser")
        token = soup.a["href"].split("/")[-1]
        rv = client.get(
            url_for("auth.login_with_token", token=token), follow_redirects=True
        )
        assert b"Log out" in rv.data

    assert auth_provider.get_user_by_email(user_info["email"]) is None
    assert (
        auth_provider.get_user_by_email(user2_info["email"]).name
        == user_info["username"]
    )
예제 #9
0
def test_submit_text_post(client, user_info, test_config):
    register_user(client, user_info)
    create_sub(client)
    rv = client.get(url_for("subs.submit", ptype="text", sub="test"))
    data = {"csrf_token": csrf_token(rv.data), "title": "f\u000A\u000A\u000A"}

    rv = client.post(
        url_for("subs.submit", ptype="text", sub="does_not_exist"),
        data=data,
        follow_redirects=True,
    )
    assert b"Sub does not exist" in get_error(rv.data)
    rv = client.post(
        url_for("subs.submit", ptype="text", sub="test"),
        data=data,
        follow_redirects=True,
    )
    assert b"Error in the 'Post type' field - This field is required." == get_error(
        rv.data)
    data["ptype"] = "text"
    rv = client.post(
        url_for("subs.submit", ptype="text", sub="test"),
        data=data,
        follow_redirects=True,
    )
    assert b"Title is too short and/or contains whitespace characters." in get_error(
        rv.data)
    data["title"] = "Testing!"
    rv = client.post(
        url_for("subs.submit", ptype="text", sub="test"),
        data=data,
        follow_redirects=True,
    )
    assert not get_error(rv.data)
    assert b"Testing! |  test" in rv.data
예제 #10
0
def test_submit_link_post(client, user_info, test_config):
    register_user(client, user_info)
    create_sub(client)
    rv = client.get(url_for("subs.submit", ptype="text", sub="test"))
    data = {
        "csrf_token": csrf_token(rv.data),
        "title": "Testing link!",
        "ptype": "link",
    }

    rv = client.post(
        url_for("subs.submit", ptype="link", sub="test"),
        data=data,
        follow_redirects=False,
    )
    assert get_error(rv.data) == b"No link provided."
    data["link"] = "https://google.com"
    rv = client.post(
        url_for("subs.submit", ptype="link", sub="test"),
        data=data,
        follow_redirects=False,
    )
    assert rv.status_code == 302
    assert "/s/test/1" == rv.location

    # Test anti-repost
    rv = client.post(
        url_for("subs.submit", ptype="link", sub="test"),
        data=data,
        follow_redirects=False,
    )
    assert (get_error(
        rv.data
    ) == b'This link was <a href="/s/test/1">recently posted</a> on this sub.')
예제 #11
0
def test_admin_totp_auth_flow(client, user_info, test_config):
    register_user(client, user_info)
    assert client.get(url_for("admin.auth")).status_code == 404
    promote_user_to_admin(client, user_info)
    rv = client.get(url_for("admin.auth"), follow_redirects=True)
    assert rv.status_code == 200
    assert b"TOTP setup" in rv.data
    user = User.get(User.name == user_info["username"])
    user_secret = UserMetadata.get((UserMetadata.uid == user.uid)
                                   & (UserMetadata.key == "totp_secret"))
    totp = pyotp.TOTP(user_secret.value)

    data = {"csrf_token": csrf_token(rv.data), "totp": totp.now()}

    rv = client.post(url_for("admin.auth"), data=data, follow_redirects=False)
    assert rv.status_code == 302
    assert rv.location == url_for("admin.index")

    # Try again with bad token
    data["totp"] = "1"
    rv = client.post(url_for("admin.auth"), data=data, follow_redirects=False)
    assert rv.status_code == 200
    assert b"Invalid or expired token." in rv.data

    # Check if we're actually logged in.
    assert client.get(url_for("admin.index")).status_code == 200

    # Get QR code after we already set up TOTP
    assert client.get(url_for("admin.get_totp_image")).status_code == 403

    # Try logging out.
    client.post(url_for("admin.logout"), data=data)
    assert client.get(url_for("admin.index"),
                      follow_redirects=False).status_code == 302
예제 #12
0
def test_registration_login(client):
    """The registration page logs a user in if they register correctly."""
    rv = client.get(url_for('auth.register'))
    with mail.record_messages() as outbox:
        data = dict(csrf_token=csrf_token(rv.data),
                    username='******',
                    password='******',
                    confirm='Safe123#$@lolnot',
                    invitecode='',
                    accept_tos=True,
                    captcha='xyzzy')
        if email_validation_is_required():
            data['email_required'] = '*****@*****.**'
        else:
            data['email_optional'] = '*****@*****.**'
        rv = client.post(url_for('auth.register'),
                         data=data,
                         follow_redirects=True)

        if email_validation_is_required():
            assert b'spam' in rv.data  # Telling user to go check it.
            message = outbox[-1]
            soup = BeautifulSoup(message.html, 'html.parser')
            token = soup.a['href'].split('/')[-1]
            rv = client.get(url_for('auth.login_with_token', token=token),
                            follow_redirects=True)

        assert auth_provider.get_user_by_email(
            '*****@*****.**').name == 'supertester'
        assert b'Log out' in rv.data
예제 #13
0
def test_registration_login(client, test_config):
    """The registration page logs a user in if they register correctly."""
    rv = client.get(url_for("auth.register"))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username="******",
            password="******",
            confirm="Safe123#$@lolnot",
            invitecode="",
            accept_tos=True,
            captcha="xyzzy",
        )
        if email_validation_is_required():
            data["email_required"] = "*****@*****.**"
        else:
            data["email_optional"] = "*****@*****.**"
        rv = client.post(url_for("auth.register"),
                         data=data,
                         follow_redirects=True)

        if email_validation_is_required():
            assert b"spam" in rv.data  # Telling user to go check it.
            message = outbox[-1]
            soup = BeautifulSoup(message.html, "html.parser")
            token = soup.a["href"].split("/")[-1]
            rv = client.get(url_for("auth.login_with_token", token=token),
                            follow_redirects=True)

        assert auth_provider.get_user_by_email(
            "*****@*****.**").name == "supertester"
        assert b"Log out" in rv.data
예제 #14
0
def test_change_password(client, user_info):
    """A user can change their password and log in with the new password."""
    register_user(client, user_info)
    new_password = "******" + "\N{PARTIAL DIFFERENTIAL}"
    assert new_password != user_info["password"]
    rv = client.get(url_for("user.edit_account"))
    rv = client.post(
        url_for("do.edit_account"),
        data=dict(
            csrf_token=csrf_token(rv.data),
            oldpassword=user_info["password"],
            password=new_password,
            confirm=new_password,
        ),
        follow_redirects=True,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    log_out_current_user(client)

    # Try to log in with the old password
    log_in_user(client, user_info, expect_success=False)

    new_info = dict(user_info)
    new_info.update(password=new_password)
    log_in_user(client, new_info, expect_success=True)
예제 #15
0
def test_login_before_confirming_email(client, user_info, test_config):
    """Registered users with unconfirmed emails can't log in."""
    rv = client.get(url_for("auth.register"))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username=user_info["username"],
            password=user_info["password"],
            confirm=user_info["password"],
            email_required=user_info["email"],
            invitecode="",
            accept_tos=True,
            captcha="xyzzy",
        )
        rv = client.post(url_for("auth.register"),
                         data=data,
                         follow_redirects=True)
        assert b"spam" in rv.data  # Telling user to go check it.

        message = outbox.pop()

        rv = client.get(url_for("auth.login"))
        rv = client.post(
            url_for("auth.login"),
            data=dict(
                csrf_token=csrf_token(rv.data),
                username=user_info["username"],
                password=user_info["password"],
            ),
            follow_redirects=True,
        )
        assert b"Resend account confirmation instructions" in rv.data
        rv = client.post(
            url_for("auth.resend_confirmation_email"),
            data=dict(csrf_token=csrf_token(rv.data),
                      email=user_info["email"]),
            follow_redirects=True,
        )

        assert b"spam" in rv.data  # Telling user to go check it.
        message = outbox.pop()
        soup = BeautifulSoup(message.html, "html.parser")
        token = soup.a["href"].split("/")[-1]
        rv = client.get(url_for("auth.login_with_token", token=token),
                        follow_redirects=True)

        assert b"Log out" in rv.data
예제 #16
0
def test_password_required_to_change_recovery_email(client, user_info,
                                                    test_config):
    """Changing the password recovery requires the correct password."""
    register_user(client, user_info)
    wrong_password = "******"
    new_email = "*****@*****.**"
    assert wrong_password != user_info["password"]
    assert new_email != user_info["email"]

    rv = client.get(url_for("user.edit_account"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        email_required=new_email,
        oldpassword=wrong_password,
        password="",
        confirm="",
    )

    # No confirmation email should be sent.
    with mail.record_messages() as outbox:
        rv = client.post(url_for("do.edit_account"),
                         data=data,
                         follow_redirects=True)
        assert len(outbox) == 0

    log_out_current_user(client)

    # Verify password recovery email goes to the right place.
    with mail.record_messages() as outbox:
        rv = client.get(url_for("user.password_recovery"))
        rv = client.post(
            url_for("user.password_recovery"),
            data=dict(csrf_token=csrf_token(rv.data),
                      email=new_email,
                      captcha="xyzzy"),
        )
        assert len(outbox) == 0
        rv = client.get(url_for("user.password_recovery"))
        rv = client.post(
            url_for("user.password_recovery"),
            data=dict(
                csrf_token=csrf_token(rv.data),
                email=user_info["email"],
                captcha="xyzzy",
            ),
        )
        assert len(outbox) == 1
예제 #17
0
def test_reregister(client, user_info, user2_info):
    "A user account which is unconfirmed after two days can be re-registered."
    rv = client.get(url_for('auth.register'))
    data = dict(csrf_token=csrf_token(rv.data),
                username=user_info['username'],
                password=user_info['password'],
                confirm=user_info['password'],
                invitecode='',
                accept_tos=True,
                email_required=user_info['email'],
                captcha='xyzzy')
    rv = client.post(url_for('auth.register'),
                     data=data,
                     follow_redirects=True)

    new_user = User.get(User.name == user_info['username'])
    assert new_user.status == UserStatus.PROBATION
    new_user.joindate -= timedelta(days=3)
    new_user.save()

    rv = client.get(url_for('auth.register'))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username=user_info['username'],
            password=user_info['password'],
            confirm=user_info['password'],
            invitecode='',
            email_required=user2_info['email'],
            accept_tos=True,
        )
        rv = client.post(url_for('auth.register'),
                         data=data,
                         follow_redirects=True)

        assert b'spam' in rv.data  # Telling user to go check it.
        message = outbox[-1]
        assert message.send_to == {user2_info['email']}
        soup = BeautifulSoup(message.html, 'html.parser')
        token = soup.a['href'].split('/')[-1]
        rv = client.get(url_for('auth.login_with_token', token=token),
                        follow_redirects=True)
        assert b'Log out' in rv.data

    assert auth_provider.get_user_by_email(user_info['email']) == None
    assert (auth_provider.get_user_by_email(
        user2_info['email']).name == user_info['username'])
예제 #18
0
def test_login_before_confirming_email(client, user_info):
    """Registered users with unconfirmed emails can't log in."""
    rv = client.get(url_for('auth.register'))
    with mail.record_messages() as outbox:
        data = dict(csrf_token=csrf_token(rv.data),
                    username=user_info['username'],
                    password=user_info['password'],
                    confirm=user_info['password'],
                    email_required=user_info['email'],
                    invitecode='',
                    accept_tos=True,
                    captcha='xyzzy')
        rv = client.post(url_for('auth.register'),
                         data=data,
                         follow_redirects=True)
        assert b'spam' in rv.data  # Telling user to go check it.

        message = outbox.pop()

        rv = client.get(url_for('auth.login'))
        rv = client.post(url_for('auth.login'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   username=user_info['username'],
                                   password=user_info['password']),
                         follow_redirects=True)
        assert b'Resend account confirmation instructions' in rv.data
        rv = client.post(url_for('auth.resend_confirmation_email'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   email=user_info['email']),
                         follow_redirects=True)

        assert b'spam' in rv.data  # Telling user to go check it.
        message = outbox.pop()
        soup = BeautifulSoup(message.html, 'html.parser')
        token = soup.a['href'].split('/')[-1]
        rv = client.get(url_for('auth.login_with_token', token=token),
                        follow_redirects=True)

        assert b'Log out' in rv.data
예제 #19
0
def test_delete_account(client, user_info):
    """A user can delete their account."""
    register_user(client, user_info)

    # The password has to be right.
    rv = client.get(url_for('user.delete_account'))
    rv = client.post(url_for('do.delete_user'),
                     data=dict(csrf_token=csrf_token(rv.data),
                               password='******',
                               consent='YES'),
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'error'

    # The consent must be given.
    rv = client.get(url_for('user.delete_account'))
    rv = client.post(url_for('do.delete_user'),
                     data=dict(csrf_token=csrf_token(rv.data),
                               password='******',
                               consent='NO'),
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'error'

    rv = client.get(url_for('user.delete_account'))
    rv = client.post(url_for('do.delete_user'),
                     data=dict(csrf_token=csrf_token(rv.data),
                               password=user_info['password'],
                               consent='YES'),
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'ok'

    # Deleting your account should log you out.
    rv = client.get(url_for('home.index'))
    assert b'Log in' in rv.data

    # Try to log in to the deleted account.
    log_in_user(client, user_info, expect_success=False)
예제 #20
0
def test_reset_password(client, user_info):
    """A user can reset their password using a link sent to their email."""
    new_password = "******"
    assert new_password != user_info["password"]
    register_user(client, user_info)
    log_out_current_user(client)

    with mail.record_messages() as outbox:
        rv = client.get(url_for("user.password_recovery"))
        rv = client.post(
            url_for("user.password_recovery"),
            data=dict(
                csrf_token=csrf_token(rv.data),
                email=user_info["email"],
                captcha="xyzzy",
            ),
        )
        message = outbox.pop()
        assert message.send_to == {user_info["email"]}
        soup = BeautifulSoup(message.html, "html.parser")
        token = soup.a["href"].split("/")[-1]
        rv = client.get(
            url_for("user.password_reset", token=token), follow_redirects=True
        )
        rv = client.post(
            url_for("do.reset"),
            data=dict(
                csrf_token=csrf_token(rv.data),
                user=get_value(rv.data, "user"),
                key=get_value(rv.data, "key"),
                password=new_password,
                confirm=new_password,
            ),
        )

        log_out_current_user(client)
        user_info["password"] = new_password
        log_in_user(client, user_info, expect_success=True)
예제 #21
0
def test_password_required_to_change_recovery_email(client, user_info):
    """Changing the password recovery requires the correct password."""
    register_user(client, user_info)
    wrong_password = '******'
    new_email = '*****@*****.**'
    assert wrong_password != user_info['password']
    assert new_email != user_info['email']

    rv = client.get(url_for('user.edit_account'))
    data = dict(csrf_token=csrf_token(rv.data),
                email_required=new_email,
                oldpassword=wrong_password,
                password='',
                confirm='')

    # No confirmation email should be sent.
    with mail.record_messages() as outbox:
        rv = client.post(url_for('do.edit_account'),
                         data=data,
                         follow_redirects=True)
        assert len(outbox) == 0

    log_out_current_user(client)

    # Verify password recovery email goes to the right place.
    with mail.record_messages() as outbox:
        rv = client.get(url_for('user.password_recovery'))
        rv = client.post(url_for('user.password_recovery'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   email=new_email,
                                   captcha='xyzzy'))
        assert len(outbox) == 0
        rv = client.get(url_for('user.password_recovery'))
        rv = client.post(url_for('user.password_recovery'),
                         data=dict(csrf_token=csrf_token(rv.data),
                                   email=user_info['email'],
                                   captcha='xyzzy'))
        assert len(outbox) == 1
예제 #22
0
def test_create_sub_error(client, user_info):
    register_user(client, user_info)
    rv = client.get(url_for("subs.create_sub"))
    assert rv.status_code == 200

    data = {"csrf_token": csrf_token(rv.data), "subname": "蛋糕", "title": "Testing"}
    rv = client.post(url_for("subs.create_sub"), data=data, follow_redirects=True)
    assert b"Sub name has invalid characters" in get_error(rv.data)
    data["subname"] = "home"
    rv = client.post(url_for("subs.create_sub"), data=data, follow_redirects=True)
    assert b"Invalid sub name" in get_error(rv.data)
    data["subname"] = "test"
    rv = client.post(url_for("subs.create_sub"), data=data, follow_redirects=True)
    assert b"You must be at least level 2." in get_error(rv.data)
예제 #23
0
def test_create_sub(client, user_info, test_config):
    register_user(client, user_info)
    rv = client.get(url_for("subs.create_sub"))
    assert rv.status_code == 200

    data = {"csrf_token": csrf_token(rv.data), "subname": "test", "title": "Testing"}

    rv = client.post(url_for("subs.create_sub"), data=data, follow_redirects=True)
    assert not get_error(rv.data)
    assert b"/s/test" in rv.data

    # if we try again it should fail
    rv = client.post(url_for("subs.create_sub"), data=data, follow_redirects=True)
    assert b"Sub is already registered" == get_error(rv.data)
예제 #24
0
def test_submit_invalid_post_type(client, user_info, test_config):
    register_user(client, user_info)
    create_sub(client)
    rv = client.get(url_for("subs.submit", ptype="text", sub="test"))
    data = {
        "csrf_token": csrf_token(rv.data),
        "title": "Testing link!",
    }

    rv = client.post(
        url_for("subs.submit", ptype="toast", sub="test"),
        data=data,
        follow_redirects=False,
    )
    assert rv.status_code == 404
예제 #25
0
def test_email_required_for_registration(client, user_info):
    "If emails are required, trying to register without one will fail."
    rv = client.get(url_for('auth.register'))
    with mail.record_messages() as outbox:
        data = dict(csrf_token=csrf_token(rv.data),
                    username='******',
                    password='******',
                    confirm='Safe123#$@lolnot',
                    email_required='',
                    invitecode='',
                    accept_tos=True,
                    captcha='xyzzy')
        rv = client.post(url_for('auth.register'),
                         data=data,
                         follow_redirects=True)
        assert len(outbox) == 0
        assert b'Error' in rv.data
        assert b'Register' in rv.data
        assert b'Log out' not in rv.data
예제 #26
0
def test_email_required_for_registration(client, user_info, test_config):
    """
    If emails are required, trying to register without one will fail.
    """
    rv = client.get(url_for("auth.register"))
    with mail.record_messages() as outbox:
        data = dict(
            csrf_token=csrf_token(rv.data),
            username="******",
            password="******",
            confirm="Safe123#$@lolnot",
            email_required="",
            invitecode="",
            accept_tos=True,
            captcha="xyzzy",
        )
        rv = client.post(url_for("auth.register"), data=data, follow_redirects=True)
        assert len(outbox) == 0
        assert b"Error" in rv.data
        assert b"Register" in rv.data
        assert b"Log out" not in rv.data
예제 #27
0
def test_resend_registration_email_after_confirmation(client, user_info,
                                                      test_config):
    """Registration instructions cannot be resent after confirmation."""
    with mail.record_messages() as outbox:
        rv = client.get(url_for("auth.register"))
        data = dict(
            csrf_token=csrf_token(rv.data),
            username=user_info["username"],
            password=user_info["password"],
            confirm=user_info["password"],
            email_required=user_info["email"],
            invitecode="",
            accept_tos=True,
            captcha="xyzzy",
        )
        rv = client.post(url_for("auth.register"),
                         data=data,
                         follow_redirects=True)
        assert b"spam" in rv.data  # Telling user to go check it.

        # Find the resend link.
        soup = BeautifulSoup(rv.data, "html.parser")
        link = soup.find_all(
            lambda tag: tag.name == "a" and tag.string == "Resend")[0]
        url = link["href"]

        # Find and use the confirmation link.
        message = outbox[-1]
        soup = BeautifulSoup(message.html, "html.parser")
        token = soup.a["href"].split("/")[-1]
        rv = client.get(url_for("auth.login_with_token", token=token),
                        follow_redirects=True)

    assert b"Log out" in rv.data
    log_out_current_user(client, verify=True)

    # Request the resend form and verify an error message is shown.
    rv = client.get(url, follow_redirects=True)
    assert b"The link you used is invalid or has expired" in rv.data
    assert b"Log out" not in rv.data
예제 #28
0
def test_change_password(client, user_info):
    """A user can change their password and log in with the new password."""
    register_user(client, user_info)
    new_password = '******' + '\N{PARTIAL DIFFERENTIAL}'
    assert new_password != user_info['password']
    rv = client.get(url_for('user.edit_account'))
    rv = client.post(url_for('do.edit_account'),
                     data=dict(csrf_token=csrf_token(rv.data),
                               oldpassword=user_info['password'],
                               password=new_password,
                               confirm=new_password),
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'ok'

    log_out_current_user(client)

    # Try to log in with the old password
    log_in_user(client, user_info, expect_success=False)

    new_info = dict(user_info)
    new_info.update(password=new_password)
    log_in_user(client, new_info, expect_success=True)
예제 #29
0
def test_mod_invite_notification(client, user_info, user2_info):
    "Notifications are sent for mod invites."
    config.update_value("site.sub_creation_min_level", 0)
    receiver, mod = user_info, user2_info

    register_user(client, receiver)
    receiver_uid = User.get(User.name == receiver["username"]).uid
    log_out_current_user(client)

    register_user(client, mod)
    mod_uid = User.get(User.name == mod["username"]).uid
    create_sub(client, name="test_janitor")
    create_sub(client, name="test_mod")

    # Mod invites receiver as moderator.
    rv_index = client.get(url_for("home.index", sub="test_mod"))
    data = {
        "csrf_token": csrf_token(rv_index.data),
        "user": receiver["username"],
        "level": "1",
    }
    rv = client.post(
        url_for("do.inv_mod", sub="test_mod"),
        data=data,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Mod invites receiver as janitor.
    data = {
        "csrf_token": csrf_token(rv_index.data),
        "user": receiver["username"],
        "level": "2",
    }
    rv = client.post(
        url_for("do.inv_mod", sub="test_janitor"),
        data=data,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"
    log_out_current_user(client)

    # Receiver blocks mod.
    log_in_user(client, receiver)
    data = {
        "csrf_token": csrf_token(rv_index.data),
        "view_messages": "show",
        "view_content": "hide",
    }
    rv = client.post(url_for("do.edit_ignore", uid=mod_uid),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Receiver checks notifications.  They should not be ignored,
    # because they are mod actions.
    assert get_notification_count(receiver_uid)["notifications"] == 2
    rv = client.get(url_for("messages.view_notifications"))
    assert b"invited you to moderate" in rv.data
    soup = BeautifulSoup(rv.data, "html.parser", from_encoding="utf-8")
    assert soup.find(href=url_for("sub.edit_sub_mods", sub="test_mod"))
    assert soup.find(href=url_for("sub.edit_sub_mods", sub="test_janitor"))

    # After checking, the notification is marked read.
    assert get_notification_count(receiver_uid)["notifications"] == 0

    # Receiver unblocks mod.
    data = {
        "csrf_token": csrf_token(rv.data),
        "view_messages": "show",
        "view_content": "show",
    }
    rv = client.post(url_for("do.edit_ignore", uid=mod_uid),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Receiver checks notifications again.
    rv = client.get(url_for("messages.view_notifications"))
    assert b"invited you to moderate" in rv.data
    assert soup.find(href=url_for("sub.edit_sub_mods", sub="test_mod"))
    assert soup.find(href=url_for("sub.edit_sub_mods", sub="test_janitor"))
예제 #30
0
def test_post_delete_notification(client, user_info, user2_info, user3_info):
    "Notifications are sent for post delete and undelete."
    config.update_value("site.sub_creation_min_level", 0)
    receiver, admin, mod = user_info, user2_info, user3_info

    register_user(client, receiver)
    receiver_uid = User.get(User.name == receiver["username"]).uid
    log_out_current_user(client)

    register_user(client, admin)
    promote_user_to_admin(client, admin)
    log_out_current_user(client)

    register_user(client, mod)
    mod_uid = User.get(User.name == mod["username"]).uid
    create_sub(client)
    log_out_current_user(client)

    # Receiver makes a post.
    log_in_user(client, receiver)
    rv_post = client.get(url_for("subs.submit", ptype="text", sub="test"))
    csrf = csrf_token(rv_post.data)
    data = {
        "csrf_token": csrf,
        "title": "the title",
        "ptype": "text",
        "content": "the content",
    }
    rv = client.post(
        url_for("subs.submit", ptype="text", sub="test"),
        data=data,
        follow_redirects=False,
    )
    assert rv.status == "302 FOUND"
    soup = BeautifulSoup(rv.data, "html.parser", from_encoding="utf-8")
    link = soup.a.get_text()
    pid = link.split("/")[-1]
    log_out_current_user(client)

    # Mod deletes the post.
    log_in_user(client, mod)
    data = {
        "csrf_token": csrf,
        "post": pid,
        "reason": "serious reason",
        "send_to_admin": False,
    }
    rv = client.post(
        url_for("do.delete_post"),
        data=data,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"
    log_out_current_user(client)

    # Admin un-deletes the post.
    log_in_user(client, admin)
    data = {
        "csrf_token": csrf,
        "post": pid,
        "reason": "frivolous reason",
    }
    rv = client.post(
        url_for("do.undelete_post"),
        data=data,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"
    log_out_current_user(client)

    # Receiver blocks mod.
    log_in_user(client, receiver)
    data = {
        "csrf_token": csrf,
        "view_messages": "show",
        "view_content": "hide",
    }
    rv = client.post(url_for("do.edit_ignore", uid=mod_uid),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Receiver checks notifications.  They should not be ignored,
    # because they are mod actions.
    assert get_notification_count(receiver_uid)["notifications"] == 2
    rv = client.get(url_for("messages.view_notifications"))
    assert b" deleted your post" in rv.data
    assert b"un-deleted your post" in rv.data
    assert b"serious reason" in rv.data
    assert b"frivolous reason" in rv.data

    # After checking, the notification is marked read.
    assert get_notification_count(receiver_uid)["notifications"] == 0

    # Receiver unblocks mod.
    data = {
        "csrf_token": csrf_token(rv.data),
        "view_messages": "show",
        "view_content": "show",
    }
    rv = client.post(url_for("do.edit_ignore", uid=mod_uid),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Receiver checks notifications again.
    rv = client.get(url_for("messages.view_notifications"))
    assert b" deleted your post" in rv.data
    assert b"un-deleted your post" in rv.data
    assert b"serious reason" in rv.data
    assert b"frivolous reason" in rv.data