コード例 #1
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)
コード例 #2
0
ファイル: test_admin.py プロジェクト: globalistas/ceknito
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
コード例 #3
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.')
コード例 #4
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
コード例 #5
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
コード例 #6
0
def test_get_totp_image(client, user_info, test_config):
    register_user(client, user_info)
    assert client.get(url_for("admin.get_totp_image")).status_code == 404
    promote_user_to_admin(client, user_info)
    rv = client.get(url_for("admin.get_totp_image"))
    assert rv.status_code == 200
    assert rv.content_type == "image/png"
コード例 #7
0
ファイル: test_admin.py プロジェクト: steadyember/throat
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
コード例 #8
0
ファイル: test_auth.py プロジェクト: steadyember/throat
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)
コード例 #9
0
ファイル: test_admin.py プロジェクト: globalistas/ceknito
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)
コード例 #10
0
ファイル: test_messages.py プロジェクト: happy-river/throat
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"
コード例 #11
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)
コード例 #12
0
ファイル: test_subs.py プロジェクト: globalistas/ceknito
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)
コード例 #13
0
ファイル: test_subs.py プロジェクト: globalistas/ceknito
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)
コード例 #14
0
ファイル: test_subs.py プロジェクト: globalistas/ceknito
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
コード例 #15
0
ファイル: test_subs.py プロジェクト: globalistas/ceknito
def test_submit_page(client, user_info):
    register_user(client, user_info)
    rv = client.get(url_for("subs.submit", ptype="text"))
    assert rv.status_code == 200
    rv = client.get(url_for("subs.submit", ptype="link"))
    assert rv.status_code == 200
    rv = client.get(url_for("subs.submit", ptype="poll"))
    assert rv.status_code == 200
    rv = client.get(url_for("subs.submit", ptype="upload"))
    assert rv.status_code == 200
    rv = client.get(url_for("subs.submit", ptype="something_that_does_not_exist"))
    assert rv.status_code == 404

    rv = client.get(url_for("subs.submit", ptype="text", sub="sub_that_does_not_exist"))
    assert rv.status_code == 404
