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
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)
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("*****@*****.**")
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)
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()
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!"
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"}), )
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"
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)
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"] == "*"
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
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)
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"
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()
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!"
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"
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
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")
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"] == []
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("*****@*****.**")
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"
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
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, ) ]
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
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")
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"
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
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")
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"
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"
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"
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"
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 == []
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
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"*****@*****.**"])
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
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, ["*****@*****.**"])
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"
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
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)
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
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
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))
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
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"
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") == []
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
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") == []
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
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"