diff --git a/SampleService.html b/SampleService.html
index 3e82f9ee..745c9325 100644
--- a/SampleService.html
+++ b/SampleService.html
@@ -1 +1 @@
-
SampleServicemoduleSampleService{typedefintboolean;
typedefinttimestamp;
typedefstringuser;
typedefstringnode_id;
typedefstringsamplenode_type;
typedefstringsample_id;
typedefstringlink_id;
typedefstringsample_name;
typedefintversion;
typedefstringmetadata_key;
typedefstringmetadata_value_key;
typedefstringws_upa;
typedefstringdata_id;
typedefstructure{}SampleNode; typedefstructure{}Sample; typedefstructure{}SampleACLs; typedefstructure{}SampleAddress; typedefstructure{intprior_version;
}CreateSampleParams; typedefstructure{}GetSampleParams; typedefstructure{}GetSampleACLsParams; typedefstructure{}ReplaceSampleACLsParams; typedefstructure{intprefix;
}GetMetadataKeyStaticMetadataParams; typedefstructure{}GetMetadataKeyStaticMetadataResults; typedefstructure{}CreateDataLinkParams; typedefstructure{}DataLink; typedefstructure{}CreateDataLinkResults; typedefstructure{}ExpireDataLinkParams; typedefstructure{}GetDataLinksFromSampleParams; typedefstructure{}GetDataLinksFromSampleResults; typedefstructure{}GetDataLinksFromDataParams; typedefstructure{}GetDataLinksFromDataResults; typedefstructure{}GetSampleViaDataParams; typedefstructure{}GetDataLinkParams; };
\ No newline at end of file
+SampleServicemoduleSampleService{typedefintboolean;
typedefinttimestamp;
typedefstringuser;
typedefstringnode_id;
typedefstringsamplenode_type;
typedefstringsample_id;
typedefstringlink_id;
typedefstringsample_name;
typedefintversion;
typedefstringmetadata_key;
typedefstringmetadata_value_key;
typedefstringws_upa;
typedefstringdata_id;
typedefstructure{}SampleNode; typedefstructure{}Sample; typedefstructure{}SampleACLs; typedefstructure{}SampleAddress; typedefstructure{intprior_version;
}CreateSampleParams; typedefstructure{}GetSampleParams; typedefstructure{}GetSampleACLsParams; typedefstructure{}ReplaceSampleACLsParams; typedefstructure{intprefix;
}GetMetadataKeyStaticMetadataParams; typedefstructure{}GetMetadataKeyStaticMetadataResults; typedefstructure{}CreateDataLinkParams; typedefstructure{}DataLink; typedefstructure{}CreateDataLinkResults; typedefstructure{}ExpireDataLinkParams; typedefstructure{}GetDataLinksFromSampleParams; typedefstructure{}GetDataLinksFromSampleResults; typedefstructure{}GetDataLinksFromDataParams; typedefstructure{}GetDataLinksFromDataResults; typedefstructure{}GetSampleViaDataParams; typedefstructure{}GetDataLinkParams; };
\ No newline at end of file
diff --git a/SampleService.spec b/SampleService.spec
index f5c49913..90d5c0b8 100644
--- a/SampleService.spec
+++ b/SampleService.spec
@@ -367,7 +367,7 @@ module SampleService {
can read are returned.
*/
funcdef get_data_links_from_sample(GetDataLinksFromSampleParams params)
- returns(GetDataLinksFromSampleResults results) authentication required;
+ returns(GetDataLinksFromSampleResults results) authentication optional;
/* get_data_links_from_data parameters.
diff --git a/TODO.md b/TODO.md
index d3a4c05f..ea92a353 100644
--- a/TODO.md
+++ b/TODO.md
@@ -15,7 +15,6 @@
* cache known good users
* cache user roles
* support anonymous users
- * get links from sample
* get links from data
* get sample via data
* remove self from acls (read/write)
diff --git a/lib/SampleService/SampleServiceImpl.py b/lib/SampleService/SampleServiceImpl.py
index 77f3b4a9..3855c4b5 100644
--- a/lib/SampleService/SampleServiceImpl.py
+++ b/lib/SampleService/SampleServiceImpl.py
@@ -53,7 +53,7 @@ class SampleService:
######################################### noqa
VERSION = "0.1.0-alpha18"
GIT_URL = "https://github.com/mrcreosote/sample_service.git"
- GIT_COMMIT_HASH = "5cb8e3652fdb244ee25998a3d96fa048fc6d7d81"
+ GIT_COMMIT_HASH = "dc5bc302aea67790951dacca3df989fc25017ed5"
#BEGIN_CLASS_HEADER
#END_CLASS_HEADER
@@ -549,11 +549,11 @@ def get_data_links_from_sample(self, ctx, params):
sid, ver = _get_sample_address_from_object(params, version_required=True)
dt = _get_datetime_from_epochmillseconds_in_object(params, 'effective_time')
admin = _check_admin(
- self._user_lookup, ctx[_CTX_TOKEN], _AdminPermission.READ,
+ self._user_lookup, ctx.get(_CTX_TOKEN), _AdminPermission.READ,
# pretty annoying to test ctx.log_info is working, do it manually
'get_data_links_from_sample', ctx.log_info, skip_check=not params.get('as_admin'))
links, ts = self._samples.get_links_from_sample(
- _UserID(ctx[_CTX_USER]), _SampleAddress(sid, ver), dt, as_admin=admin)
+ _get_user_from_object(ctx, _CTX_USER), _SampleAddress(sid, ver), dt, as_admin=admin)
results = {'links': _links_to_dicts(links),
'effective_time': _datetime_to_epochmilliseconds(ts)
}
diff --git a/lib/SampleService/SampleServiceServer.py b/lib/SampleService/SampleServiceServer.py
index 67f3bf4a..6ae801bf 100644
--- a/lib/SampleService/SampleServiceServer.py
+++ b/lib/SampleService/SampleServiceServer.py
@@ -375,7 +375,7 @@ def __init__(self):
self.rpc_service.add(impl_SampleService.get_data_links_from_sample,
name='SampleService.get_data_links_from_sample',
types=[dict])
- self.method_authentication['SampleService.get_data_links_from_sample'] = 'required' # noqa
+ self.method_authentication['SampleService.get_data_links_from_sample'] = 'optional' # noqa
self.rpc_service.add(impl_SampleService.get_data_links_from_data,
name='SampleService.get_data_links_from_data',
types=[dict])
diff --git a/test/SampleService_test.py b/test/SampleService_test.py
index c3c3a16a..f2694dfb 100644
--- a/test/SampleService_test.py
+++ b/test/SampleService_test.py
@@ -2265,35 +2265,36 @@ def test_get_links_from_sample_public_read(sample_port, workspace):
_replace_acls(url, id_, TOKEN1, {'public_read': 1})
- # check correct links are returned, user 4 has no explicit permisions
- ret = requests.post(url, headers=get_authorized_headers(TOKEN4), json={
- 'method': 'SampleService.get_data_links_from_sample',
- 'version': '1.1',
- 'id': '42',
- 'params': [{'id': id_, 'version': 1}]
- })
- # print(ret.text)
- assert ret.ok is True
+ for token in [None, TOKEN4]: # anon user & user without explicit permission
+ # check correct links are returned
+ ret = requests.post(url, headers=get_authorized_headers(token), json={
+ 'method': 'SampleService.get_data_links_from_sample',
+ 'version': '1.1',
+ 'id': '42',
+ 'params': [{'id': id_, 'version': 1}]
+ })
+ # print(ret.text)
+ assert ret.ok is True
- assert len(ret.json()['result']) == 1
- assert len(ret.json()['result'][0]) == 2
- assert_ms_epoch_close_to_now(ret.json()['result'][0]['effective_time'])
- assert len(ret.json()['result'][0]['links']) == 1
- link = ret.json()['result'][0]['links'][0]
- assert_ms_epoch_close_to_now(link['created'])
- del link['created']
+ assert len(ret.json()['result']) == 1
+ assert len(ret.json()['result'][0]) == 2
+ assert_ms_epoch_close_to_now(ret.json()['result'][0]['effective_time'])
+ assert len(ret.json()['result'][0]['links']) == 1
+ link = ret.json()['result'][0]['links'][0]
+ assert_ms_epoch_close_to_now(link['created'])
+ del link['created']
- assert link == {
- 'linkid': lid,
- 'id': id_,
- 'version': 1,
- 'node': 'foo',
- 'upa': '1/1/1',
- 'dataid': None,
- 'createdby': USER1,
- 'expiredby': None,
- 'expired': None
- }
+ assert link == {
+ 'linkid': lid,
+ 'id': id_,
+ 'version': 1,
+ 'node': 'foo',
+ 'upa': '1/1/1',
+ 'dataid': None,
+ 'createdby': USER1,
+ 'expiredby': None,
+ 'expired': None
+ }
def test_create_link_fail(sample_port, workspace):
@@ -2420,6 +2421,9 @@ def test_get_links_from_sample_fail(sample_port):
_get_link_from_sample_fail(
sample_port, TOKEN4, {'id': id_, 'version': 1},
f'Sample service error code 20000 Unauthorized: User user4 cannot read sample {id_}')
+ _get_link_from_sample_fail(
+ sample_port, None, {'id': id_, 'version': 1},
+ f'Sample service error code 20000 Unauthorized: Anonymous users cannot read sample {id_}')
badid = uuid.uuid4()
_get_link_from_sample_fail(
sample_port, TOKEN3, {'id': str(badid), 'version': 1},
@@ -2430,6 +2434,10 @@ def test_get_links_from_sample_fail(sample_port):
sample_port, TOKEN4, {'id': id_, 'version': 1, 'as_admin': 1},
'Sample service error code 20000 Unauthorized: User user4 does not have the ' +
'necessary administration privileges to run method get_data_links_from_sample')
+ _get_link_from_sample_fail(
+ sample_port, None, {'id': id_, 'version': 1, 'as_admin': 1},
+ 'Sample service error code 20000 Unauthorized: Anonymous users ' +
+ 'may not act as service administrators.')
def _get_link_from_sample_fail(sample_port, token, params, expected):