コード例 #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
ファイル: test_auth.py プロジェクト: steadyember/throat
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)
コード例 #18
0
ファイル: test_auth.py プロジェクト: seafoamstars/throat
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)
コード例 #19
0
ファイル: test_auth.py プロジェクト: steadyember/throat
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
コード例 #20
0
ファイル: test_auth.py プロジェクト: steadyember/throat
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)
コード例 #21
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"))
コード例 #22
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
コード例 #23
0
def test_ban_notification(client, user_info, user2_info):
    "Notifications are sent for sub bans."
    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)
    log_out_current_user(client)

    # Receiver blocks mod.
    log_in_user(client, receiver)
    rv_index = client.get(url_for("home.index", sub="test"))
    csrf = csrf_token(rv_index.data)
    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"
    log_out_current_user(client)

    # Mod bans receiver.
    log_in_user(client, mod)
    data = {
        "csrf_token": csrf,
        "user": receiver["username"],
        "reason": "serious reason",
        "expires": None,
    }
    rv = client.post(
        url_for("do.ban_user_sub", sub="test"),
        data=data,
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Mod un-bans receiver.
    rv = client.post(
        url_for("do.remove_sub_ban", sub="test", user=receiver["username"]),
        data={"csrf_token": csrf},
    )
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"
    log_out_current_user(client)

    # Receiver checks notifications.  They should not be ignored,
    # because they are mod actions.
    log_in_user(client, receiver)
    assert get_notification_count(receiver_uid)["notifications"] == 2
    rv = client.get(url_for("messages.view_notifications"))
    assert b"banned you from" in rv.data
    assert b"serious reason" in rv.data
    assert b"unbanned you from" 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"banned you from" in rv.data
    assert b"serious reason" in rv.data
    assert b"unbanned you from" in rv.data
コード例 #24
0
def test_reply_notification(client, sub_mod, user_info, user2_info,
                            user3_info):
    "Notifications are sent for post and comment replies."
    sender, receiver, mod = user_info, user2_info, user3_info
    config.update_value("site.sub_creation_min_level", 0)

    register_user(client, sender)
    sender_uid = User.get(User.name == sender["username"]).uid
    if sub_mod == "sender":
        create_sub(client)
    log_out_current_user(client)

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

    if sub_mod == "neither":
        register_user(client, mod)
        create_sub(client)
        log_out_current_user(client)

    # Receiver makes a post that can be replied to
    log_in_user(client, receiver)
    rv = client.get(url_for("subs.submit", ptype="text", sub="test"))
    csrf = csrf_token(rv.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]

    # Receiver makes a comment that can be replied to.
    rv = client.get(link, follow_redirects=True)
    assert b"the title |  test" in rv.data
    data = {
        "csrf_token": csrf,
        "post": pid,
        "parent": "0",
        "comment": "OP reply",
    }
    rv = client.post(url_for("do.create_comment", pid=pid),
                     data=data,
                     follow_redirects=False)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"
    cid = reply["cid"]

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

    # Sender replies to the post.
    log_in_user(client, sender)
    rv = client.get(link, follow_redirects=True)
    assert b"the title |  test" in rv.data
    data = {
        "csrf_token": csrf,
        "post": pid,
        "parent": "0",
        "comment": "the comment",
    }
    rv = client.post(url_for("do.create_comment", pid=pid),
                     data=data,
                     follow_redirects=True)
    assert b"the comment" in rv.data

    # Sender replies to the comment.
    rv = client.get(link, follow_redirects=True)
    data = {
        "csrf_token": csrf_token(rv.data),
        "post": pid,
        "parent": cid,
        "comment": "comment reply",
    }
    rv = client.post(url_for("do.create_comment", pid=pid),
                     data=data,
                     follow_redirects=True)
    log_out_current_user(client)

    # Depending on who is the mod of the sub, should these notifications
    # be visible when the receiver has the sender blocked?
    expected = {"sender": True, "receiver": True, "neither": False}[sub_mod]
    assert get_notification_count(receiver_uid)["notifications"] == (
        2 if expected else 0)

    # Receiver checks notifications.
    log_in_user(client, receiver)
    rv = client.get(url_for("messages.view_notifications"))
    assert (b"replied to your post" in rv.data) == expected
    assert (b"the comment" in rv.data) == expected
    assert (b"replied to your comment" in rv.data) == expected
    assert (b"comment reply" in rv.data) == expected

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

    # Receiver checks notifications.
    rv = client.get(url_for("messages.view_notifications"))
    assert b"replied to your post" in rv.data
    assert b"the comment" in rv.data
    assert b"replied to your comment" in rv.data
    assert b"comment reply" in rv.data

    # Notifications should be marked read.
    assert get_notification_count(receiver_uid)["notifications"] == 0
コード例 #25
0
ファイル: test_user.py プロジェクト: globalistas/ceknito
def test_settings_page(client, user_info):
    register_user(client, user_info)
    username = user_info["username"]
    assert client.get(url_for("user.edit_user",
                              user=username)).status_code == 200
コード例 #26
0
def test_invite_code_required_for_registration(client, user_info, user2_info):
    """If invite codes are required, trying to register without one will fail."""
    register_user(client, user_info)
    promote_user_to_admin(client, user_info)

    # Enable invite codes.
    rv = client.get(url_for("admin.invitecodes"))
    data = dict(csrf_token=csrf_token(rv.data),
                enableinvitecode=True,
                minlevel=3,
                maxcodes=10)

    rv = client.post(url_for("do.use_invite_code"),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode("utf-8"))
    assert reply["status"] == "ok"

    # Create an invite code.
    rv = client.get(url_for("admin.invitecodes"))
    data = dict(csrf_token=csrf_token(rv.data),
                code="abcde",
                uses=10,
                expires="")
    client.post(url_for("admin.invitecodes"), data=data, follow_redirects=True)

    log_out_current_user(client)

    # Now try to register a new user without an invite code.
    rv = client.get(url_for("auth.register"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        username=user2_info["username"],
        password=user2_info["password"],
        confirm=user2_info["password"],
        invitecode="",
        email_optional=user2_info["email"],
        accept_tos=True,
        captcha="xyzzy",
    )

    rv = client.post(url_for("auth.register"),
                     data=data,
                     follow_redirects=True)
    assert b"Invalid invite code" in rv.data

    # Now try to register a new user with an incorrect invite code.
    rv = client.get(url_for("auth.register"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        username=user2_info["username"],
        password=user2_info["password"],
        confirm=user2_info["password"],
        invitecode="xyzzy",
        email_optional=user2_info["email"],
        accept_tos=True,
        captcha="xyzzy",
    )

    rv = client.post(url_for("auth.register"),
                     data=data,
                     follow_redirects=True)
    assert b"Invalid invite code" in rv.data

    # Now try to register a new user with a valid invite code.
    rv = client.get(url_for("auth.register"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        username=user2_info["username"],
        password=user2_info["password"],
        confirm=user2_info["password"],
        invitecode="abcde",
        email_optional=user2_info["email"],
        accept_tos=True,
        captcha="xyzzy",
    )

    rv = client.post(url_for("auth.register"),
                     data=data,
                     follow_redirects=True)
    assert b"Log out" in rv.data
コード例 #27
0
ファイル: test_auth.py プロジェクト: steadyember/throat
def test_change_password_recovery_email(client, user_info):
    """The user can change their password recovery email."""
    register_user(client, user_info)
    new_email = '*****@*****.**'
    assert new_email != user_info['email']

    rv = client.get(url_for('user.edit_account'))
    data = dict(csrf_token=csrf_token(rv.data),
                oldpassword=user_info['password'],
                password='',
                confirm='')
    if email_validation_is_required():
        data['email_required'] = new_email
    else:
        data['email_optional'] = new_email

    with mail.record_messages() as outbox:
        rv = client.post(url_for('do.edit_account'),
                         data=data,
                         follow_redirects=True)
        log_out_current_user(client)

        if email_validation_is_required():
            message = outbox.pop()

            # Make sure that password recovery emails go to the former address
            # if the new one has not yet been confirmed.
            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 outbox.pop().send_to == {user_info['email']}

            # Now click the confirm link.
            assert message.send_to == {new_email}
            soup = BeautifulSoup(message.html, 'html.parser')
            token = soup.a['href'].split('/')[-1]
            rv = client.get(url_for('user.confirm_email_change', token=token),
                            follow_redirects=True)
        else:
            assert len(outbox) == 0

    # 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=user_info['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=new_email,
                                   captcha='xyzzy'))
        assert outbox.pop().send_to == {new_email}
コード例 #28
0
def test_change_password_recovery_email(client, user_info, test_config):
    """The user can change their password recovery email."""
    register_user(client, user_info)
    new_email = "*****@*****.**"
    assert new_email != user_info["email"]

    rv = client.get(url_for("user.edit_account"))
    data = dict(
        csrf_token=csrf_token(rv.data),
        oldpassword=user_info["password"],
        password="",
        confirm="",
    )
    if email_validation_is_required():
        data["email_required"] = new_email
    else:
        data["email_optional"] = new_email

    with mail.record_messages() as outbox:
        rv = client.post(url_for("do.edit_account"),
                         data=data,
                         follow_redirects=True)
        log_out_current_user(client)

        if email_validation_is_required():
            message = outbox.pop()

            # Make sure that password recovery emails go to the former address
            # if the new one has not yet been confirmed.
            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 outbox.pop().send_to == {user_info["email"]}

            # Now click the confirm link.
            assert message.send_to == {new_email}
            soup = BeautifulSoup(message.html, "html.parser")
            token = soup.a["href"].split("/")[-1]
            rv = client.get(url_for("user.confirm_email_change", token=token),
                            follow_redirects=True)
        else:
            assert len(outbox) == 0

    # 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=user_info["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=new_email,
                      captcha="xyzzy"),
        )
        assert outbox.pop().send_to == {new_email}
