diff --git a/Makefile b/Makefile index 4c7ffc96..2a110690 100644 --- a/Makefile +++ b/Makefile @@ -27,7 +27,7 @@ compile: # Don't compile server automatically, overwrites fixes to error handling # Temporarily add the next line to the command line args if recompiliation is needed to add # methods. -# --pysrvname $(SERVICE_CAPS).$(SERVICE_CAPS)Server \ +# --pysrvname $(SERVICE_CAPS).$(SERVICE_CAPS)Server \ kb-sdk compile $(SPEC_FILE) \ --out $(LIB_DIR) \ diff --git a/SampleService.html b/SampleService.html index 68688ec7..6eb1f563 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_idid;
node_idparent;
samplenode_typetype;
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{
sample_idid;
useruser;
list<SampleNode>node_tree;
sample_namename;
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{
sample_idid;
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{
sample_idid;
versionversion;
booleanas_admin;
}
GetSampleParams;

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

/*
*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{
sample_idid;
booleanas_admin;
}
GetSampleACLsParams;

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

/*
*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{
sample_idid;
SampleACLsacls;
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;
sample_idid;
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;
sample_idid;
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{
sample_idid;
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;
sample_idid;
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_idid;
node_idparent;
samplenode_typetype;
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{
sample_idid;
useruser;
list<SampleNode>node_tree;
sample_namename;
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{
sample_idid;
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{
sample_idid;
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{
sample_idid;
booleanas_admin;
}
GetSampleACLsParams;

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

/*
*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{
sample_idid;
SampleACLsacls;
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;
sample_idid;
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;
sample_idid;
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{
sample_idid;
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;
sample_idid;
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 ed4a275e..8d10e11e 100644 --- a/SampleService.spec +++ b/SampleService.spec @@ -167,7 +167,7 @@ module SampleService { } GetSampleParams; /* Get a sample. If the version is omitted the most recent sample is returned. */ - funcdef get_sample(GetSampleParams params) returns (Sample sample) authentication required; + funcdef get_sample(GetSampleParams params) returns (Sample sample) authentication optional; /* get_sample_acls parameters. id - the ID of the sample to retrieve. diff --git a/TODO.md b/TODO.md index dccdaeca..2bacad8a 100644 --- a/TODO.md +++ b/TODO.md @@ -15,7 +15,6 @@ * cache known good users * cache user roles * support anonymous users - * get sample * get sample acls * get links from sample * get links from data diff --git a/lib/SampleService/SampleServiceImpl.py b/lib/SampleService/SampleServiceImpl.py index 20e3180e..9ec38b32 100644 --- a/lib/SampleService/SampleServiceImpl.py +++ b/lib/SampleService/SampleServiceImpl.py @@ -20,7 +20,8 @@ get_upa_from_object as _get_upa_from_object, get_data_unit_id_from_object as _get_data_unit_id_from_object, get_admin_request_from_object as _get_admin_request_from_object, - datetime_to_epochmilliseconds as _datetime_to_epochmilliseconds + datetime_to_epochmilliseconds as _datetime_to_epochmilliseconds, + get_user_from_object as _get_user_from_object, ) from SampleService.core.acls import AdminPermission as _AdminPermission from SampleService.core.sample import SampleAddress as _SampleAddress @@ -52,7 +53,7 @@ class SampleService: ######################################### noqa VERSION = "0.1.0-alpha18" GIT_URL = "https://github.com/mrcreosote/sample_service.git" - GIT_COMMIT_HASH = "208af320923599cab027cf022167238bb78ce785" + GIT_COMMIT_HASH = "a1e16589e20404b119283c8bc42a0dcc97982dfc" #BEGIN_CLASS_HEADER #END_CLASS_HEADER @@ -220,10 +221,11 @@ def get_sample(self, ctx, params): # return variables are: sample #BEGIN get_sample id_, ver = _get_sample_address_from_object(params) - admin = _check_admin(self._user_lookup, ctx[_CTX_TOKEN], _AdminPermission.READ, + admin = _check_admin(self._user_lookup, ctx.get(_CTX_TOKEN), _AdminPermission.READ, # pretty annoying to test ctx.log_info is working, do it manually 'get_sample', ctx.log_info, skip_check=not params.get('as_admin')) - s = self._samples.get_sample(id_, _UserID(ctx[_CTX_USER]), ver, as_admin=admin) + s = self._samples.get_sample( + id_, _get_user_from_object(ctx, _CTX_USER), ver, as_admin=admin) sample = _sample_to_dict(s) #END get_sample diff --git a/lib/SampleService/SampleServiceServer.py b/lib/SampleService/SampleServiceServer.py index 380ba1eb..67418529 100644 --- a/lib/SampleService/SampleServiceServer.py +++ b/lib/SampleService/SampleServiceServer.py @@ -351,7 +351,7 @@ def __init__(self): self.rpc_service.add(impl_SampleService.get_sample, name='SampleService.get_sample', types=[dict]) - self.method_authentication['SampleService.get_sample'] = 'required' # noqa + self.method_authentication['SampleService.get_sample'] = 'optional' # noqa self.rpc_service.add(impl_SampleService.get_sample_acls, name='SampleService.get_sample_acls', types=[dict]) diff --git a/test/SampleService_test.py b/test/SampleService_test.py index 5c354f3a..d93e9b80 100644 --- a/test/SampleService_test.py +++ b/test/SampleService_test.py @@ -440,7 +440,10 @@ def test_status(sample_port): def get_authorized_headers(token): - return {'authorization': token, 'accept': 'application/json'} + headers = {'accept': 'application/json'} + if token is not None: + headers['authorization'] = token + return headers def _check_kafka_messages(kafka, expected_msgs, topic=KAFKA_TOPIC, print_res=False): @@ -741,28 +744,29 @@ def test_get_sample_public_read(sample_port): _replace_acls(url, id_, TOKEN1, {'public_read': 1}) - s = _get_sample(url, TOKEN4, id_) - assert_ms_epoch_close_to_now(s['save_date']) - del s['save_date'] - assert s == { - 'id': id_, - 'version': 1, - 'user': 'user1', - 'name': 'mysample', - 'node_tree': [{'id': 'root', - 'parent': None, - 'type': 'BioReplicate', - 'meta_controlled': {}, - 'meta_user': {} - }, - {'id': 'foo', - 'parent': 'root', - 'type': 'TechReplicate', - 'meta_controlled': {}, - 'meta_user': {} - } - ] - } + for token in [TOKEN4, None]: # unauthed user and anonymous user + s = _get_sample(url, token, id_) + assert_ms_epoch_close_to_now(s['save_date']) + del s['save_date'] + assert s == { + 'id': id_, + 'version': 1, + 'user': 'user1', + 'name': 'mysample', + 'node_tree': [{'id': 'root', + 'parent': None, + 'type': 'BioReplicate', + 'meta_controlled': {}, + 'meta_user': {} + }, + {'id': 'foo', + 'parent': 'root', + 'type': 'TechReplicate', + 'meta_controlled': {}, + 'meta_user': {} + } + ] + } def _get_sample(url, token, id_): @@ -1049,18 +1053,19 @@ def test_get_sample_fail_permissions(sample_port): assert ret.json()['result'][0]['version'] == 1 id_ = ret.json()['result'][0]['id'] - ret = requests.post(url, headers=get_authorized_headers(TOKEN2), json={ - 'method': 'SampleService.get_sample', - 'version': '1.1', - 'id': '42', - 'params': [{'id': id_}] - }) - - # print(ret.text) - assert ret.status_code == 500 - assert ret.json()['error']['message'] == ( + _get_sample_fail( + url, TOKEN2, {'id': id_}, f'Sample service error code 20000 Unauthorized: User user2 cannot read sample {id_}') + _get_sample_fail( + url, None, {'id': id_}, + f'Sample service error code 20000 Unauthorized: Anonymous users cannot read sample {id_}') + + _get_sample_fail( + url, None, {'id': id_, 'as_admin': 1}, + 'Sample service error code 20000 Unauthorized: Anonymous users ' + + 'may not act as service administrators.') + def test_get_sample_fail_admin_permissions(sample_port): url = f'http://localhost:{sample_port}' @@ -1083,19 +1088,25 @@ def test_get_sample_fail_admin_permissions(sample_port): assert ret.json()['result'][0]['version'] == 1 id_ = ret.json()['result'][0]['id'] + _get_sample_fail( + url, TOKEN4, {'id': id_, 'as_admin': 1}, + 'Sample service error code 20000 Unauthorized: User user4 does not have the ' + + 'necessary administration privileges to run method get_sample') + + +def _get_sample_fail(url, token, params, expected): + # user 4 has no admin permissions - ret = requests.post(url, headers=get_authorized_headers(TOKEN4), json={ + ret = requests.post(url, headers=get_authorized_headers(token), json={ 'method': 'SampleService.get_sample', 'version': '1.1', 'id': '42', - 'params': [{'id': id_, 'as_admin': 1}] + 'params': [params] }) # print(ret.text) assert ret.status_code == 500 - assert ret.json()['error']['message'] == ( - 'Sample service error code 20000 Unauthorized: User user4 does not have the ' + - 'necessary administration privileges to run method get_sample') + assert ret.json()['error']['message'] == expected def test_get_and_replace_acls(sample_port, kafka):