Exemple #1
0
def test_register_generic_pwchange_error(client, cleanup_dummy_user):
    """Change user's password with an unhandled error"""
    ipa_client = mock.Mock()
    ipa_client.change_password.side_effect = python_freeipa.exceptions.FreeIPAError(
        message="something went wrong", code="4242")
    with mock.patch("securitas.controller.registration.untouched_ipa_client",
                    lambda a: ipa_client):
        result = client.post(
            '/register',
            data={
                "firstname": "First",
                "lastname": "Last",
                "username": "******",
                "password": "******",
                "password_confirm": "password",
            },
        )
    assert_redirects_with_flash(
        result,
        expected_url="/login",
        expected_message=
        ('Your account has been created, but an error occurred while setting your '
         'password (something went wrong). You may need to change it after logging in.'
         ),
        expected_category="warning",
    )
def test_ask_post(client, dummy_user, patched_lock):
    with mailer.record_messages() as outbox:
        result = client.post('/forgot-password/ask', data={"username": "******"})
    # Confirmation message
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message=(
            "An email has been sent to your address with instructions on how to reset "
            "your password"
        ),
        expected_category="success",
    )
    # Sent email
    assert len(outbox) == 1
    message = outbox[0]
    assert message.subject == "Password reset procedure"
    assert message.recipients == ["*****@*****.**"]
    # Valid token
    token_match = re.search(r"\?token=([^\s\"']+)", message.body)
    assert token_match is not None
    token = token_match.group(1)
    token_data = jwt.decode(
        token, current_app.config["SECRET_KEY"], algorithms=["HS256"]
    )
    assert token_data.get("username") == "dummy"
    assert "last_change" in token_data
    # Lock activated
    patched_lock["store"].assert_called_once()
def test_change_invalid_token(client):
    result = client.get('/forgot-password/change?token=this-is-invalid')
    assert_redirects_with_flash(
        result,
        expected_url="/forgot-password/ask",
        expected_message="The token is invalid, please request a new one.",
        expected_category="warning",
    )
def test_change_no_token(client):
    result = client.get('/forgot-password/change')
    assert_redirects_with_flash(
        result,
        expected_url="/forgot-password/ask",
        expected_message="No token provided, please request one.",
        expected_category="warning",
    )
Exemple #5
0
def test_group_remove_member_invalid_form(client, dummy_user_as_group_manager):
    """Test an invalid form when removing a member from a group"""
    result = client.post('/group/dummy-group/members/remove', data={})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message="Username must not be empty",
        expected_category="danger",
    )
Exemple #6
0
def test_user_edit_post(client, logged_in_dummy_user):
    """Test posting to the user edit page: /user/<username>/edit/"""
    result = client.post('/user/dummy/edit/', data=POST_CONTENTS)
    assert_redirects_with_flash(
        result,
        expected_url="/user/dummy/",
        expected_message="Profile has been succesfully updated.",
        expected_category="success",
    )
Exemple #7
0
def test_user_unauthed(client):
    """Check that when unauthed, the user page redirects back to /."""
    result = client.get('/user/dudemcpants/')
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="Please log in to continue.",
        expected_category="warning",
    )
def test_change_not_active(client, token_for_dummy_user, patched_lock):
    result = client.get(f'/forgot-password/change?token={token_for_dummy_user}')
    patched_lock["delete"].assert_called_once()
    assert_redirects_with_flash(
        result,
        expected_url="/forgot-password/ask",
        expected_message="The token has expired, please request a new one.",
        expected_category="warning",
    )
Exemple #9
0
def test_group_add_unknown_member(client, dummy_user_as_group_manager):
    """Test adding a non-existent member to a group"""
    result = client.post('/group/dummy-group/members/',
                         data={"new_member_username": "******"})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message="User testuser was not found in the system.",
        expected_category="danger",
    )
Exemple #10
0
def test_group_add_member(client, dummy_user_as_group_manager, make_user):
    """Test adding a member to a group"""
    make_user("testuser")
    result = client.post('/group/dummy-group/members/',
                         data={"new_member_username": "******"})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message="You got it! testuser has been added to dummy-group.",
        expected_category="success",
    )