コード例 #29
0
ファイル: test_auth.py プロジェクト: steadyember/throat
def test_invite_code_required_for_registration(client, user_info, user2_info):
    "If invite codes are required, trying to register without one will fail."
    register_user(client, user_info)
    promote_user_to_admin(client, user_info)

    # Enable invite codes.
    rv = client.get(url_for('admin.invitecodes'))
    data = dict(csrf_token=csrf_token(rv.data),
                enableinvitecode=True,
                minlevel=3,
                maxcodes=10)

    rv = client.post(url_for('do.use_invite_code'),
                     data=data,
                     follow_redirects=True)
    reply = json.loads(rv.data.decode('utf-8'))
    assert reply['status'] == 'ok'

    # Create an invite code.
    rv = client.get(url_for('admin.invitecodes'))
    data = dict(csrf_token=csrf_token(rv.data),
                code="abcde",
                uses=10,
                expires='')
    rv = client.post(url_for('admin.invitecodes'),
                     data=data,
                     follow_redirects=True)

    log_out_current_user(client)

    # Now try to register a new user without an invite code.
    rv = client.get(url_for('auth.register'))
    data = dict(csrf_token=csrf_token(rv.data),
                username=user2_info['username'],
                password=user2_info['password'],
                confirm=user2_info['password'],
                invitecode='',
                email_optional=user2_info['email'],
                accept_tos=True,
                captcha='xyzzy')

    rv = client.post(url_for('auth.register'),
                     data=data,
                     follow_redirects=True)
    assert b'Invalid invite code' in rv.data

    # Now try to register a new user with an incorrect invite code.
    rv = client.get(url_for('auth.register'))
    data = dict(csrf_token=csrf_token(rv.data),
                username=user2_info['username'],
                password=user2_info['password'],
                confirm=user2_info['password'],
                invitecode='xyzzy',
                email_optional=user2_info['email'],
                accept_tos=True,
                captcha='xyzzy')

    rv = client.post(url_for('auth.register'),
                     data=data,
                     follow_redirects=True)
    assert b'Invalid invite code' in rv.data

    # Now try to register a new user with a valid invite code.
    rv = client.get(url_for('auth.register'))
    data = dict(csrf_token=csrf_token(rv.data),
                username=user2_info['username'],
                password=user2_info['password'],
                confirm=user2_info['password'],
                invitecode='abcde',
                email_optional=user2_info['email'],
                accept_tos=True,
                captcha='xyzzy')

    rv = client.post(url_for('auth.register'),
                     data=data,
                     follow_redirects=True)
    assert b'Log out' in rv.data
コード例 #30
0
def test_logout_and_login_again(client, user_info):
    """A logged in user can log out and back in again."""
    register_user(client, user_info)
    assert b"Log out" in client.get(url_for("home.index")).data
    log_out_current_user(client, verify=True)
    log_in_user(client, user_info, expect_success=True)