-
Notifications
You must be signed in to change notification settings - Fork 3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(tokens) Adds non-admin tests for access tokens #5174
Changes from 19 commits
c1e77f4
43cfa3a
6979717
b105237
eeb2c87
f88f01e
162034d
3e5d050
0986b1c
29e0043
60ecbd0
f3e57c2
87d7f25
c560217
ea3037d
023ac8b
01f17e5
62cb181
4024cc5
dcf780e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -179,6 +179,14 @@ public void revokeAccessToken(@Nonnull String hashedToken) throws TokenException | |
throw new TokenException("Access token no longer exists"); | ||
} | ||
|
||
public boolean isTokenRevoked(@Nonnull String hashToken) { | ||
try { | ||
return _revokedTokenCache.get(hashToken); | ||
} catch (ExecutionException e) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why would ExecutionException be thrown? Is it worth logging a warn / error? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's the API from Guava's Cache. I wanted a simpler API, to see if a token was revoked or not. |
||
return false; | ||
} | ||
} | ||
|
||
/** | ||
* Hashes the input after salting it. | ||
*/ | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -74,7 +74,8 @@ | |
"actors":{ | ||
"resourceOwners":false, | ||
"allUsers":true, | ||
"allGroups":false | ||
"allGroups":false, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why?? |
||
"users":[] | ||
}, | ||
"privileges":[ | ||
"MANAGE_POLICIES", | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,12 +1,28 @@ | ||
import os | ||
import json | ||
import pytest | ||
from time import sleep | ||
from datahub.cli import delete_cli, ingest_cli | ||
from datahub.cli.docker import check_local_docker_containers | ||
from datahub.cli.cli_utils import guess_entity_type, post_entity, get_aspects_for_entity | ||
from datahub.cli.ingest_cli import get_session_and_host | ||
from datahub.cli.delete_cli import guess_entity_type, delete_one_urn_cmd, delete_references | ||
from tests.utils import ingest_file_via_rest, delete_urns_from_file | ||
|
||
# Disable telemetry | ||
os.putenv("DATAHUB_TELEMETRY_ENABLED", "false") | ||
|
||
@pytest.fixture(scope="session") | ||
def wait_for_healthchecks(): | ||
# Simply assert that everything is healthy, but don't wait. | ||
assert not check_local_docker_containers() | ||
yield | ||
|
||
@pytest.mark.dependency() | ||
def test_healthchecks(wait_for_healthchecks): | ||
# Call to wait_for_healthchecks fixture will do the actual functionality. | ||
pass | ||
|
||
@pytest.fixture(autouse=True) | ||
def test_setup(): | ||
"""Fixture to execute asserts before and after a test is run""" | ||
|
@@ -24,21 +40,21 @@ def test_setup(): | |
|
||
ingested_dataset_run_id = ingest_file_via_rest("tests/delete/cli_test_data.json").config.run_id | ||
|
||
sleep(2) | ||
sleep(3) | ||
|
||
assert "browsePaths" in get_aspects_for_entity(entity_urn=dataset_urn, aspects=["browsePaths"], typed=False) | ||
|
||
yield | ||
rollback_url = f"{gms_host}/runs?action=rollback" | ||
session.post(rollback_url, data=json.dumps({"runId": ingested_dataset_run_id, "dryRun": False, "hardDelete": True, "safe": False})) | ||
|
||
sleep(2) | ||
sleep(3) | ||
|
||
assert "browsePaths" not in get_aspects_for_entity(entity_urn=dataset_urn, aspects=["browsePaths"], typed=False) | ||
assert "editableDatasetProperties" not in get_aspects_for_entity(entity_urn=dataset_urn, aspects=["editableDatasetProperties"], typed=False) | ||
|
||
@pytest.mark.dependency() | ||
def test_delete_reference(): | ||
def test_delete_reference(depends=["test_healthchecks"]): | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you - this should fix many of the existing issues we are seeing correct? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It should but we still have issues on the tests. I'm not seeing the adequate policies being applied. |
||
platform = "urn:li:dataPlatform:kafka" | ||
dataset_name = "test-delete" | ||
|
||
|
@@ -58,7 +74,7 @@ def test_delete_reference(): | |
# Delete references to the tag | ||
delete_references(tag_urn, dry_run=False, cached_session_host=(session, gms_host)) | ||
|
||
sleep(2) | ||
sleep(3) | ||
|
||
# Validate that references no longer exist | ||
references_count, related_aspects = delete_references(tag_urn, dry_run=True, cached_session_host=(session, gms_host)) | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,223 @@ | ||
import time | ||
import pytest | ||
import requests | ||
from tests.utils import get_frontend_url | ||
from datahub.cli.docker import check_local_docker_containers | ||
|
||
TEST_POLICY_NAME = "Updated Platform Policy" | ||
|
||
@pytest.fixture(scope="session") | ||
def wait_for_healthchecks(): | ||
# Simply assert that everything is healthy, but don't wait. | ||
assert not check_local_docker_containers() | ||
yield | ||
|
||
|
||
@pytest.mark.dependency() | ||
def test_healthchecks(wait_for_healthchecks): | ||
# Call to wait_for_healthchecks fixture will do the actual functionality. | ||
pass | ||
|
||
|
||
@pytest.fixture(scope="session") | ||
def frontend_session(wait_for_healthchecks): | ||
session = requests.Session() | ||
|
||
headers = { | ||
"Content-Type": "application/json", | ||
} | ||
data = '{"username":"datahub", "password":"datahub"}' | ||
response = session.post(f"{get_frontend_url()}/logIn", headers=headers, data=data) | ||
response.raise_for_status() | ||
|
||
yield session | ||
|
||
@pytest.mark.dependency(depends=["test_healthchecks"]) | ||
@pytest.fixture(scope='class', autouse=True) | ||
def test_frontend_list_policies(frontend_session): | ||
"""Fixture to execute setup before and tear down after all tests are run""" | ||
res_data = listPolicies(frontend_session) | ||
|
||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["listPolicies"] | ||
assert res_data["data"]["listPolicies"]["start"] == 0 | ||
assert res_data["data"]["listPolicies"]["count"] > 0 | ||
assert len(res_data["data"]["listPolicies"]["policies"]) > 0 | ||
|
||
# Verify that policy to be created does not exist before the test. | ||
# If it does, this test class's state is tainted | ||
result = filter( | ||
lambda x: x["name"] == TEST_POLICY_NAME, | ||
res_data["data"]["listPolicies"]["policies"], | ||
) | ||
assert len(list(result)) == 0 | ||
|
||
# Run remaining tests. | ||
yield | ||
|
||
res_data = listPolicies(frontend_session) | ||
|
||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["listPolicies"] | ||
|
||
# Verify that policy that was created is no longer in the list | ||
result = filter( | ||
lambda x: x["name"] == TEST_POLICY_NAME, | ||
res_data["data"]["listPolicies"]["policies"], | ||
) | ||
assert len(list(result)) == 0 | ||
|
||
@pytest.mark.dependency(depends=["test_healthchecks"]) | ||
def test_frontend_policy_operations(frontend_session): | ||
|
||
json = { | ||
"query": """mutation createPolicy($input: PolicyUpdateInput!) {\n | ||
createPolicy(input: $input) }""", | ||
"variables": { | ||
"input": { | ||
"type": "METADATA", | ||
"name": "Test Metadata Policy", | ||
"description": "My Metadaata Policy", | ||
"state": "ACTIVE", | ||
"resources": {"type": "dataset", "allResources": True}, | ||
"privileges": ["EDIT_ENTITY_TAGS"], | ||
"actors": { | ||
"users": ["urn:li:corpuser:datahub"], | ||
"resourceOwners": False, | ||
"allUsers": False, | ||
"allGroups": False, | ||
}, | ||
} | ||
}, | ||
} | ||
|
||
response = frontend_session.post(f"{get_frontend_url()}/api/v2/graphql", json=json) | ||
response.raise_for_status() | ||
res_data = response.json() | ||
|
||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["createPolicy"] | ||
|
||
new_urn = res_data["data"]["createPolicy"] | ||
|
||
# Sleep for eventual consistency | ||
time.sleep(3) | ||
|
||
update_json = { | ||
"query": """mutation updatePolicy($urn: String!, $input: PolicyUpdateInput!) {\n | ||
updatePolicy(urn: $urn, input: $input) }""", | ||
"variables": { | ||
"urn": new_urn, | ||
"input": { | ||
"type": "METADATA", | ||
"state": "ACTIVE", | ||
"name": "Test Metadata Policy", | ||
"description": "Updated Metadaata Policy", | ||
"privileges": ["EDIT_ENTITY_TAGS", "EDIT_ENTITY_GLOSSARY_TERMS"], | ||
"actors": { | ||
"resourceOwners": False, | ||
"allUsers": True, | ||
"allGroups": False, | ||
}, | ||
}, | ||
}, | ||
} | ||
|
||
response = frontend_session.post(f"{get_frontend_url()}/api/v2/graphql", json=update_json) | ||
response.raise_for_status() | ||
res_data = response.json() | ||
|
||
# Check updated was submitted successfully | ||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["updatePolicy"] | ||
assert res_data["data"]["updatePolicy"] == new_urn | ||
|
||
# Sleep for eventual consistency | ||
time.sleep(3) | ||
|
||
res_data = listPolicies(frontend_session) | ||
|
||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["listPolicies"] | ||
|
||
# Verify that the updated policy appears in the list and has the appropriate changes | ||
result = list(filter( | ||
lambda x: x["urn"] == new_urn, res_data["data"]["listPolicies"]["policies"] | ||
)) | ||
print(result) | ||
|
||
assert len(result) == 1 | ||
assert result[0]["description"] == "Updated Metadaata Policy" | ||
assert result[0]["privileges"] == ["EDIT_ENTITY_TAGS", "EDIT_ENTITY_GLOSSARY_TERMS"] | ||
assert result[0]["actors"]["allUsers"] == True | ||
|
||
# Now test that the policy can be deleted | ||
json = { | ||
"query": """mutation deletePolicy($urn: String!) {\n | ||
deletePolicy(urn: $urn) }""", | ||
"variables": {"urn": new_urn}, | ||
} | ||
|
||
response = frontend_session.post(f"{get_frontend_url()}/api/v2/graphql", json=json) | ||
response.raise_for_status() | ||
res_data = response.json() | ||
|
||
res_data = listPolicies(frontend_session) | ||
|
||
assert res_data | ||
assert res_data["data"] | ||
assert res_data["data"]["listPolicies"] | ||
|
||
# Verify that the URN is no longer in the list | ||
result = filter( | ||
lambda x: x["urn"] == new_urn, | ||
res_data["data"]["listPolicies"]["policies"], | ||
) | ||
assert len(list(result)) == 0 | ||
|
||
def listPolicies(session): | ||
json = { | ||
"query": """query listPolicies($input: ListPoliciesInput!) {\n | ||
listPolicies(input: $input) {\n | ||
start\n | ||
count\n | ||
total\n | ||
policies {\n | ||
urn\n | ||
type\n | ||
name\n | ||
description\n | ||
state\n | ||
resources {\n | ||
type\n | ||
allResources\n | ||
resources\n | ||
}\n | ||
privileges\n | ||
actors {\n | ||
users\n | ||
groups\n | ||
allUsers\n | ||
allGroups\n | ||
resourceOwners\n | ||
}\n | ||
editable\n | ||
}\n | ||
}\n | ||
}""", | ||
"variables": { | ||
"input": { | ||
"start": "0", | ||
"count": "20", | ||
} | ||
}, | ||
} | ||
response = session.post(f"{get_frontend_url()}/api/v2/graphql", json=json) | ||
response.raise_for_status() | ||
|
||
return response.json() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there another method that will do this , while also injecting the ".keyword" part?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not exactly, you have ResolverUtils#buildFilter which takes
@Nullable List<FacetFilterInput> facetFilterInputs
as input instead of@Nullable List<FacetFilterInput> facetFilterInputs, @Nonnull Set<String> validFacetFields