def test_change_too_old(client, token_for_dummy_user, patched_lock):
    passed_expiry = datetime.datetime.now() - datetime.timedelta(minutes=1)
    patched_lock["valid_until"].return_value = passed_expiry
    result = client.get(f'/forgot-password/change?token={token_for_dummy_user}')
    patched_lock["delete"].assert_called_once()
    assert_redirects_with_flash(
        result,
        expected_url="/forgot-password/ask",
        expected_message="The token has expired, please request a new one.",
        expected_category="warning",
    )
Exemple #12
0
def test_user_edit_no_permission(method, client, logged_in_dummy_user):
    """Verify that a user can't be changed by another user."""
    result = client.open(
        "/user/dudemcpants/edit/",
        method=method,
        data=POST_CONTENTS if method == "POST" else None,
    )
    assert_redirects_with_flash(
        result,
        expected_url="/user/dudemcpants/",
        expected_message="You do not have permission to edit this account.",
        expected_category="danger",
    )
Exemple #13
0
def test_group_remove_member(client, dummy_user_as_group_manager, make_user):
    """Test removing a member from a group"""
    make_user("testuser")
    ipa_admin.group_add_member("dummy-group", users="testuser")
    result = client.post('/group/dummy-group/members/remove',
                         data={"username": "******"})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message=
        "You got it! testuser has been removed from dummy-group.",
        expected_category="success",
    )
Exemple #14
0
def test_password_changes(client, dummy_user, no_password_min_time):
    """Verify that password changes"""
    result = client.post(
        '/password-reset?username=dummy',
        data={
            "current_password": "******",
            "password": "******",
            "password_confirm": "secretpw",
        },
    )
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="Your password has been changed",
        expected_category="success",
    )
Exemple #15
0
def test_login_expired_password(client, dummy_user_expired_password):
    """Test a successful Login with an expired password"""
    result = client.post(
        '/login',
        data={"username": "******", "password": "******"},
        follow_redirects=False,
    )
    assert_redirects_with_flash(
        result,
        expected_url="/password-reset?username=dummy",
        expected_message="Password expired. Please reset it.",
        expected_category="danger",
    )
    # We are not logged in
    assert "securitas_session" not in session
    assert "securitas_username" not in session
Exemple #16
0
def test_password_changes_wrong_user(client, logged_in_dummy_user):
    """Verify that we error if trying to change another user's password"""
    result = client.post(
        '/user/admin/password-reset',
        data={
            "username": "******",
            "current_password": "******",
            "password": "******",
            "password_confirm": "secretpw",
        },
    )
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="You do not have permission to edit this account.",
        expected_category="danger",
    )
Exemple #17
0
def test_group_remove_self(client, logged_in_dummy_user, dummy_group):
    """Test a non-sponsor user removing themselves from a group"""
    ipa_admin.group_add_member("dummy-group", users="dummy")
    result = client.get('/group/dummy-group/')
    assert result.status_code == 200
    page = BeautifulSoup(result.data, 'html.parser')
    leave_btn = page.select_one("#leave-group-btn")
    assert leave_btn.get_text(strip=True) == "Leave group"

    result = client.post('/group/dummy-group/members/remove',
                         data={"username": "******"})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message="You got it! dummy has been removed from dummy-group.",
        expected_category="success",
    )
def test_ask_no_smtp(client, dummy_user, patched_lock):
    with mock.patch("securitas.controller.password.mailer") as mailer:
        mailer.send.side_effect = ConnectionRefusedError
        with mock.patch("securitas.controller.password.app.logger") as logger:
            result = client.post('/forgot-password/ask', data={"username": "******"})
    # Email
    mailer.send.assert_called_once()
    # Lock untouched
    patched_lock["store"].assert_not_called()
    # Error message
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="We could not send you an email, please retry later",
        expected_category="danger",
    )
    # Log message
    logger.error.assert_called_once()
