From 024f1cebd58d1b66109faf9d748e786ef4b4d4d5 Mon Sep 17 00:00:00 2001 From: Gavin Date: Thu, 2 Jul 2020 10:37:08 -0700 Subject: [PATCH] Support anon users for get links from sample --- SampleService.html | 2 +- SampleService.spec | 2 +- TODO.md | 1 - lib/SampleService/SampleServiceImpl.py | 6 +-- lib/SampleService/SampleServiceServer.py | 2 +- test/SampleService_test.py | 62 +++++++++++++----------- 6 files changed, 41 insertions(+), 34 deletions(-) diff --git a/SampleService.html b/SampleService.html index 3e82f9ee..745c9325 100644 --- a/SampleService.html +++ b/SampleService.html @@ -1 +1 @@ -SampleService
/*
*A KBase module: SampleService
*
*Handles creating, updating, retriving samples and linking data to samples.
*
*Note that usage of the administration flags will be logged by the service.
*/
moduleSampleService{

/*
*A boolean value, 0 for false, 1 for true.
*/
typedefintboolean;

/*
*A timestamp in epoch milliseconds.
*/
typedefinttimestamp;

/*
*A user's username.
*/
typedefstringuser;

/*
*A SampleNode ID. Must be unique within a Sample and be less than 255 characters.
*/
typedefstringnode_id;

/*
*The type of a sample node. One of:
*BioReplicate - a biological replicate. Always at the top of the sample tree.
*TechReplicate - a technical replicate.
*SubSample - a sub sample that is not a technical replicate.
*/
typedefstringsamplenode_type;

/*
*A Sample ID. Must be globally unique. Always assigned by the Sample service.
*/
typedefstringsample_id;

/*
*A link ID. Must be globally unique. Always assigned by the Sample service.
*Typically only of use to service admins.
*/
typedefstringlink_id;

/*
*A sample name. Must be less than 255 characters.
*/
typedefstringsample_name;

/*
*The version of a sample. Always > 0.
*/
typedefintversion;

/*
*A key in a metadata key/value pair. Less than 1000 unicode characters.
*/
typedefstringmetadata_key;

/*
*A key for a value associated with a piece of metadata. Less than 1000 unicode characters.
*Examples: units, value, species
*/
typedefstringmetadata_value_key;

/*
*Metadata attached to a sample.
*The UnspecifiedObject map values MUST be a primitive type - either int, float, string,
*or equivalent typedefs.
*/
typedefmapping<metadata_key,mapping<metadata_value_key,UnspecifiedObject>>metadata;

/*
*A KBase Workspace service Unique Permanent Address (UPA). E.g. 5/6/7 where 5 is the
*workspace ID, 6 the object ID, and 7 the object version.
*/
typedefstringws_upa;

/*
*An id for a unit of data within a KBase Workspace object. A single object may contain
*many data units. A dataid is expected to be unique within a single object. Must be less
*than 255 characters.
*/
typedefstringdata_id;

/*
*A node in a sample tree.
*id - the ID of the node.
*parent - the id of the parent node for the current node. BioReplicate nodes, and only
*BioReplicate nodes, do not have a parent.
*type - the type of the node.
*meta_controlled - metadata restricted by the sample controlled vocabulary and validators.
*meta_user - unrestricted metadata.
*/
typedefstructure{
node_idparent;
metadatameta_controlled;
metadatameta_user;
}
SampleNode;

/*
*A Sample, consisting of a tree of subsamples and replicates.
*id - the ID of the sample.
*user - the user that saved the sample.
*node_tree - the tree(s) of sample nodes in the sample. The the roots of all trees must
*be BioReplicate nodes. All the BioReplicate nodes must be at the start of the list,
*and all child nodes must occur after their parents in the list.
*name - the name of the sample. Must be less than 255 characters.
*save_date - the date the sample version was saved.
*version - the version of the sample.
*/
typedefstructure{
useruser;
list<SampleNode>node_tree;
timestampsave_date;
versionversion;
}
Sample;

/*
*Access control lists for a sample. Access levels include the privileges of the lower
*access levels.
*
*owner - the user that created and owns the sample.
*admin - users that can administrate (e.g. alter ACLs) the sample.
*write - users that can write (e.g. create a new version) to the sample.
*read - users that can view the sample.
*public_read - whether any user can read the sample, regardless of permissions.
*/
typedefstructure{
userowner;
list<user>admin;
list<user>write;
list<user>read;
booleanpublic_read;
}
SampleACLs;

/*
*A Sample ID and version.
*id - the ID of the sample.
*version - the version of the sample.
*/
typedefstructure{
versionversion;
}
SampleAddress;

/*
*Parameters for creating a sample.
*If Sample.id is null, a new Sample is created along with a new ID.
*Otherwise, a new version of Sample.id is created. If Sample.id does not exist, an error
*is returned.
*Any incoming user, version or timestamp in the incoming sample is ignored.
*
*sample - the sample to save.
*prior_version - if non-null, ensures that no other sample version is saved between
*prior_version and the version that is created by this save. If this is not the case,
*the sample will fail to save.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - create the sample as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the sample if a
*new version is saved.
*/
typedefstructure{
Samplesample;
intprior_version;
booleanas_admin;
useras_user;
}
CreateSampleParams;

/*
*Create a new sample or a sample version.
*/
funcdefcreate_sample(CreateSampleParamsparams)returns(SampleAddressaddress)authenticationrequired;

/*
*get_sample parameters.
*id - the ID of the sample to retrieve.
*version - the version of the sample to retrieve, or the most recent sample if omitted.
*as_admin - get the sample regardless of ACLs as long as the user has administration read
*permissions.
*/
typedefstructure{
versionversion;
booleanas_admin;
}
GetSampleParams;

/*
*Get a sample. If the version is omitted the most recent sample is returned.
*/
funcdefget_sample(GetSampleParamsparams)returns(Samplesample)authenticationoptional;

/*
*get_sample_acls parameters.
*id - the ID of the sample to retrieve.
*as_admin - get the sample acls regardless of ACL contents as long as the user has
*administration read permissions.
*/
typedefstructure{
booleanas_admin;
}
GetSampleACLsParams;

/*
*Get a sample's ACLs.
*/
funcdefget_sample_acls(GetSampleACLsParamsparams)returns(SampleACLsacls)authenticationoptional;

/*
*replace_sample_acls parameters.
*
*id - the ID of the sample to modify.
*acls - the ACLs to set on the sample.
*as_admin - replace the sample acls regardless of ACL contents as long as the user has
*full administration permissions.
*/
typedefstructure{
booleanas_admin;
}
ReplaceSampleACLsParams;

/*
*Completely overwrite a sample's ACLs. Any current ACLs are replaced by the provided
*ACLs, even if empty, and gone forever.
*
*The sample owner cannot be changed via this method.
*/
funcdefreplace_sample_acls(ReplaceSampleACLsParamsparams)returns()authenticationrequired;

/*
*get_metadata_key_static_metadata parameters.
*
*keys - the list of metadata keys to interrogate.
*prefix -
*0 (the default) to interrogate standard metadata keys.
*1 to interrogate prefix metadata keys, but require an exact match to the prefix key.
*2 to interrogate prefix metadata keys, but any keys which are a prefix of the
*provided keys will be included in the results.
*/
typedefstructure{
list<metadata_key>keys;
intprefix;
}
GetMetadataKeyStaticMetadataParams;

/*
*get_metadata_key_static_metadata results.
*
*static_metadata - the static metadata for the requested keys.
*/
typedefstructure{
metadatastatic_metadata;
}
GetMetadataKeyStaticMetadataResults;

/*
*Get static metadata for one or more metadata keys.
*
*The static metadata for a metadata key is metadata *about* the key - e.g. it may
*define the key's semantics or denote that the key is linked to an ontological ID.
*
*The static metadata does not change without the service being restarted. Client caching is
*recommended to improve performance.
*/
funcdefget_metadata_key_static_metadata(GetMetadataKeyStaticMetadataParamsparams)returns(GetMetadataKeyStaticMetadataResultsresults)authenticationnone;

/*
*create_data_link parameters.
*
*upa - the workspace UPA of the object to be linked.
*dataid - the dataid of the data to be linked, if any, within the object. If omitted the
*entire object is linked to the sample.
*id - the sample id.
*version - the sample version.
*node - the sample node.
*update - if false (the default), fail if a link already exists from the data unit (the
*combination of the UPA and dataid). if true, expire the old link and create the new
*link unless the link is already to the requested sample node, in which case the
*operation is a no-op.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - create the link as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the data or
*sample.
*/
typedefstructure{
ws_upaupa;
data_iddataid;
versionversion;
node_idnode;
booleanupdate;
booleanas_admin;
useras_user;
}
CreateDataLinkParams;

/*
*A data link from a KBase workspace object to a sample.
*
*upa - the workspace UPA of the linked object.
*dataid - the dataid of the linked data, if any, within the object. If omitted the
*entire object is linked to the sample.
*id - the sample id.
*version - the sample version.
*node - the sample node.
*createdby - the user that created the link.
*created - the time the link was created.
*expiredby - the user that expired the link, if any.
*expired - the time the link was expired, if at all.
*/
typedefstructure{
link_idlinkid;
ws_upaupa;
data_iddataid;
versionversion;
node_idnode;
usercreatedby;
timestampcreated;
userexpiredby;
timestampexpired;
}
DataLink;

/*
*create_data_link results.
*
*new_link - the new link.
*/
typedefstructure{
DataLinknew_link;
}
CreateDataLinkResults;

/*
*Create a link from a KBase Workspace object to a sample.
*
*The user must have admin permissions for the sample and write permissions for the
*Workspace object.
*/
funcdefcreate_data_link(CreateDataLinkParamsparams)returns(CreateDataLinkResultsresults)authenticationrequired;

/*
*expire_data_link parameters.
*
*upa - the workspace upa of the object from which the link originates.
*dataid - the dataid, if any, of the data within the object from which the link originates.
*Omit for links where the link is from the entire object.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - expire the link as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the link if a
*new version is saved.
*/
typedefstructure{
ws_upaupa;
data_iddataid;
booleanas_admin;
useras_user;
}
ExpireDataLinkParams;

/*
*Expire a link from a KBase Workspace object.
*
*The user must have admin permissions for the sample and write permissions for the
*Workspace object.
*/
funcdefexpire_data_link(ExpireDataLinkParamsparams)returns()authenticationrequired;

/*
*get_data_links_from_sample parameters.
*
*id - the sample ID.
*version - the sample version.
*effective_time - the effective time at which the query should be run - the default is
*the current time. Providing a time allows for reproducibility of previous results.
*as_admin - run the method as a service administrator. The user must have read
*administration permissions.
*/
typedefstructure{
versionversion;
timestampeffective_time;
booleanas_admin;
}
GetDataLinksFromSampleParams;

/*
*get_data_links_from_sample results.
*
*links - the links.
*effective_time - the time at which the query was run. This timestamp, if saved, can be
*used when running the method again to ensure reproducible results. Note that changes
*to workspace permissions may cause results to change over time.
*/
typedefstructure{
list<DataLink>links;
timestampeffective_time;
}
GetDataLinksFromSampleResults;

/*
*Get data links to Workspace objects originating from a sample.
*
*The user must have read permissions to the sample. Only Workspace objects the user
*can read are returned.
*/
funcdefget_data_links_from_sample(GetDataLinksFromSampleParamsparams)returns(GetDataLinksFromSampleResultsresults)authenticationrequired;

/*
*get_data_links_from_data parameters.
*
*upa - the data UPA.
*effective_time - the effective time at which the query should be run - the default is
*the current time. Providing a time allows for reproducibility of previous results.
*as_admin - run the method as a service administrator. The user must have read
*administration permissions.
*/
typedefstructure{
ws_upaupa;
timestampeffective_time;
booleanas_admin;
}
GetDataLinksFromDataParams;

/*
*get_data_links_from_data results.
*
*links - the links.
*effective_time - the time at which the query was run. This timestamp, if saved, can be
*used when running the method again to ensure reproducible results.
*/
typedefstructure{
list<DataLink>links;
timestampeffective_time;
}
GetDataLinksFromDataResults;

/*
*Get data links to samples originating from Workspace data.
*
*The user must have read permissions to the workspace data.
*/
funcdefget_data_links_from_data(GetDataLinksFromDataParamsparams)returns(GetDataLinksFromDataResultsresults)authenticationrequired;

/*
*get_sample_via_data parameters.
*
*upa - the workspace UPA of the target object.
*id - the target sample id.
*version - the target sample version.
*/
typedefstructure{
ws_upaupa;
versionversion;
}
GetSampleViaDataParams;

/*
*Get a sample via a workspace object. Read permissions to a workspace object grants
*read permissions to all versions of any linked samples, whether the links are expired or
*not. This method allows for fetching samples when the user does not have explicit
*read access to the sample.
*/
funcdefget_sample_via_data(GetSampleViaDataParamsparams)returns(Samplesample)authenticationrequired;

/*
*get_data_link parameters.
*
*linkid - the link ID.
*/
typedefstructure{
link_idlinkid;
}
GetDataLinkParams;

/*
*Get a link, expired or not, by its ID. This method requires read administration privileges
*for the service.
*/
funcdefget_data_link(GetDataLinkParamsparams)returns(DataLinklink)authenticationrequired;
};

