Skip to content
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
58 changes: 51 additions & 7 deletions src/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -722,21 +722,65 @@ def _get_entity_visibility(normalized_entity_type, entity_dict):


@app.route("/entities/<id>", methods=["GET"])
@app.route("/_entities/<id>", methods=["POST"])
@strip_whitespace_id()
def get_entity_by_id(id):
# Token is not required, but if an invalid token provided,
# we need to tell the client with a 401 error
validate_token_if_auth_header_exists(request)
authorized = user_in_sennet_read_group(request)
data_access_level = "public" if authorized is False else None

# Use the internal token to query the target entity
# since public entities don't require user token
token = get_internal_token()

# Query target entity against uuid-api and neo4j and return as a dict if exists
entity_dict = query_target_entity(id)

final_result = {}
if request.method == "POST":
if request.is_json and request.json != {}:
filtering_dict = request.json
if len(filtering_dict.keys()) > 0 and "filter_properties" not in filtering_dict:
abort_bad_req("Missing required key: filter_properties")
if "filter_properties" in filtering_dict:
properties_action = filtering_dict.get("is_include", True)
segregated_properties = schema_manager.group_verify_properties_list(
properties=filtering_dict["filter_properties"]
)

entity_dict = app_neo4j_queries.get_entity(
neo4j_driver_instance,
entity_dict['uuid'], data_access_level,
properties=segregated_properties,
is_include_action=properties_action,)

complete_entities_list = schema_manager.get_complete_entities_list(
token,
[entity_dict],
segregated_properties.trigger,
is_include_action=properties_action,
use_memcache=False,
)

# Final result
normalize_result = schema_manager.normalize_entities_list_for_response(
complete_entities_list,
segregated_properties,
is_include_action=properties_action,
is_strict=True,
)
_final_result = schema_manager.remove_unauthorized_fields_from_response(
normalize_result, unauthorized=not authorized
)
if (len(_final_result) > 0):
final_result = _final_result[0]
return jsonify(final_result)

normalized_entity_type = entity_dict["entity_type"]
fields_to_exclude = schema_manager.get_fields_to_exclude(normalized_entity_type)

# Use the internal token to query the target entity
# since public entities don't require user token
token = get_internal_token()

# To verify if a Collection is public, it is necessary to have its Datasets, which
# are populated as triggered data. So pull back the complete entity for
# _get_entity_visibility() to check.
Expand Down Expand Up @@ -787,7 +831,7 @@ def get_entity_by_id(id):
# The `data_access_level` property is available in all entities Source/Sample/Dataset
# and this filter is being used by gateway to check the data_access_level for file assets
# The `status` property is only available in Dataset and being used by search-api for revision
result_filtering_accepted_property_keys = ["data_access_level", "status"]
result_filtering_accepted_property_keys = ["data_access_level", "status", "uuid"]

# Allow for `return_dict` as well since some code passes that to the PUT /entities endpoint. Return as normal
supported_query_params = ["property", "exclude", "return_dict"]
Expand Down Expand Up @@ -841,11 +885,11 @@ def get_entity_by_id(id):
return jsonify(final_result)
else:
# Response with the dict
if public_entity and not user_in_sennet_read_group(request):
if public_entity and not authorized:
final_result = schema_manager.exclude_properties_from_response(
fields_to_exclude, final_result
)
return jsonify(final_result)
return jsonify(final_result)


"""
Expand Down
32 changes: 27 additions & 5 deletions src/app_neo4j_queries.py
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,11 @@ def get_activity(neo4j_driver, uuid):
return result


def get_entity(neo4j_driver, uuid):
def get_entity(neo4j_driver,
uuid,
data_access_level=None,
properties: Union[PropertyGroups, List[str]] = None,
is_include_action: bool = True,):
"""
Get target entity dict

Expand All @@ -134,18 +138,36 @@ def get_entity(neo4j_driver, uuid):
The neo4j database connection pool
uuid : str
The uuid of target entity
data_access_level : Optional[str]
The data access level of the ancestor entities (public or consortium). None returns all ancestors.
properties : Union[PropertyGroups, List[str]]
A list of property keys to filter in or out from the normalized results, default is []
is_include_action : bool
Whether to include or exclude the listed properties

Returns
-------
dict
A dictionary of entity details returned from the Cypher query
"""

predicate = ""
if data_access_level:
predicate = "AND (t.status = 'Published' OR t.data_access_level = $data_access_level) "

result = {}

_activity_query_part = schema_neo4j_queries.activity_query_part(for_all_match=True)
query = (
"MATCH (t:Entity) " "WHERE t.uuid = $uuid " f"{_activity_query_part} {record_field_name}"
)
is_filtered = isinstance(properties, PropertyGroups) or isinstance(properties, list)
if is_filtered:
query = (
f"MATCH (t:Entity) WHERE t.uuid = $uuid {predicate} "
f"{schema_neo4j_queries.exclude_include_query_part(properties, is_include_action)}"
)
else:
_activity_query_part = schema_neo4j_queries.activity_query_part(for_all_match=True)
query = (
"MATCH (t:Entity) " "WHERE t.uuid = $uuid " f"{_activity_query_part} {record_field_name}"
)

logger.info("======get_entity() query======")
logger.info(query)
Expand Down
Loading