Ejemplo n.º 1
0
def test_toggle_perm_audited(groups, permissions, http_client, base_url):  # noqa: F811
    perm_name = "audited"  # perm that is already audited
    nonpriv_user_name = "*****@*****.**"  # user with no audit perms and without PERMISSION_ADMIN
    nonpriv_user_team = "sad-team"
    nonpriv_headers = {"X-Grouper-User": nonpriv_user_name}
    priv_user_name = "*****@*****.**"  # user with AUDIT_MANAGER
    priv_headers = {"X-Grouper-User": priv_user_name}
    enable_url = url(base_url, "/permissions/{}/enable-auditing".format(perm_name))
    disable_url = url(base_url, "/permissions/{}/disable-auditing".format(perm_name))

    # Give nonpriv user audit view permissions, which shouldn't allow enabling/disabling auditing
    grant_permission(groups[nonpriv_user_team], permissions[AUDIT_VIEWER], argument="")

    # attempt to enable/disable auditing; both should fail due to lack of perms
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(enable_url, method="POST", headers=nonpriv_headers, body="")
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(
            disable_url, method="POST", headers=nonpriv_headers, body=""
        )

    # Now confirm that enabling/disabling auditing works as a privileged user
    # Note that enabling audits on an audited perm succeeds (same for disabling)
    resp = yield http_client.fetch(enable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm is still audited
    resp = yield http_client.fetch(disable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm no longer audited
    resp = yield http_client.fetch(disable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm still not audited
    resp = yield http_client.fetch(enable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
Ejemplo n.º 2
0
def test_remove_last_owner_via_audit(async_server, browser, users, groups, session):  # noqa: F811
    future = datetime.utcnow() + timedelta(1)

    add_member(groups["auditors"], users["*****@*****.**"], role="owner")
    add_member(groups["audited-team"], users["*****@*****.**"], role="owner", expiration=future)

    session.commit()

    fe_url = url(async_server, "/audits/create")
    browser.get(fe_url)

    page = AuditsCreatePage(browser)

    page.set_end_date(future.strftime("%m/%d/%Y"))
    page.submit()

    fe_url = url(async_server, "/groups/audited-team")
    browser.get(fe_url)

    page = GroupViewPage(browser)

    audit_modal = page.get_audit_modal()
    audit_modal.find_member_row("*****@*****.**").set_audit_status("remove")
    audit_modal.confirm()

    assert page.current_url.endswith("/groups/audited-team")
    assert page.has_text(group_ownership_policy.EXCEPTION_MESSAGE)
Ejemplo n.º 3
0
def test_require_clickthru(tmpdir: LocalPath, setup: SetupTest,
                           browser: Chrome) -> None:
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups"))
        groups_page = GroupsViewPage(browser)

        groups_page.click_create_group_button()
        create_group_modal = groups_page.get_create_group_modal()
        create_group_modal.set_group_name("test-group")
        create_group_modal.set_join_policy(GroupJoinPolicy.CAN_JOIN)
        create_group_modal.click_require_clickthru_checkbox()
        create_group_modal.confirm()

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/test-group/join"))
        join_page = GroupJoinPage(browser)

        join_page.set_reason("Testing")
        join_page.submit()
        clickthru_modal = join_page.get_clickthru_modal()
        clickthru_modal.confirm()

        group_page = GroupViewPage(browser)
        assert group_page.current_url.endswith(
            "/groups/test-group?refresh=yes")
        assert group_page.find_member_row("*****@*****.**")
Ejemplo n.º 4
0
def test_public_key_admin(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_public_keys_of_user(session, user.id)

    # add it
    fe_url = url(base_url, "/users/{}/public-key/add".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"public_key": SSH_KEY_1}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_1

    # have an admin delete it
    fe_url = url(base_url, "/users/{}/public-key/{}/delete".format(user.username, keys[0].id))
    resp = yield http_client.fetch(
        fe_url, method="POST", body="", headers={"X-Grouper-User": "******"}
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    assert not get_public_keys_of_user(session, user.id)
Ejemplo n.º 5
0
def test_service_account_lifecycle(async_server, browser):  # noqa: F811
    browser.get(url(async_server, "/groups/user-admins"))

    page = GroupViewPage(browser)
    page.click_add_service_account_button()

    page = ServiceAccountCreatePage(browser)
    page.set_name("my-special-service-account")
    page.submit()

    page = ServiceAccountViewPage(browser)
    page.click_disable_button()

    disable_modal = page.get_disable_modal()
    disable_modal.confirm()

    browser.get(url(async_server, "/users"))

    page = UsersViewPage(browser)
    page.click_show_disabled_users_button()
    page.click_show_service_accounts_button()

    user_row = page.find_user_row("[email protected] (service)")
    user_row.click()

    page = ServiceAccountViewPage(browser)
    page.click_enable_button()

    page = ServiceAccountEnablePage(browser)
    page.select_owner("Group: user-admins")
    page.submit()
Ejemplo n.º 6
0
def test_shell(session, users, http_client, base_url, graph):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)

    set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/bash")
    graph.update_from_db(session)

    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    assert body["data"]["user"]["metadata"] != [], "There should be metadata"
    assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!"
    assert (
        body["data"]["user"]["metadata"][0]["data_key"] == "shell"
    ), "There should only be 1 metadata!"
    assert (
        body["data"]["user"]["metadata"][0]["data_value"] == "/bin/bash"
    ), "The shell should be set to the correct value"

    set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/zsh")
    graph.update_from_db(session)

    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    assert body["data"]["user"]["metadata"] != [], "There should be metadata"
    assert (
        body["data"]["user"]["metadata"][0]["data_key"] == "shell"
    ), "There should only be 1 metadata!"
    assert (
        body["data"]["user"]["metadata"][0]["data_value"] == "/bin/zsh"
    ), "The shell should be set to the correct value"
    assert len(body["data"]["user"]["metadata"]) == 1, "There should only be 1 metadata!"
Ejemplo n.º 7
0
def test_user_tok_acls(
    session, graph, users, user_admin_perm_to_auditors, http_client, base_url  # noqa: F811
):
    role_user = "******"
    admin = "*****@*****.**"
    pleb = "*****@*****.**"

    # admin creating token for role user
    fe_url = url(base_url, "/users/{}/tokens/add".format(role_user))
    resp = yield http_client.fetch(
        fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({"name": "foo"})
    )
    assert resp.code == 200

    with pytest.raises(HTTPError):
        # non-admin creating token for role user
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            headers={"X-Grouper-User": pleb},
            body=urlencode({"name": "foo2"}),
        )

    fe_url = url(base_url, "/users/{}/tokens/add".format(pleb))
    with pytest.raises(HTTPError):
        # admin creating token for normal (non-role) user
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            headers={"X-Grouper-User": admin},
            body=urlencode({"name": "foo3"}),
        )
Ejemplo n.º 8
0
def test_group_request(session, users, groups, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    group = groups["sad-team"]

    # Request to join

    fe_url = url(base_url, "/groups/{}/join".format(group.groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        headers={"X-Grouper-User": user.username},
        body=urlencode({"reason": "Test Request", "member": "User: [email protected]"}),
    )
    assert resp.code == 200

    request = Request.get(session, requester_id=user.id, requesting_id=group.id)
    assert request.status == "pending"

    # Approve request

    fe_url = url(base_url, "/groups/{}/requests/{}".format(group.groupname, request.id))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        headers={"X-Grouper-User": "******"},
        body=urlencode({"reason": "Test Request", "status": "actioned"}),
    )
    assert resp.code == 200

    request = Request.get(session, requester_id=user.id, requesting_id=group.id)
    assert request.status == "actioned"
Ejemplo n.º 9
0
def test_public_key(session, users, http_client, base_url):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_public_keys_of_user(session, user.id)

    # add it
    fe_url = url(base_url, "/users/{}/public-key/add".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"public_key": SSH_KEY_ED25519}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    keys = get_public_keys_of_user(session, user.id)
    assert len(keys) == 1
    assert keys[0].public_key == SSH_KEY_ED25519
    assert keys[0].fingerprint == "fa:d9:ca:40:bd:f7:64:37:a7:99:3a:8e:50:8a:c5:94"
    assert keys[0].fingerprint_sha256 == "ExrCZ0nqSJv+LqAEh8CWeKUxiAeZA+N0bKC18dK7Adg"
    assert keys[0].comment == "comment"

    # delete it
    fe_url = url(base_url, "/users/{}/public-key/{}/delete".format(user.username, keys[0].id))
    resp = yield http_client.fetch(
        fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)
    assert not get_public_keys_of_user(session, user.id)
Ejemplo n.º 10
0
def test_service_accounts(session, standard_graph, users, http_client, base_url):  # noqa: F811
    api_url = url(base_url, "/service_accounts")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["service_accounts"]) == sorted(
        [u.name for u in itervalues(users) if u.role_user] + ["*****@*****.**"]
    )

    # Retrieve a single service account and check its metadata.
    api_url = url(base_url, "/service_accounts/[email protected]")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    data = body["data"]["user"]
    assert "service_account" in data
    assert data["service_account"]["description"] == "some service account"
    assert data["service_account"]["machine_set"] == "some machines"
    assert data["service_account"]["owner"] == "team-sre"
    assert body["data"]["permissions"] == []

    # Delegate a permission to the service account and check for it.
    service_account = ServiceAccount.get(session, name="*****@*****.**")
    permission = get_permission(session, "team-sre")
    grant_permission_to_service_account(session, service_account, permission, "*")
    standard_graph.update_from_db(session)
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    perms = body["data"]["permissions"]
    assert perms[0]["permission"] == "team-sre"
    assert perms[0]["argument"] == "*"
Ejemplo n.º 11
0
def test_disabling_group_clears_audit(tmpdir: LocalPath, setup: SetupTest,
                                      browser: Chrome) -> None:
    future = datetime.utcnow() + timedelta(days=60)

    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group", role="owner")
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.create_permission("some-permission", audited=True)
        setup.grant_permission_to_group("some-permission", "argument",
                                        "some-group")
        setup.add_user_to_group("*****@*****.**", "auditors")
        setup.grant_permission_to_group(AUDIT_VIEWER, "", "auditors")
        setup.grant_permission_to_group(AUDIT_MANAGER, "", "auditors")
        setup.grant_permission_to_group(PERMISSION_AUDITOR, "", "auditors")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/audits/create"))

        create_page = AuditsCreatePage(browser)
        create_page.set_end_date(future.strftime("%m/%d/%Y"))
        create_page.submit()

        browser.get(url(frontend_url, "/groups/some-group"))

        group_page = GroupViewPage(browser)
        assert group_page.subheading == "some-group AUDIT IN PROGRESS"

    # Check that this created email reminder messages to the group owner.  We have to refresh the
    # session since otherwise SQLite may not see changes.
    setup.reopen_database()
    group = Group.get(setup.session, name="some-group")
    assert group
    expected_key = f"audit-{group.id}"
    emails = setup.session.query(AsyncNotification).filter_by(
        sent=False, email="*****@*****.**").all()
    assert len(emails) > 0
    assert all((e.key is None or e.key == expected_key for e in emails))
    assert all(("Group Audit" in e.subject for e in emails))

    # Now, disable the group, which should complete the audit.
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/some-group"))
        page = GroupViewPage(browser)

        audit_modal = page.get_audit_modal()
        audit_modal.click_close_button()
        page.wait_until_audit_modal_clears()
        page.click_disable_button()
        modal = page.get_disable_modal()
        modal.confirm()

        assert page.subheading == "some-group (disabled)"

    # And now all of the email messages should be marked sent except the immediate one (the one
    # that wasn't created with async_send_email).
    setup.reopen_database()
    emails = setup.session.query(AsyncNotification).filter_by(
        sent=False, email="*****@*****.**").all()
    assert len(emails) == 1
    assert emails[0].key is None
Ejemplo n.º 12
0
def test_remove_last_owner_via_audit(tmpdir: LocalPath, setup: SetupTest,
                                     browser: Chrome) -> None:
    future = datetime.utcnow() + timedelta(1)

    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "audited-team", role="owner")
        setup.create_permission("audited", audited=True)
        setup.grant_permission_to_group("audited", "", "audited-team")
        setup.add_user_to_group("*****@*****.**", "auditors")
        setup.add_user_to_group("*****@*****.**", "auditors", role="owner")
        setup.grant_permission_to_group(AUDIT_VIEWER, "", "auditors")
        setup.grant_permission_to_group(AUDIT_MANAGER, "", "auditors")
        setup.grant_permission_to_group(PERMISSION_AUDITOR, "", "auditors")
        setup.add_user_to_group("*****@*****.**",
                                "audited-team",
                                role="owner",
                                expiration=future)

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/audits/create"))

        create_page = AuditsCreatePage(browser)
        create_page.set_end_date(future.strftime("%m/%d/%Y"))
        create_page.submit()

        browser.get(url(frontend_url, "/groups/audited-team"))
        group_page = GroupViewPage(browser)
        audit_modal = group_page.get_audit_modal()
        audit_modal.find_member_row("*****@*****.**").set_audit_status("remove")
        audit_modal.confirm()

        assert group_page.current_url.endswith("/groups/audited-team")
        assert group_page.has_alert(group_ownership_policy.EXCEPTION_MESSAGE)
Ejemplo n.º 13
0
def test_list_pagination(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    """Test pagination.

    This forces the pagination to specific values, rather than using the page controls, since we
    don't create more than 100 permissions for testing.
    """
    permissions = create_test_data(setup)
    settings = FrontendSettings()
    settings.update_from_config(src_path("config", "dev.yaml"))
    expected_permissions = [
        (p.name, p.description, format_date(settings, p.created_on)) for p in permissions
    ]

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions?limit=1&offset=1"))
        page = PermissionsPage(browser)
        seen_permissions = [(r.name, r.description, r.created_on) for r in page.permission_rows]
        assert seen_permissions == sorted(expected_permissions)[1:2]
        assert page.limit_label == "Limit: 1"

        # Retrieve the last permission but with a larger limit to test that the limit isn't capped
        # to the number of returned items.
        browser.get(url(frontend_url, "/permissions?limit=10&offset=2"))
        page = PermissionsPage(browser)
        seen_permissions = [(r.name, r.description, r.created_on) for r in page.permission_rows]
        assert seen_permissions == sorted(expected_permissions)[2:]
        assert page.limit_label == "Limit: 10"
Ejemplo n.º 14
0
def test_permission_grant_denied(tmpdir: LocalPath, setup: SetupTest,
                                 browser: Chrome) -> None:
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.add_user_to_group("*****@*****.**", "other-group")
        setup.grant_permission_to_group("some-permission", "foo", "some-group")
        setup.create_service_account("*****@*****.**", "some-group")

    # Member of the owning team will get denied when trying to grant a perm the team doesn't have
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(
            url(frontend_url,
                "/groups/some-group/service/[email protected]/grant"))

        page = ServiceAccountGrantPermissionPage(browser)
        page.select_permission("some-permission (foo)")
        page.set_argument("bar")
        page.submit()

        assert page.has_alert("Permission denied")

    # Unrelated user can click the Add Permission button but will get a 403
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(
            url(frontend_url,
                "/groups/some-group/service/[email protected]"))

        view_page = ServiceAccountViewPage(browser)
        assert len(view_page.permission_rows) == 0
        view_page.click_add_permission_button()

        forbidden_page = ErrorPage(browser)
        assert forbidden_page.heading == "Error"
        assert forbidden_page.subheading == "403 Forbidden"
def test_service_account_lifecycle(async_server, browser):  # noqa: F811
    browser.get(url(async_server, "/groups/user-admins"))

    page = GroupViewPage(browser)
    page.click_add_service_account_button()

    page = ServiceAccountCreatePage(browser)
    page.set_name("my-special-service-account")
    page.submit()

    page = ServiceAccountViewPage(browser)
    page.click_disable_button()

    disable_modal = page.get_disable_modal()
    disable_modal.confirm()

    browser.get(url(async_server, "/users"))

    page = UsersViewPage(browser)
    page.click_show_disabled_users_button()
    page.click_show_service_accounts_button()

    user_row = page.find_user_row(
        "[email protected] (service)")
    user_row.click()

    page = ServiceAccountViewPage(browser)
    page.click_enable_button()

    page = ServiceAccountEnablePage(browser)
    page.select_owner("Group: user-admins")
    page.submit()
Ejemplo n.º 16
0
def test_user_tok_acls(
    session, graph, users, user_admin_perm_to_auditors, http_client, base_url  # noqa: F811
):
    role_user = "******"
    admin = "*****@*****.**"
    pleb = "*****@*****.**"

    # admin creating token for role user
    fe_url = url(base_url, "/users/{}/tokens/add".format(role_user))
    resp = yield http_client.fetch(
        fe_url, method="POST", headers={"X-Grouper-User": admin}, body=urlencode({"name": "foo"})
    )
    assert resp.code == 200

    with pytest.raises(HTTPError):
        # non-admin creating token for role user
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            headers={"X-Grouper-User": pleb},
            body=urlencode({"name": "foo2"}),
        )

    fe_url = url(base_url, "/users/{}/tokens/add".format(pleb))
    with pytest.raises(HTTPError):
        # admin creating token for normal (non-role) user
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            headers={"X-Grouper-User": admin},
            body=urlencode({"name": "foo3"}),
        )
Ejemplo n.º 17
0
def test_toggle_perm_audited(groups, permissions, http_client, base_url):  # noqa: F811
    perm_name = "audited"  # perm that is already audited
    nonpriv_user_name = "*****@*****.**"  # user with no audit perms and without PERMISSION_ADMIN
    nonpriv_user_team = "sad-team"
    nonpriv_headers = {"X-Grouper-User": nonpriv_user_name}
    priv_user_name = "*****@*****.**"  # user with AUDIT_MANAGER
    priv_headers = {"X-Grouper-User": priv_user_name}
    enable_url = url(base_url, "/permissions/{}/enable-auditing".format(perm_name))
    disable_url = url(base_url, "/permissions/{}/disable-auditing".format(perm_name))

    # Give nonpriv user audit view permissions, which shouldn't allow enabling/disabling auditing
    grant_permission(groups[nonpriv_user_team], permissions[AUDIT_VIEWER], argument="")

    # attempt to enable/disable auditing; both should fail due to lack of perms
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(enable_url, method="POST", headers=nonpriv_headers, body="")
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(
            disable_url, method="POST", headers=nonpriv_headers, body=""
        )

    # Now confirm that enabling/disabling auditing works as a privileged user
    # Note that enabling audits on an audited perm succeeds (same for disabling)
    resp = yield http_client.fetch(enable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm is still audited
    resp = yield http_client.fetch(disable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm no longer audited
    resp = yield http_client.fetch(disable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
    # Perm still not audited
    resp = yield http_client.fetch(enable_url, method="POST", headers=priv_headers, body="")
    assert resp.code == 200
Ejemplo n.º 18
0
def test_shell(session, users, http_client, base_url, graph):  # noqa: F811
    user = users["*****@*****.**"]
    assert not get_user_metadata_by_key(session, user.id,
                                        USER_METADATA_SHELL_KEY)

    set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/bash")
    graph.update_from_db(session)

    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    assert body["data"]["user"]["metadata"] != [], "There should be metadata"
    assert len(body["data"]["user"]
               ["metadata"]) == 1, "There should only be 1 metadata!"
    assert (body["data"]["user"]["metadata"][0]["data_key"] == "shell"
            ), "There should only be 1 metadata!"
    assert (body["data"]["user"]["metadata"][0]["data_value"] == "/bin/bash"
            ), "The shell should be set to the correct value"

    set_user_metadata(session, user.id, USER_METADATA_SHELL_KEY, "/bin/zsh")
    graph.update_from_db(session)

    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    assert body["data"]["user"]["metadata"] != [], "There should be metadata"
    assert (body["data"]["user"]["metadata"][0]["data_key"] == "shell"
            ), "There should only be 1 metadata!"
    assert (body["data"]["user"]["metadata"][0]["data_value"] == "/bin/zsh"
            ), "The shell should be set to the correct value"
    assert len(body["data"]["user"]
               ["metadata"]) == 1, "There should only be 1 metadata!"
Ejemplo n.º 19
0
def test_list_groups(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.create_group("one-group", "Some group", GroupJoinPolicy.CAN_JOIN)
        setup.create_group("another-group", "Another group", GroupJoinPolicy.CAN_ASK)
        setup.create_group("private", join_policy=GroupJoinPolicy.NOBODY)

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups"))
        page = GroupsViewPage(browser)

        group_row = page.find_group_row("one-group")
        assert group_row.name == "one-group"
        assert group_row.href == url(frontend_url, "/groups/one-group")
        assert group_row.description == "Some group"
        assert group_row.can_join == "Anyone"

        group_row = page.find_group_row("another-group")
        assert group_row.name == "another-group"
        assert group_row.href == url(frontend_url, "/groups/another-group")
        assert group_row.description == "Another group"
        assert group_row.can_join == "Must Ask"

        group_row = page.find_group_row("private")
        assert group_row.name == "private"
        assert group_row.href == url(frontend_url, "/groups/private")
        assert group_row.description == ""
        assert group_row.can_join == "Nobody"
Ejemplo n.º 20
0
def test_list_pagination(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    """Test pagination.

    This forces the pagination to specific values, rather than using the page controls, since we
    don't create more than 100 permissions for testing.
    """
    permissions = create_test_data(setup)
    settings = FrontendSettings()
    settings.update_from_config(src_path("config", "dev.yaml"))
    expected_permissions = [
        (p.name, p.description, format_date(settings, p.created_on)) for p in permissions
    ]

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions?limit=1&offset=1"))
        page = PermissionsPage(browser)
        seen_permissions = [(r.name, r.description, r.created_on) for r in page.permission_rows]
        assert seen_permissions == sorted(expected_permissions)[1:2]
        assert page.limit_label == "Limit: 1"

        # Retrieve the last permission but with a larger limit to test that the limit isn't capped
        # to the number of returned items.
        browser.get(url(frontend_url, "/permissions?limit=10&offset=2"))
        page = PermissionsPage(browser)
        seen_permissions = [(r.name, r.description, r.created_on) for r in page.permission_rows]
        assert seen_permissions == sorted(expected_permissions)[2:]
        assert page.limit_label == "Limit: 10"
Ejemplo n.º 21
0
def test_remove_last_owner_via_audit(async_server, browser, users, groups, session):  # noqa: F811
    future = datetime.utcnow() + timedelta(1)

    add_member(groups["auditors"], users["*****@*****.**"], role="owner")
    add_member(groups["audited-team"], users["*****@*****.**"], role="owner", expiration=future)

    session.commit()

    fe_url = url(async_server, "/audits/create")
    browser.get(fe_url)

    page = AuditsCreatePage(browser)

    page.set_end_date(future.strftime("%m/%d/%Y"))
    page.submit()

    fe_url = url(async_server, "/groups/audited-team")
    browser.get(fe_url)

    page = GroupViewPage(browser)

    audit_modal = page.get_audit_modal()
    audit_modal.find_member_row("*****@*****.**").set_audit_status("remove")
    audit_modal.confirm()

    assert page.current_url.endswith("/groups/audited-team")
    assert page.has_text(group_ownership_policy.EXCEPTION_MESSAGE)
Ejemplo n.º 22
0
def test_request_logging(session, users, http_client, base_url):  # noqa: F811
    """Test that the fe request handlers properly log stats"""
    mock_plugin = Mock()
    get_plugin_proxy().add_plugin(mock_plugin)

    user = users["*****@*****.**"]
    fe_url = url(base_url, "/users")
    start_time = time.time()
    resp = yield http_client.fetch(fe_url,
                                   method="GET",
                                   headers={"X-Grouper-User": user.username})
    duration_ms = (time.time() - start_time) * 1000
    assert resp.code == 200
    assert mock_plugin.log_request.call_count == 1
    assert mock_plugin.log_request.call_args_list[0][0][0] == "UsersView"
    assert mock_plugin.log_request.call_args_list[0][0][1] == 200
    # the reported value should be within 1s of our own observation
    assert abs(mock_plugin.log_request.call_args_list[0][0][2] -
               duration_ms) <= 1000

    mock_plugin.log_request.reset_mock()
    start_time = time.time()
    with pytest.raises(HTTPError):
        fe_url = url(base_url, "/groups/{}".format("does-not-exist"))
        resp = yield http_client.fetch(
            fe_url, method="GET", headers={"X-Grouper-User": user.username})
    duration_ms = (time.time() - start_time) * 1000
    assert mock_plugin.log_request.call_count == 1
    assert mock_plugin.log_request.call_args_list[0][0][0] == "GroupView"
    assert mock_plugin.log_request.call_args_list[0][0][1] == 404
    # the reported value should be within 1s of our own observation
    assert abs(mock_plugin.log_request.call_args_list[0][0][2] -
               duration_ms) <= 1000
Ejemplo n.º 23
0
def test_request_options(tmpdir: LocalPath, setup: SetupTest,
                         browser: Chrome) -> None:
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group", role="owner")
        setup.create_group("other-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/other-group/join"))
        page = GroupJoinPage(browser)

        options = [o.get_attribute("value") for o in page.get_member_options()]
        assert options == ["User: [email protected]", "Group: some-group"]

        page.set_reason("Testing")
        page.submit()

        # Now that there is a pending request, the first option should be blank and there should be
        # a notice saying that there is already a pending membership request.
        browser.get(url(frontend_url, "/groups/other-group/join"))
        options = [o.get_attribute("value") for o in page.get_member_options()]
        assert options == ["", "Group: some-group"]
        alerts = page.get_alerts()
        assert len(alerts) == 1
        assert "already a member" in alerts[0].text

        # Attempting to submit the form should fail, asking the user to select a value.
        page.set_reason("Testing")
        page.submit()
        assert page.current_url == url(frontend_url,
                                       "/groups/other-group/join")
Ejemplo n.º 24
0
def test_github_username(session, users, http_client, base_url,
                         graph):  # noqa: F811
    user = users["*****@*****.**"]
    assert get_user_metadata_by_key(session, user.id,
                                    USER_METADATA_GITHUB_USERNAME_KEY) is None

    set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY,
                      "zorkian-on-gh")
    graph.update_from_db(session)
    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    [metadata] = body["data"]["user"]["metadata"]
    assert metadata["data_key"] == "github_username"
    assert metadata["data_value"] == "zorkian-on-gh"

    set_user_metadata(session, user.id, USER_METADATA_GITHUB_USERNAME_KEY,
                      None)
    graph.update_from_db(session)
    fe_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(fe_url)
    assert resp.code == 200
    body = json.loads(resp.body)
    assert body["data"]["user"]["metadata"] == []
Ejemplo n.º 25
0
def test_require_clickthru(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups"))
        groups_page = GroupsViewPage(browser)

        groups_page.click_create_group_button()
        create_group_modal = groups_page.get_create_group_modal()
        create_group_modal.set_group_name("test-group")
        create_group_modal.set_join_policy(GroupJoinPolicy.CAN_JOIN)
        create_group_modal.click_require_clickthru_checkbox()
        create_group_modal.confirm()

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/test-group/join"))
        join_page = GroupJoinPage(browser)

        join_page.set_reason("Testing")
        join_page.submit()
        clickthru_modal = join_page.get_clickthru_modal()
        clickthru_modal.confirm()

        group_page = GroupViewPage(browser)
        assert group_page.current_url.endswith("/groups/test-group?refresh=yes")
        assert group_page.find_member_row("*****@*****.**")
Ejemplo n.º 26
0
def test_service_account_lifecycle(tmpdir: LocalPath, setup: SetupTest,
                                   browser: Chrome) -> None:
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "user-admins")
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.grant_permission_to_group(USER_ADMIN, "", "user-admins")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/user-admins"))

        group_page = GroupViewPage(browser)
        group_page.click_add_service_account_button()

        # Test with an invalid machine set.
        create_page = ServiceAccountCreatePage(browser)
        create_page.set_name("my-special-service-account")
        create_page.set_description("some description")
        create_page.set_machine_set("some machines bad-machine")
        create_page.submit()
        assert create_page.has_alert("machine_set")
        expected = "[email protected] has invalid machine set"
        assert create_page.has_alert(expected)

        # Fix the machine set but test with an invalid name.
        create_page.set_name("service@service@service")
        create_page.set_machine_set("some machines")
        create_page.submit()
        assert create_page.has_alert("name")

        # Fix the name and then creation should succeed.
        create_page.set_name("my-special-service-account")
        create_page.submit()

        view_page = ServiceAccountViewPage(browser)
        assert view_page.owner == "user-admins"
        assert view_page.description == "some description"
        assert view_page.machine_set == "some machines"
        view_page.click_disable_button()
        disable_modal = view_page.get_disable_modal()
        disable_modal.confirm()

        browser.get(url(frontend_url, "/users"))

        users_page = UsersViewPage(browser)
        users_page.click_show_disabled_users_button()
        users_page.click_show_service_accounts_button()
        user_row = users_page.find_user_row(
            "[email protected] (service)")
        user_row.click()

        view_page = ServiceAccountViewPage(browser)
        view_page.click_enable_button()

        enable_page = ServiceAccountEnablePage(browser)
        enable_page.select_owner("Group: some-group")
        enable_page.submit()

        view_page = ServiceAccountViewPage(browser)
        assert view_page.owner == "some-group"
Ejemplo n.º 27
0
def test_grant_permission_to_tag(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    perm = create_permission(session, TAG_EDIT)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )

    fe_url = url(base_url, "/tags")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    perm = get_permission(session, TAG_EDIT)
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 1
    ), "The tag should have exactly 1 permission"
    assert (
        get_public_key_tag_permissions(session, tag)[0].name == perm.name
    ), "The tag's permission should be the one we added"
    assert (
        get_public_key_tag_permissions(session, tag)[0].argument == "*"
    ), "The tag's permission should be the one we added"

    # Make sure trying to add a permission to a tag doesn't fail horribly if it's already there
    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
Ejemplo n.º 28
0
def test_grant_permission(tmpdir: LocalPath, setup: SetupTest,
                          browser: Chrome) -> None:
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.grant_permission_to_group(PERMISSION_GRANT, "some-permission",
                                        "some-group")
        setup.create_permission("some-permission")
        setup.create_group("other-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/some-group"))

        group_page = GroupViewPage(browser)
        assert group_page.find_permission_rows("some-permission") == []
        group_page.click_add_permission_button()

        grant_page = PermissionGrantPage(browser)
        grant_page.set_permission("some-permission")
        grant_page.set_argument("foo")
        grant_page.submit()

        rows = group_page.find_permission_rows("some-permission")
        assert len(rows) == 1
        assert rows[0].argument == "foo"

        # Grant a permission with surrounding and internal whitespace to test whitespace handling.
        browser.get(url(frontend_url, "/groups/other-group"))
        assert group_page.find_permission_rows("some-permission") == []
        group_page.click_add_permission_button()

        grant_page.set_permission("some-permission")
        grant_page.set_argument("  arg u  ment  ")
        grant_page.submit()

        rows = group_page.find_permission_rows("some-permission")
        assert len(rows) == 1
        assert rows[0].argument in ("arg u ment", "arg u  ment"
                                    )  # browser messes with whitespace

    # Check directly in the database to make sure the whitespace is stripped, since we may not be
    # able to see it via the browser.  We need to explicitly reopen the database since otherwise
    # SQLite doesn't always see changes written by the frontend.
    setup.reopen_database()
    permission_grant_repository = setup.sql_repository_factory.create_permission_grant_repository(
    )
    grants = permission_grant_repository.permission_grants_for_group(
        "other-group")
    assert grants == [
        GroupPermissionGrant(
            group="other-group",
            permission="some-permission",
            argument="arg u  ment",
            granted_on=ANY,
            is_alias=False,
            grant_id=ANY,
        )
    ]
Ejemplo n.º 29
0
def test_view(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.create_permission("audited-permission", "", audited=True)
        setup.create_permission("some-permission", "Some permission")
        setup.create_permission("disabled-permission", "", enabled=False)
        setup.grant_permission_to_group("some-permission", "", "another-group")
        setup.grant_permission_to_group("some-permission", "foo", "some-group")
        setup.create_service_account("*****@*****.**", "owner-group")
        setup.grant_permission_to_service_account("audited-permission",
                                                  "argument",
                                                  "*****@*****.**")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions/some-permission/groups"))
        page = PermissionViewPage(browser)
        assert page.subheading == "some-permission 2 grant(s)"
        assert page.description == "Some permission"
        assert not page.has_disable_permission_button
        assert not page.has_disable_auditing_button
        assert not page.has_enable_auditing_button
        assert not page.has_audited_warning
        assert not page.has_disabled_warning
        grants = [(r.group, r.argument)
                  for r in page.group_permission_grant_rows]
        assert grants == [("another-group", "(unargumented)"),
                          ("some-group", "foo")]

        browser.get(
            url(frontend_url, "/permissions/some-permission/service_accounts"))
        page = PermissionViewPage(browser)
        assert page.has_no_service_account_grants

        browser.get(url(frontend_url,
                        "/permissions/audited-permission/groups"))
        page = PermissionViewPage(browser)
        assert page.subheading == "audited-permission 0 grant(s)"
        assert not page.description
        assert page.has_audited_warning
        assert not page.has_disable_auditing_button
        assert not page.has_enable_auditing_button
        assert page.has_no_group_grants

        browser.get(
            url(frontend_url,
                "/permissions/audited-permission/service_accounts"))
        page = PermissionViewPage(browser)
        grants = [(r.service_account, r.argument)
                  for r in page.service_account_permission_grant_rows]
        assert grants == [("*****@*****.**", "argument")]

        browser.get(url(frontend_url, "/permissions/disabled-permission"))
        page = PermissionViewPage(browser)
        assert page.subheading == "disabled-permission"
        assert not page.has_disable_permission_button
        assert page.has_disabled_warning
Ejemplo n.º 30
0
def test_shell(session, users, http_client, base_url):  # noqa: F811
    settings().shell = [["/bin/bash", "bash"], ["/bin/zsh", "zsh"]]

    user = users["*****@*****.**"]
    assert not get_user_metadata_by_key(session, user.id,
                                        USER_METADATA_SHELL_KEY)

    user = User.get(session, name=user.username)
    fe_url = url(base_url, "/users/{}/shell".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"shell": "/bin/bash"}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)

    assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
            is not None), "The user should have shell metadata"
    assert (get_user_metadata_by_key(
        session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash")

    fe_url = url(base_url, "/users/{}/shell".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"shell": "/bin/fish"}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)

    assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
            is not None), "The user should have shell metadata"
    assert (get_user_metadata_by_key(
        session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/bash")

    fe_url = url(base_url, "/users/{}/shell".format(user.username))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"shell": "/bin/zsh"}),
        headers={"X-Grouper-User": user.username},
    )
    assert resp.code == 200

    user = User.get(session, name=user.username)

    assert (get_user_metadata_by_key(session, user.id, USER_METADATA_SHELL_KEY)
            is not None), "The user should have shell metadata"
    assert (get_user_metadata_by_key(
        session, user.id, USER_METADATA_SHELL_KEY).data_value == "/bin/zsh")