Function Index

create_data_link
create_sample
expire_data_link
get_data_link
get_data_links_from_data
get_data_links_from_sample
get_metadata_key_static_metadata
get_sample
get_sample_acls
get_sample_via_data
replace_sample_acls

Type Index

boolean
CreateDataLinkParams
CreateDataLinkResults
CreateSampleParams
data_id
DataLink
ExpireDataLinkParams
GetDataLinkParams
GetDataLinksFromDataParams
GetDataLinksFromDataResults
GetDataLinksFromSampleParams
GetDataLinksFromSampleResults
GetMetadataKeyStaticMetadataParams
GetMetadataKeyStaticMetadataResults
GetSampleACLsParams
GetSampleParams
GetSampleViaDataParams
link_id
metadata
metadata_key
metadata_value_key
node_id
ReplaceSampleACLsParams
Sample
sample_id
sample_name
SampleACLs
SampleAddress
SampleNode
samplenode_type
timestamp
user
version
ws_upa
\ No newline at end of file +SampleService
/*
*A KBase module: SampleService
*
*Handles creating, updating, retriving samples and linking data to samples.
*
*Note that usage of the administration flags will be logged by the service.
*/
moduleSampleService{

/*
*A boolean value, 0 for false, 1 for true.
*/
typedefintboolean;

/*
*A timestamp in epoch milliseconds.
*/
typedefinttimestamp;

/*
*A user's username.
*/
typedefstringuser;

/*
*A SampleNode ID. Must be unique within a Sample and be less than 255 characters.
*/
typedefstringnode_id;

/*
*The type of a sample node. One of:
*BioReplicate - a biological replicate. Always at the top of the sample tree.
*TechReplicate - a technical replicate.
*SubSample - a sub sample that is not a technical replicate.
*/
typedefstringsamplenode_type;

/*
*A Sample ID. Must be globally unique. Always assigned by the Sample service.
*/
typedefstringsample_id;

/*
*A link ID. Must be globally unique. Always assigned by the Sample service.
*Typically only of use to service admins.
*/
typedefstringlink_id;

/*
*A sample name. Must be less than 255 characters.
*/
typedefstringsample_name;

/*
*The version of a sample. Always > 0.
*/
typedefintversion;

/*
*A key in a metadata key/value pair. Less than 1000 unicode characters.
*/
typedefstringmetadata_key;

/*
*A key for a value associated with a piece of metadata. Less than 1000 unicode characters.
*Examples: units, value, species
*/
typedefstringmetadata_value_key;

/*
*Metadata attached to a sample.
*The UnspecifiedObject map values MUST be a primitive type - either int, float, string,
*or equivalent typedefs.
*/
typedefmapping<metadata_key,mapping<metadata_value_key,UnspecifiedObject>>metadata;

/*
*A KBase Workspace service Unique Permanent Address (UPA). E.g. 5/6/7 where 5 is the
*workspace ID, 6 the object ID, and 7 the object version.
*/
typedefstringws_upa;

/*
*An id for a unit of data within a KBase Workspace object. A single object may contain
*many data units. A dataid is expected to be unique within a single object. Must be less
*than 255 characters.
*/
typedefstringdata_id;

/*
*A node in a sample tree.
*id - the ID of the node.
*parent - the id of the parent node for the current node. BioReplicate nodes, and only
*BioReplicate nodes, do not have a parent.
*type - the type of the node.
*meta_controlled - metadata restricted by the sample controlled vocabulary and validators.
*meta_user - unrestricted metadata.
*/
typedefstructure{
node_idparent;
metadatameta_controlled;
metadatameta_user;
}
SampleNode;

/*
*A Sample, consisting of a tree of subsamples and replicates.
*id - the ID of the sample.
*user - the user that saved the sample.
*node_tree - the tree(s) of sample nodes in the sample. The the roots of all trees must
*be BioReplicate nodes. All the BioReplicate nodes must be at the start of the list,
*and all child nodes must occur after their parents in the list.
*name - the name of the sample. Must be less than 255 characters.
*save_date - the date the sample version was saved.
*version - the version of the sample.
*/
typedefstructure{
useruser;
list<SampleNode>node_tree;
timestampsave_date;
versionversion;
}
Sample;

/*
*Access control lists for a sample. Access levels include the privileges of the lower
*access levels.
*
*owner - the user that created and owns the sample.
*admin - users that can administrate (e.g. alter ACLs) the sample.
*write - users that can write (e.g. create a new version) to the sample.
*read - users that can view the sample.
*public_read - whether any user can read the sample, regardless of permissions.
*/
typedefstructure{
userowner;
list<user>admin;
list<user>write;
list<user>read;
booleanpublic_read;
}
SampleACLs;

/*
*A Sample ID and version.
*id - the ID of the sample.
*version - the version of the sample.
*/
typedefstructure{
versionversion;
}
SampleAddress;

/*
*Parameters for creating a sample.
*If Sample.id is null, a new Sample is created along with a new ID.
*Otherwise, a new version of Sample.id is created. If Sample.id does not exist, an error
*is returned.
*Any incoming user, version or timestamp in the incoming sample is ignored.
*
*sample - the sample to save.
*prior_version - if non-null, ensures that no other sample version is saved between
*prior_version and the version that is created by this save. If this is not the case,
*the sample will fail to save.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - create the sample as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the sample if a
*new version is saved.
*/
typedefstructure{
Samplesample;
intprior_version;
booleanas_admin;
useras_user;
}
CreateSampleParams;

/*
*Create a new sample or a sample version.
*/
funcdefcreate_sample(CreateSampleParamsparams)returns(SampleAddressaddress)authenticationrequired;

/*
*get_sample parameters.
*id - the ID of the sample to retrieve.
*version - the version of the sample to retrieve, or the most recent sample if omitted.
*as_admin - get the sample regardless of ACLs as long as the user has administration read
*permissions.
*/
typedefstructure{
versionversion;
booleanas_admin;
}
GetSampleParams;

/*
*Get a sample. If the version is omitted the most recent sample is returned.
*/
funcdefget_sample(GetSampleParamsparams)returns(Samplesample)authenticationoptional;

/*
*get_sample_acls parameters.
*id - the ID of the sample to retrieve.
*as_admin - get the sample acls regardless of ACL contents as long as the user has
*administration read permissions.
*/
typedefstructure{
booleanas_admin;
}
GetSampleACLsParams;

/*
*Get a sample's ACLs.
*/
funcdefget_sample_acls(GetSampleACLsParamsparams)returns(SampleACLsacls)authenticationoptional;

/*
*replace_sample_acls parameters.
*
*id - the ID of the sample to modify.
*acls - the ACLs to set on the sample.
*as_admin - replace the sample acls regardless of ACL contents as long as the user has
*full administration permissions.
*/
typedefstructure{
booleanas_admin;
}
ReplaceSampleACLsParams;

/*
*Completely overwrite a sample's ACLs. Any current ACLs are replaced by the provided
*ACLs, even if empty, and gone forever.
*
*The sample owner cannot be changed via this method.
*/
funcdefreplace_sample_acls(ReplaceSampleACLsParamsparams)returns()authenticationrequired;

/*
*get_metadata_key_static_metadata parameters.
*
*keys - the list of metadata keys to interrogate.
*prefix -
*0 (the default) to interrogate standard metadata keys.
*1 to interrogate prefix metadata keys, but require an exact match to the prefix key.
*2 to interrogate prefix metadata keys, but any keys which are a prefix of the
*provided keys will be included in the results.
*/
typedefstructure{
list<metadata_key>keys;
intprefix;
}
GetMetadataKeyStaticMetadataParams;

/*
*get_metadata_key_static_metadata results.
*
*static_metadata - the static metadata for the requested keys.
*/
typedefstructure{
metadatastatic_metadata;
}
GetMetadataKeyStaticMetadataResults;

/*
*Get static metadata for one or more metadata keys.
*
*The static metadata for a metadata key is metadata *about* the key - e.g. it may
*define the key's semantics or denote that the key is linked to an ontological ID.
*
*The static metadata does not change without the service being restarted. Client caching is
*recommended to improve performance.
*/
funcdefget_metadata_key_static_metadata(GetMetadataKeyStaticMetadataParamsparams)returns(GetMetadataKeyStaticMetadataResultsresults)authenticationnone;

/*
*create_data_link parameters.
*
*upa - the workspace UPA of the object to be linked.
*dataid - the dataid of the data to be linked, if any, within the object. If omitted the
*entire object is linked to the sample.
*id - the sample id.
*version - the sample version.
*node - the sample node.
*update - if false (the default), fail if a link already exists from the data unit (the
*combination of the UPA and dataid). if true, expire the old link and create the new
*link unless the link is already to the requested sample node, in which case the
*operation is a no-op.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - create the link as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the data or
*sample.
*/
typedefstructure{
ws_upaupa;
data_iddataid;
versionversion;
node_idnode;
booleanupdate;
booleanas_admin;
useras_user;
}
CreateDataLinkParams;

/*
*A data link from a KBase workspace object to a sample.
*
*upa - the workspace UPA of the linked object.
*dataid - the dataid of the linked data, if any, within the object. If omitted the
*entire object is linked to the sample.
*id - the sample id.
*version - the sample version.
*node - the sample node.
*createdby - the user that created the link.
*created - the time the link was created.
*expiredby - the user that expired the link, if any.
*expired - the time the link was expired, if at all.
*/
typedefstructure{
link_idlinkid;
ws_upaupa;
data_iddataid;
versionversion;
node_idnode;
usercreatedby;
timestampcreated;
userexpiredby;
timestampexpired;
}
DataLink;

/*
*create_data_link results.
*
*new_link - the new link.
*/
typedefstructure{
DataLinknew_link;
}
CreateDataLinkResults;

/*
*Create a link from a KBase Workspace object to a sample.
*
*The user must have admin permissions for the sample and write permissions for the
*Workspace object.
*/
funcdefcreate_data_link(CreateDataLinkParamsparams)returns(CreateDataLinkResultsresults)authenticationrequired;

/*
*expire_data_link parameters.
*
*upa - the workspace upa of the object from which the link originates.
*dataid - the dataid, if any, of the data within the object from which the link originates.
*Omit for links where the link is from the entire object.
*as_admin - run the method as a service administrator. The user must have full
*administration permissions.
*as_user - expire the link as a different user. Ignored if as_admin is not true. Neither
*the administrator nor the impersonated user need have permissions to the link if a
*new version is saved.
*/
typedefstructure{
ws_upaupa;
data_iddataid;
booleanas_admin;
useras_user;
}
ExpireDataLinkParams;

/*
*Expire a link from a KBase Workspace object.
*
*The user must have admin permissions for the sample and write permissions for the
*Workspace object.
*/
funcdefexpire_data_link(ExpireDataLinkParamsparams)returns()authenticationrequired;

/*
*get_data_links_from_sample parameters.
*
*id - the sample ID.
*version - the sample version.
*effective_time - the effective time at which the query should be run - the default is
*the current time. Providing a time allows for reproducibility of previous results.
*as_admin - run the method as a service administrator. The user must have read
*administration permissions.
*/
typedefstructure{
versionversion;
timestampeffective_time;
booleanas_admin;
}
GetDataLinksFromSampleParams;

/*
*get_data_links_from_sample results.
*
*links - the links.
*effective_time - the time at which the query was run. This timestamp, if saved, can be
*used when running the method again to ensure reproducible results. Note that changes
*to workspace permissions may cause results to change over time.
*/
typedefstructure{
list<DataLink>links;
timestampeffective_time;
}
GetDataLinksFromSampleResults;

/*
*Get data links to Workspace objects originating from a sample.
*
*The user must have read permissions to the sample. Only Workspace objects the user
*can read are returned.
*/
funcdefget_data_links_from_sample(GetDataLinksFromSampleParamsparams)returns(GetDataLinksFromSampleResultsresults)authenticationoptional;

/*
*get_data_links_from_data parameters.
*
*upa - the data UPA.
*effective_time - the effective time at which the query should be run - the default is
*the current time. Providing a time allows for reproducibility of previous results.
*as_admin - run the method as a service administrator. The user must have read
*administration permissions.
*/
typedefstructure{
ws_upaupa;
timestampeffective_time;
booleanas_admin;
}
GetDataLinksFromDataParams;

/*
*get_data_links_from_data results.
*
*links - the links.
*effective_time - the time at which the query was run. This timestamp, if saved, can be
*used when running the method again to ensure reproducible results.
*/
typedefstructure{
list<DataLink>links;
timestampeffective_time;
}
GetDataLinksFromDataResults;

/*
*Get data links to samples originating from Workspace data.
*
*The user must have read permissions to the workspace data.
*/
funcdefget_data_links_from_data(GetDataLinksFromDataParamsparams)returns(GetDataLinksFromDataResultsresults)authenticationrequired;

/*
*get_sample_via_data parameters.
*
*upa - the workspace UPA of the target object.
*id - the target sample id.
*version - the target sample version.
*/
typedefstructure{
ws_upaupa;
versionversion;
}
GetSampleViaDataParams;

/*
*Get a sample via a workspace object. Read permissions to a workspace object grants
*read permissions to all versions of any linked samples, whether the links are expired or
*not. This method allows for fetching samples when the user does not have explicit
*read access to the sample.
*/
funcdefget_sample_via_data(GetSampleViaDataParamsparams)returns(Samplesample)authenticationrequired;

/*
*get_data_link parameters.
*
*linkid - the link ID.
*/
typedefstructure{
link_idlinkid;
}
GetDataLinkParams;

/*
*Get a link, expired or not, by its ID. This method requires read administration privileges
*for the service.
*/
funcdefget_data_link(GetDataLinkParamsparams)returns(DataLinklink)authenticationrequired;
};

Function Index

create_data_link
create_sample
expire_data_link
get_data_link
get_data_links_from_data
get_data_links_from_sample
get_metadata_key_static_metadata
get_sample
get_sample_acls
get_sample_via_data
replace_sample_acls

Type Index

boolean
CreateDataLinkParams
CreateDataLinkResults
CreateSampleParams
data_id
DataLink
ExpireDataLinkParams
GetDataLinkParams
GetDataLinksFromDataParams
GetDataLinksFromDataResults
GetDataLinksFromSampleParams
GetDataLinksFromSampleResults
GetMetadataKeyStaticMetadataParams
GetMetadataKeyStaticMetadataResults
GetSampleACLsParams
GetSampleParams
GetSampleViaDataParams
link_id
metadata
metadata_key
metadata_value_key
node_id
ReplaceSampleACLsParams
Sample
sample_id
sample_name
SampleACLs
SampleAddress
SampleNode
samplenode_type
timestamp
user
version
ws_upa
\ 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):