def test_change_post(client, dummy_user, token_for_dummy_user, patched_lock_active):
    with mock.patch("securitas.controller.password.app.logger") as logger:
        result = client.post(
            f'/forgot-password/change?token={token_for_dummy_user}',
            data={"password": "******", "password_confirm": "newpassword"},
        )
    patched_lock_active["delete"].assert_called()
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="Your password has been changed.",
        expected_category="success",
    )
    # Log message
    logger.info.assert_called_once()
    log_msg = logger.info.call_args[0][0]
    assert "dummy" in log_msg
    assert "newpassword" not in log_msg
Exemple #20
0
def test_password_changes_user(client, logged_in_dummy_user, dummy_group,
                               no_password_min_time):
    """Verify that password changes"""
    ipa_admin.group_add_member("dummy-group", users="dummy")
    result = client.post(
        '/user/dummy/password-reset',
        data={
            "username": "******",
            "current_password": "******",
            "password": "******",
            "password_confirm": "secretpw",
        },
    )
    assert_redirects_with_flash(
        result,
        expected_url="/",
        expected_message="Your password has been changed",
        expected_category="success",
    )
Exemple #21
0
def test_group_remove_member_invalid(client, dummy_user_as_group_manager):
    """Test failure when removing a member from a group"""
    with mock.patch(
            "securitas.security.ipa.Client.group_remove_member") as method:
        method.side_effect = python_freeipa.exceptions.ValidationError(
            message={
                "member": {
                    "user": [("testuser", "something went wrong")],
                    "group": []
                }
            },
            code="4242",
        )
        result = client.post('/group/dummy-group/members/remove',
                             data={"username": "******"})
    assert_redirects_with_flash(
        result,
        expected_url="/group/dummy-group/",
        expected_message="Unable to remove user testuser: something went wrong",
        expected_category="danger",
    )
Exemple #22
0
def test_register_short_password(client, cleanup_dummy_user):
    """Register a user with too short a password"""
    result = client.post(
        '/register',
        data={
            "firstname": "First",
            "lastname": "Last",
            "username": "******",
            "password": "******",
            "password_confirm": "42",
        },
    )
    assert_redirects_with_flash(
        result,
        expected_url="/login",
        expected_message=
        ('Your account has been created, but the password you chose does not comply '
         'with the policy (Constraint violation: Password is too short) and has thus '
         'been set as expired. You will be asked to change it after logging in.'
         ),
        expected_category="warning",
    )
def test_change_recent_password_change(
    client,
    dummy_user,
    dummy_group,
    token_for_dummy_user,
    no_password_min_time,
    patched_lock_active,
):
    ipa_admin.group_add_member("dummy-group", users="dummy")
    ipa = untouched_ipa_client(current_app)
    ipa.change_password("dummy", "dummy_password", "dummy_password")
    result = client.get(f'/forgot-password/change?token={token_for_dummy_user}')
    patched_lock_active["delete"].assert_called_once()
    assert_redirects_with_flash(
        result,
        expected_url="/forgot-password/ask",
        expected_message=(
            "Your password has been changed since you requested this token, please "
            "request a new one."
        ),
        expected_category="warning",
    )
def test_change_post_password_too_short(
    client, dummy_user, token_for_dummy_user, patched_lock_active
):
    with mock.patch("securitas.controller.password.app.logger") as logger:
        result = client.post(
            f'/forgot-password/change?token={token_for_dummy_user}',
            data={"password": "******", "password_confirm": "42"},
        )
    assert_redirects_with_flash(
        result,
        expected_url="/login",
        expected_message=(
            'Your password has been changed, but it does not comply '
            'with the policy (Constraint violation: Password is too short) and has thus '
            'been set as expired. You will be asked to change it after logging in.'
        ),
        expected_category="warning",
    )
    patched_lock_active["delete"].assert_called()
    logger.info.assert_called_with(
        "Password for dummy was changed to a non-compliant password after completing "
        "the forgotten password process."
    )