Ejemplo n.º 31
0
def test_revoke_permission_from_tag(users, http_client, base_url, session):  # noqa: F811

    user = session.query(User).filter_by(username="******").scalar()

    create_permission(session, TAG_EDIT)
    session.commit()

    grant_permission(
        session.query(Group).filter_by(groupname="all-teams").scalar(),
        get_permission(session, TAG_EDIT),
        "*",
    )

    fe_url = url(base_url, "/tags")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"tagname": "tyler_was_here", "description": "Test Tag Please Ignore"}),
        headers={"X-Grouper-User": user.username},
    )

    tag = PublicKeyTag.get(session, name="tyler_was_here")

    user = session.query(User).filter_by(username="******").scalar()

    fe_url = url(base_url, "/permissions/grant_tag/{}".format(tag.name))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({"permission": TAG_EDIT, "argument": "*"}),
        headers={"X-Grouper-User": user.username},
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    get_permission(session, TAG_EDIT)
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 1
    ), "The tag should have exactly 1 permission"

    user = session.query(User).filter_by(username="******").scalar()

    mapping = get_public_key_tag_permissions(session, tag)[0]
    fe_url = url(base_url, "/permissions/{}/revoke_tag/{}".format(TAG_EDIT, mapping.mapping_id))
    resp = yield http_client.fetch(
        fe_url, method="POST", body="", headers={"X-Grouper-User": user.username}
    )

    assert resp.code == 200
    tag = PublicKeyTag.get(session, name="tyler_was_here")
    assert (
        len(get_public_key_tag_permissions(session, tag)) == 0
    ), "The tag should have no permissions"
