Skip to content
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

[SYNPY-1553] Removes Blank Auth Header #1185

Merged
merged 8 commits into from
Apr 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 14 additions & 7 deletions synapseclient/api/entity_factory.py
Original file line number Diff line number Diff line change
Expand Up @@ -412,12 +412,19 @@ def _check_entity_restrictions(
if restriction_information and restriction_information.get(
"hasUnmetAccessRequirement", None
):
warning_message = (
"\nThis entity has access restrictions. Please visit the web page for this entity "
f'(syn.onweb("{synapse_id}")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
if not syn.credentials or not syn.credentials._token:
warning_message = (
"You have not provided valid credentials for authentication with Synapse."
" Please provide an authentication token and use `synapseclient.login()` before your next attempt."
" See https://python-docs.synapse.org/tutorials/authentication/ for more information."
)
else:
warning_message = (
"\nThis entity has access restrictions. Please visit the web page for this entity "
f'(syn.onweb("{synapse_id}")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
if download_file and bundle.get("entityType") not in ("project", "folder"):
raise SynapseUnmetAccessRestrictions(warning_message)
syn.logger.warn(warning_message)
syn.logger.warning(warning_message)
27 changes: 18 additions & 9 deletions synapseclient/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1445,17 +1445,26 @@ def _check_entity_restrictions(
Raises:
SynapseUnmetAccessRestrictions: Warning for unmet access requirements.
"""
restrictionInformation = bundle["restrictionInformation"]
if restrictionInformation["hasUnmetAccessRequirement"]:
warning_message = (
"\nThis entity has access restrictions. Please visit the web page for this entity "
f'(syn.onweb("{id_of(entity)}")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
restriction_information = bundle.get("restrictionInformation", None)
if restriction_information and restriction_information.get(
"hasUnmetAccessRequirement", None
):
if not self.credentials or not self.credentials._token:
warning_message = (
"You have not provided valid credentials for authentication with Synapse."
" Please provide an authentication token and use `synapseclient.login()` before your next attempt."
" See https://python-docs.synapse.org/tutorials/authentication/ for more information."
)
else:
warning_message = (
"\nThis entity has access restrictions. Please visit the web page for this entity "
f'(syn.onweb("{id_of(entity)}")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
if downloadFile and bundle.get("entityType") not in ("project", "folder"):
raise SynapseUnmetAccessRestrictions(warning_message)
warnings.warn(warning_message)
self.logger.warning(warning_message)

def _getFromFile(
self, filepath: str, limitSearch: str = None, md5: str = None
Expand Down
3 changes: 2 additions & 1 deletion synapseclient/core/credentials/cred_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,8 @@ def secret(self) -> str:
return self._token

def __call__(self, r):
r.headers.update({"Authorization": f"Bearer {self.secret}"})
if self.secret:
r.headers.update({"Authorization": f"Bearer {self.secret}"})
return r

def __repr__(self):
Expand Down
259 changes: 154 additions & 105 deletions tests/unit/synapseclient/unit_test_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -1157,121 +1157,169 @@ def expected_request_json(token) -> str:
)


def test_check_entity_restrictions_no_unmet_restriction(syn: Synapse) -> None:
with patch("warnings.warn") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"restrictionInformation": {"hasUnmetAccessRequirement": False},
}
entity = "syn123"
syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_not_called()

class TestCheckEntityRestrictions:
@pytest.fixture(autouse=True, scope="function")
def init_syn(self, syn: Synapse) -> None:
self.syn = syn
self.syn.credentials = SynapseAuthTokenCredentials(token="abc", username="def")

def test_check_entity_restrictions_unmet_restriction_entity_file_with_download_file_is_true(
syn: Synapse,
) -> None:
with patch("warnings.warn") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "file",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
pytest.raises(
SynapseUnmetAccessRestrictions,
syn._check_entity_restrictions,
bundle,
entity,
True,
)
mocked_warn.assert_not_called()
def test_check_entity_restrictions_no_unmet_restriction(self) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"restrictionInformation": {"hasUnmetAccessRequirement": False},
}
entity = "syn123"
self.syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_not_called()

def test_check_entity_restrictions_unmet_restriction_entity_file_with_download_file_is_true(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "file",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
pytest.raises(
SynapseUnmetAccessRestrictions,
self.syn._check_entity_restrictions,
bundle,
entity,
True,
)
mocked_warn.assert_not_called()

def test_check_entity_restrictions_unmet_restriction_entity_project_with_download_file_is_true(
syn: Synapse,
) -> None:
with patch("warnings.warn") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "project",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"\nThis entity has access restrictions. Please visit the web page for this entity "
'(syn.onweb("syn123")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
def test_check_entity_restrictions_unmet_restriction_entity_project_with_download_file_is_true(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "project",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
self.syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"\nThis entity has access restrictions. Please visit the web page for this entity "
'(syn.onweb("syn123")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)

def test_check_entity_restrictions_unmet_restriction_entity_folder_with_download_file_is_true_and_no_token(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "folder",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
self.syn.credentials = SynapseAuthTokenCredentials(token="")
self.syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"You have not provided valid credentials for authentication with Synapse."
" Please provide an authentication token and use `synapseclient.login()` before your next attempt."
" See https://python-docs.synapse.org/tutorials/authentication/ for more information."
)

def test_check_entity_restrictions_unmet_restriction_entity_folder_with_download_file_is_true(
syn: Synapse,
) -> None:
with patch("warnings.warn") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "folder",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"\nThis entity has access restrictions. Please visit the web page for this entity "
'(syn.onweb("syn123")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)
def test_check_entity_restrictions_unmet_restriction_entity_folder_with_download_file_is_true_and_no_credentials(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "folder",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
self.syn.credentials = None
self.syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"You have not provided valid credentials for authentication with Synapse."
" Please provide an authentication token and use `synapseclient.login()` before your next attempt."
" See https://python-docs.synapse.org/tutorials/authentication/ for more information."
)

def test_check_entity_restrictions_unmet_restriction_entity_folder_with_download_file_is_true(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "folder",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
self.syn._check_entity_restrictions(bundle, entity, True)
mocked_warn.assert_called_with(
"\nThis entity has access restrictions. Please visit the web page for this entity "
'(syn.onweb("syn123")). Look for the "Access" label and the lock icon underneath '
'the file name. Click "Request Access", and then review and fulfill the file '
"download requirement(s).\n"
)

def test_check_entity_restrictions__unmet_restriction_downloadFile_is_False(
syn: Synapse,
) -> None:
with patch("warnings.warn") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "file",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"
def test_check_entity_restrictions__unmet_restriction_downloadFile_is_False(
self,
) -> None:
with patch("logging.Logger.warning") as mocked_warn:
bundle = {
"entity": {
"id": "syn123",
"name": "anonymous",
"concreteType": "org.sagebionetworks.repo.model.FileEntity",
"parentId": "syn12345",
},
"entityType": "file",
"restrictionInformation": {"hasUnmetAccessRequirement": True},
}
entity = "syn123"

syn._check_entity_restrictions(bundle, entity, False)
mocked_warn.assert_called_once()
self.syn._check_entity_restrictions(bundle, entity, False)
mocked_warn.assert_called_once()

bundle["entityType"] = "project"
syn._check_entity_restrictions(bundle, entity, False)
assert mocked_warn.call_count == 2
bundle["entityType"] = "project"
self.syn._check_entity_restrictions(bundle, entity, False)
assert mocked_warn.call_count == 2

bundle["entityType"] = "folder"
syn._check_entity_restrictions(bundle, entity, False)
assert mocked_warn.call_count == 3
bundle["entityType"] = "folder"
self.syn._check_entity_restrictions(bundle, entity, False)
assert mocked_warn.call_count == 3


class TestGetColumns(object):
Expand Down Expand Up @@ -1299,6 +1347,7 @@ class TestPrivateGetEntityBundle:
@pytest.fixture(autouse=True, scope="function")
def init_syn(self, syn: Synapse) -> None:
self.syn = syn
self.syn.credentials = SynapseAuthTokenCredentials(token="abc", username="def")

@pytest.fixture(scope="function", autouse=True)
def setup_method(self) -> None:
Expand Down
Loading