Ejemplo n.º 32
0
def test_list_create_button(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions"))
        page = PermissionsPage(browser)
        assert not page.has_create_permission_button

        with setup.transaction():
            setup.grant_permission_to_group(PERMISSION_CREATE, "*", "admins")
            setup.add_user_to_group("*****@*****.**", "admins")
        browser.get(url(frontend_url, "/permissions?refresh=yes"))
        assert page.has_create_permission_button
Ejemplo n.º 33
0
def test_permission_revoke_denied(tmpdir: LocalPath, setup: SetupTest,
                                  browser: Chrome) -> None:
    with setup.transaction():
        setup.create_service_account("*****@*****.**", "some-group")
        setup.grant_permission_to_service_account("some-permission", "*",
                                                  "*****@*****.**")
        setup.create_user("*****@*****.**")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(
            url(frontend_url,
                "/groups/some-group/service/[email protected]"))

        page = ServiceAccountViewPage(browser)
        assert page.owner == "some-group"
        permission_rows = page.permission_rows
        assert len(permission_rows) == 1
        permission = permission_rows[0]
        assert permission.permission == "some-permission"
        assert permission.argument == "*"

        # The button doesn't show for someone who can't manage the service account.
        with pytest.raises(NoSuchElementException):
            permission.click_revoke_button()

    # Add the user to the group so that the revoke button will show up, and then revoke it before
    # attempting to click the button.  We can't just directly initiate a request to the revoke URL
    # without making the button appear because Python Selenium doesn't support a test-initiated
    # POST (only GET).
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(
            url(frontend_url,
                "/groups/some-group/service/[email protected]"))

        page = ServiceAccountViewPage(browser)
        assert page.owner == "some-group"
        permission_rows = page.permission_rows
        assert len(permission_rows) == 1
        permission = permission_rows[0]

        with setup.transaction():
            setup.remove_user_from_group("*****@*****.**", "some-group")

        permission.click_revoke_button()
        permission_revoke_modal = page.get_revoke_permission_modal()
        permission_revoke_modal.confirm()

        assert page.has_text(
            "The operation you tried to complete is unauthorized")
Ejemplo n.º 34
0
def test_user_enable_disable(
    session,  # noqa: F811
    graph,  # noqa: F811
    users,  # noqa: F811
    user_admin_perm_to_auditors,
    user_enable_perm_to_sre,
    http_client,
    base_url,
):
    username = u"*****@*****.**"
    old_groups = sorted(get_groups(graph, username))
    headers_admin = {"X-Grouper-User": "******"}
    headers_enable = {"X-Grouper-User": "******"}
    body_preserve = urlencode({"preserve_membership": "true"})
    body_base = urlencode({})

    # disable user
    fe_url = url(base_url, "/users/{}/disable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_admin, body=body_base)
    assert resp.code == 200

    # Attempt to enable user, preserving groups, as user with `grouper.user.enable`.
    # Should fail due to lack of admin perm.
    fe_url = url(base_url, "/users/{}/enable".format(username))
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(
            fe_url, method="POST", headers=headers_enable, body=body_preserve
        )

    # enable user, PRESERVE groups, as a user with the correct admin permission
    fe_url = url(base_url, "/users/{}/enable".format(username))
    resp = yield http_client.fetch(
        fe_url, method="POST", headers=headers_admin, body=body_preserve
    )
    assert resp.code == 200
    graph.update_from_db(session)
    assert old_groups == sorted(get_groups(graph, username)), "nothing should be removed"

    # disable user again
    fe_url = url(base_url, "/users/{}/disable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_admin, body=body_base)
    assert resp.code == 200

    # Attempt to enable user, PURGE groups. Should now succeed even with
    # only the `grouper.user.enable` perm.
    fe_url = url(base_url, "/users/{}/enable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_enable, body=body_base)
    assert resp.code == 200

    graph.update_from_db(session)
    assert len(get_groups(graph, username)) == 0, "all group membership should be removed"
Ejemplo n.º 35
0
def test_user_enable_disable(
    session,  # noqa: F811
    graph,  # noqa: F811
    users,  # noqa: F811
    user_admin_perm_to_auditors,
    user_enable_perm_to_sre,
    http_client,
    base_url,
):
    username = "******"
    old_groups = sorted(get_groups(graph, username))
    headers_admin = {"X-Grouper-User": "******"}
    headers_enable = {"X-Grouper-User": "******"}
    body_preserve = urlencode({"preserve_membership": "true"})
    body_base = urlencode({})

    # disable user
    fe_url = url(base_url, "/users/{}/disable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_admin, body=body_base)
    assert resp.code == 200

    # Attempt to enable user, preserving groups, as user with `grouper.user.enable`.
    # Should fail due to lack of admin perm.
    fe_url = url(base_url, "/users/{}/enable".format(username))
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(
            fe_url, method="POST", headers=headers_enable, body=body_preserve
        )

    # enable user, PRESERVE groups, as a user with the correct admin permission
    fe_url = url(base_url, "/users/{}/enable".format(username))
    resp = yield http_client.fetch(
        fe_url, method="POST", headers=headers_admin, body=body_preserve
    )
    assert resp.code == 200
    graph.update_from_db(session)
    assert old_groups == sorted(get_groups(graph, username)), "nothing should be removed"

    # disable user again
    fe_url = url(base_url, "/users/{}/disable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_admin, body=body_base)
    assert resp.code == 200

    # Attempt to enable user, PURGE groups. Should now succeed even with
    # only the `grouper.user.enable` perm.
    fe_url = url(base_url, "/users/{}/enable".format(username))
    resp = yield http_client.fetch(fe_url, method="POST", headers=headers_enable, body=body_base)
    assert resp.code == 200

    graph.update_from_db(session)
    assert len(get_groups(graph, username)) == 0, "all group membership should be removed"
Ejemplo n.º 36
0
def test_graph_edit_role(
        session,
        graph,
        standard_graph,
        groups,
        users,
        http_client,
        base_url  # noqa: F811
):
    """Test that membership role changes are refected in the graph."""
    user_role = graph.get_group_details(
        "tech-ops")["users"]["*****@*****.**"]["rolename"]
    assert user_role == "np-owner"

    # Ensure they are auditors so that they can be owner.
    add_member(groups["auditors"], users["*****@*****.**"])
    session.commit()

    # np-owner cannot upgrade themselves to owner
    resp = yield http_client.fetch(
        url(base_url, "/groups/tech-ops/edit/user/[email protected]"),
        method="POST",
        headers={"X-Grouper-User": "******"},
        body=urlencode({
            "role": "owner",
            "reason": "testing"
        }),
    )
    assert resp.code == 200
    graph.update_from_db(session)
    user_role = graph.get_group_details(
        "tech-ops")["users"]["*****@*****.**"]["rolename"]
    assert user_role == "np-owner"

    # but an owner can
    resp = yield http_client.fetch(
        url(base_url, "/groups/tech-ops/edit/user/[email protected]"),
        method="POST",
        headers={"X-Grouper-User": "******"},
        body=urlencode({
            "role": "owner",
            "reason": "testing"
        }),
    )
    assert resp.code == 200
    graph.update_from_db(session)
    user_role = graph.get_group_details(
        "tech-ops")["users"]["*****@*****.**"]["rolename"]
    assert user_role == "owner"
Ejemplo n.º 37
0
def test_permissions(permissions, http_client, base_url, session, graph):  # noqa: F811
    api_url = url(base_url, "/permissions")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["permissions"]) == sorted(permissions)

    api_url = url(base_url, "/permissions/{}".format("team-sre"))
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
Ejemplo n.º 38
0
def test_permissions(permissions, http_client, base_url, session, graph):  # noqa: F811
    api_url = url(base_url, "/permissions")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["permissions"]) == sorted(permissions)

    api_url = url(base_url, "/permissions/{}".format("team-sre"))
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
Ejemplo n.º 39
0
def test_permission_grant_revoke(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.grant_permission_to_group("some-permission", "foo", "some-group")
        setup.create_service_account("*****@*****.**", "some-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/groups/some-group/service/[email protected]"))

        page = ServiceAccountViewPage(browser)
        assert page.permission_rows == []
        page.click_add_permission_button()

        grant_page = ServiceAccountGrantPermissionPage(browser)
        grant_page.select_permission("some-permission (foo)")
        grant_page.set_argument("foo")
        grant_page.submit()

        page = ServiceAccountViewPage(browser)
        permission_rows = page.permission_rows
        assert len(permission_rows) == 1
        permission = permission_rows[0]
        assert permission.permission == "some-permission"
        assert permission.argument == "foo"

        permission.click_revoke_button()
        permission_revoke_modal = page.get_revoke_permission_modal()
        permission_revoke_modal.confirm()

        assert page.permission_rows == []
Ejemplo n.º 40
0
def test_view_change_audited(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "audit-managers")
        setup.grant_permission_to_group(AUDIT_MANAGER, "", "audit-managers")
        setup.create_permission("some-permission", "Some permission")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions/some-permission"))
        page = PermissionViewPage(browser)
        assert not page.has_disable_permission_button
        assert not page.has_audited_warning
        assert page.has_enable_auditing_button

        page.click_enable_auditing_button()
        enable_auditing_modal = page.get_enable_auditing_modal()
        enable_auditing_modal.confirm()

        assert page.subheading == "some-permission"
        assert page.has_audited_warning
        assert not page.has_enable_auditing_button
        assert page.has_disable_auditing_button

        page.click_disable_auditing_button()
        disable_auditing_modal = page.get_disable_auditing_modal()
        disable_auditing_modal.confirm()

        assert page.subheading == "some-permission"
        assert not page.has_audited_warning
        assert page.has_enable_auditing_button
        assert not page.has_disable_auditing_button
Ejemplo n.º 41
0
def test_limited_permissions_global_approvers(
    session, standard_graph, groups, grantable_permissions, http_client, base_url  # noqa: F811
):
    """Test that notifications are not sent to global approvers."""
    perm_grant, _, perm1, _ = grantable_permissions
    grant_permission(groups["security-team"], perm_grant, argument="grantable.*")

    # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team'
    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode(
            {
                "permission_name": perm1.name,
                "argument": "specific_arg",
                "reason": "blah blah black sheep",
                "argument_type": "text",
            }
        ),
        headers={"X-Grouper-User": username},
    )
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert_same_recipients(emails, [u"*****@*****.**"])
Ejemplo n.º 42
0
def test_completed_inbound_requests(async_server, browser, do_action_requests):  # noqa: F811
    fe_url = url(async_server, "/permissions/requests?")
    browser.get(fe_url)

    # Check that the request rows have info we expect
    page = PermissionRequestsPage(browser)
    request_rows = page.request_rows
    expected_perms = [
        "{}, {}".format(PERM_WITH_GRANTER, ARGUMENT),
        "{}, {}".format(PERM_NO_GRANTER, ARGUMENT),
        "{}, {}".format(PERMISSION_ADMIN, ARGUMENT),
    ]
    request_perms = [row.requested for row in request_rows]
    assert sorted(expected_perms) == sorted(request_perms)

    # Check the status change rows as well.  The timestamp part of the row is normally "(now)" but
    # can be "(1 second ago)" on slow systems and "(in the future)" if MySQL rounds the timestamp
    # up.  Allow for all of these.
    expected_whos = ([REQUESTING_USER] * 3) + ([GRANTING_USER] * 2)
    request_whos = []
    for row in page.status_change_rows:
        who, when = row.who.split(None, 1)
        assert when in ("(now)", "(1 second ago)", "(in the future)")
        request_whos.append(who)
    assert sorted(expected_whos) == sorted(request_whos)

    # and make sure the "no requests" row doesn't show up
    with pytest.raises(Exception):
        page.no_requests_row
Ejemplo n.º 43
0
def test_limited_permissions_global_approvers(
        session,
        standard_graph,
        groups,
        grantable_permissions,
        http_client,
        base_url  # noqa: F811
):
    """Test that notifications are not sent to global approvers."""
    perm_grant, _, perm1, _ = grantable_permissions
    grant_permission(groups["security-team"],
                     perm_grant,
                     argument="grantable.*")

    # SPECIFIC REQUEST: 'grantable.one', 'specific_arg' for 'sad-team'
    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        body=urlencode({
            "permission_name": perm1.name,
            "argument": "specific_arg",
            "reason": "blah blah black sheep",
            "argument_type": "text",
        }),
        headers={"X-Grouper-User": username},
    )
    assert resp.code == 200

    emails = _get_unsent_and_mark_as_sent_emails(session)
    assert_same_recipients(emails, ["*****@*****.**"])
Ejemplo n.º 44
0
def test_service_account_edit(tmpdir: LocalPath, setup: SetupTest,
                              browser: Chrome) -> None:
    with setup.transaction():
        setup.add_user_to_group("*****@*****.**", "some-group")
        setup.create_service_account("*****@*****.**", "some-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(
            url(frontend_url,
                "/groups/some-group/service/[email protected]"))

        view_page = ServiceAccountViewPage(browser)
        assert view_page.owner == "some-group"
        assert view_page.description == ""
        assert view_page.machine_set == ""
        view_page.click_edit_button()

        edit_page = ServiceAccountEditPage(browser)
        edit_page.set_description("some description")
        edit_page.set_machine_set("some machines bad-machine")
        edit_page.submit()
        assert edit_page.has_alert("machine_set")
        assert edit_page.has_alert(
            "[email protected] has invalid machine set")

        edit_page.set_machine_set("some machines")
        edit_page.submit()

        assert browser.current_url.endswith(
            "/groups/some-group/service/[email protected]")
        assert view_page.description == "some description"
        assert view_page.machine_set == "some machines"
Ejemplo n.º 45
0
def test_invalid_user(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/"))
        page = ErrorPage(browser)
        assert page.heading == "Error"
        assert page.subheading == "403 Forbidden"
        assert "[email protected] does not match" in page.content
Ejemplo n.º 46
0
def test_groups(groups, http_client, base_url):  # noqa: F811
    api_url = url(base_url, "/groups")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)

    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["groups"]) == sorted(groups)
Ejemplo n.º 47
0
def test_users(users, http_client, base_url):  # noqa: F811
    all_users = sorted(list(users.keys()) + ["*****@*****.**"])
    users_wo_role = sorted([u for u in users if u != u"*****@*****.**"])

    api_url = url(base_url, "/users")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["users"]) == users_wo_role

    api_url = url(base_url, "/users?include_role_users=yes")
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert resp.code == 200
    assert body["status"] == "ok"
    assert sorted(body["data"]["users"]) == all_users
Ejemplo n.º 48
0
def test_view(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.create_permission("audited-permission", "", audited=True)
        setup.create_permission("some-permission", "Some permission")
        setup.create_permission("disabled-permission", "", enabled=False)
        setup.grant_permission_to_group("some-permission", "", "another-group")
        setup.grant_permission_to_group("some-permission", "foo", "some-group")
        setup.create_service_account("*****@*****.**", "owner-group")
        setup.grant_permission_to_service_account(
            "audited-permission", "argument", "*****@*****.**"
        )

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/permissions/some-permission"))
        page = PermissionViewPage(browser)
        assert page.subheading == "some-permission"
        assert page.description == "Some permission"
        assert not page.has_disable_permission_button
        assert not page.has_disable_auditing_button
        assert not page.has_enable_auditing_button
        assert not page.has_audited_warning
        assert not page.has_disabled_warning
        grants = [(r.group, r.argument) for r in page.group_permission_grant_rows]
        assert grants == [("another-group", "(unargumented)"), ("some-group", "foo")]
        assert page.has_no_service_account_grants

        browser.get(url(frontend_url, "/permissions/audited-permission"))
        page = PermissionViewPage(browser)
        assert page.subheading == "audited-permission"
        assert not page.description
        assert page.has_audited_warning
        assert not page.has_disable_auditing_button
        assert not page.has_enable_auditing_button
        assert page.has_no_group_grants
        grants = [
            (r.service_account, r.argument) for r in page.service_account_permission_grant_rows
        ]
        assert grants == [("*****@*****.**", "argument")]

        browser.get(url(frontend_url, "/permissions/disabled-permission"))
        page = PermissionViewPage(browser)
        assert page.subheading == "disabled-permission"
        assert not page.has_disable_permission_button
        assert page.has_disabled_warning
Ejemplo n.º 49
0
def test_list_groups(async_server, browser, groups):  # noqa: F811
    fe_url = url(async_server, "/groups")
    browser.get(fe_url)

    page = GroupsViewPage(browser)

    for name, _ in groups.iteritems():
        row = page.find_group_row(name)
        assert row.href.endswith("/groups/{}".format(name))
Ejemplo n.º 50
0
def test_no_requests(async_server, browser, do_action_requests):  # noqa: F811
    fe_url = url(async_server, "/permissions/requests?status=pending&direction=Requested+by+me")
    browser.get(fe_url)

    page = PermissionRequestsPage(browser)
    assert page.no_requests_row is not None

    assert len(page.request_rows) == 0
    assert len(page.status_change_rows) == 0
Ejemplo n.º 51
0
def test_passwords_api(session, users, http_client, base_url, graph):  # noqa: F811
    user = users["*****@*****.**"]
    TEST_PASSWORD = "******"

    add_new_user_password(session, "test", TEST_PASSWORD, user.id)
    assert len(user_passwords(session, user)) == 1, "The user should only have a single password"

    graph.update_from_db(session)
    c = Counter.get(session, name="updates")
    api_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert body["checkpoint"] == c.count, "The API response is not up to date"
    assert (
        body["data"]["user"]["passwords"] != []
    ), "The user should not have an empty passwords field"
    assert (
        body["data"]["user"]["passwords"][0]["name"] == "test"
    ), "The password should have the same name"
    assert (
        body["data"]["user"]["passwords"][0]["func"] == "crypt(3)-$6$"
    ), "This test does not support any hash functions other than crypt(3)-$6$"
    assert body["data"]["user"]["passwords"][0]["hash"] == crypt.crypt(
        TEST_PASSWORD, body["data"]["user"]["passwords"][0]["salt"]
    ), (
        "The hash should be the same as hashing the password and the salt together using the"
        " hashing function"
    )
    assert body["data"]["user"]["passwords"][0]["hash"] != crypt.crypt(
        "hello", body["data"]["user"]["passwords"][0]["salt"]
    ), (
        "The hash should not be the same as hashing the wrong password and the salt together"
        " using the hashing function"
    )

    delete_user_password(session, "test", user.id)
    c = Counter.get(session, name="updates")
    graph.update_from_db(session)
    api_url = url(base_url, "/users/{}".format(user.username))
    resp = yield http_client.fetch(api_url)
    body = json.loads(resp.body)
    assert body["checkpoint"] == c.count, "The API response is not up to date"
    assert body["data"]["user"]["passwords"] == [], "The user should not have any passwords"
Ejemplo n.º 52
0
def test_show_group_hides_aliased_permissions(async_server, browser):  # noqa: F811
    fe_url = url(async_server, "/groups/sad-team")
    browser.get(fe_url)

    page = GroupViewPage(browser)

    assert len(page.find_permission_rows("owner", "sad-team")) == 1

    assert page.find_permission_rows("ssh", "owner=sad-team") == []
    assert page.find_permission_rows("sudo", "sad-team") == []
Ejemplo n.º 53
0
def test_regress_permreq_global_approvers(
    session, standard_graph, groups, grantable_permissions, http_client, base_url  # noqa: F811
):
    """Validates that we can render a permission request form where a global approver exists"""
    perm_grant, _, perm1, _ = grantable_permissions
    groupname = "sad-team"
    username = "******"
    fe_url = url(base_url, "/groups/{}/permission/request".format(groupname))
    resp = yield http_client.fetch(fe_url, method="GET", headers={"X-Grouper-User": username})
    assert resp.code == 200
Ejemplo n.º 54
0
def test_show_user_hides_aliased_permissions(async_server, browser):  # noqa: F811
    fe_url = url(async_server, "/users/[email protected]")
    browser.get(fe_url)

    page = UserViewPage(browser)

    assert len(page.find_permission_rows("owner", "sad-team")) == 1

    assert page.find_permission_rows("ssh", "owner=sad-team") == []
    assert page.find_permission_rows("sudo", "sad-team") == []
Ejemplo n.º 55
0
def test_service_account(tmpdir, setup, browser):
    # type: (LocalPath, SetupTest, Chrome) -> None
    with setup.transaction():
        setup.create_service_account("*****@*****.**", "some-group")

    with frontend_server(tmpdir, "*****@*****.**") as frontend_url:
        browser.get(url(frontend_url, "/"))
        page = ErrorPage(browser)
        assert page.heading == "Error"
        assert page.subheading == "403 Forbidden"
        assert "[email protected] is a service account" in page.content
Ejemplo n.º 56
0
def test_group_disable(session, groups, http_client, base_url):  # noqa: F811
    # create global audit
    fe_url = url(base_url, "/audits/create")
    ends_at = date.today() + timedelta(days=7)
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        headers={"X-Grouper-User": "******"},
        body=urlencode({"ends_at": ends_at.strftime("%m/%d/%Y")}),
    )
    assert resp.code == 200

    serving_team, just_created = Group.get_or_create(session, groupname="serving-team")
    assert not just_created
    assert serving_team.audit
    assert not serving_team.audit.complete

    # disable with insufficient permissions
    fe_url = url(base_url, "/groups/serving-team/disable")
    with pytest.raises(HTTPError):
        resp = yield http_client.fetch(
            fe_url,
            method="POST",
            headers={"X-Grouper-User": "******"},
            body=urlencode({"name": "serving-team"}),
        )

    # disable
    fe_url = url(base_url, "/groups/serving-team/disable")
    resp = yield http_client.fetch(
        fe_url,
        method="POST",
        headers={"X-Grouper-User": "******"},
        body=urlencode({"name": "serving-team"}),
    )
    assert resp.code == 200

    serving_team, just_created = Group.get_or_create(session, groupname="serving-team")
    assert not just_created
    assert serving_team.audit
    assert serving_team.audit.complete, "disabling group should complete any outstanding audit"