From fbb853dda99c75e726fc1aeb28299c4621add1a7 Mon Sep 17 00:00:00 2001 From: DerekFurstPitt Date: Thu, 30 Nov 2023 15:47:37 -0500 Subject: [PATCH] added fields ingest_task and assigned_to_group_name and their accompanying validators. Fixed bug in validate_if_retraction_permitted with group names --- src/schema/provenance_schema.yaml | 32 ++++++++++++++ src/schema/schema_validators.py | 69 ++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 2 deletions(-) diff --git a/src/schema/provenance_schema.yaml b/src/schema/provenance_schema.yaml index 05174972..850383b4 100644 --- a/src/schema/provenance_schema.yaml +++ b/src/schema/provenance_schema.yaml @@ -490,6 +490,22 @@ ENTITIES: description: "A list of all status change events. Each entry in the list is a dictionary containing the change_timestamp, changed_by_email, previous_status, new_status" generated: true immutable: true + assigned_to_group_name: + type: string + description: The group who is responsible for the next step in the ingest process + before_property_create_validators: + - validate_in_admin_group + - validate_group_name + before_property_update_validators: + - validate_in_admin_group + - validate_group_name + ingest_task: + type: string + description: A description of the next task in the ingest process + before_property_create_validators: + - validate_in_admin_group + before_property_update_validators: + - validate_in_admin_group ############################################# Publication ############################################# Publication: @@ -1176,3 +1192,19 @@ ENTITIES: description: "A list of all status change events. Each entry in the list is a dictionary containing the change_timestamp, changed_by_email, previous_status, new_status" generated: true immutable: true + assigned_to_group_name: + type: string + description: The group who is responsible for the next step in the ingest process + before_property_create_validators: + - validate_in_admin_group + - validate_group_name + before_property_update_validators: + - validate_in_admin_group + - validate_group_name + ingest_task: + type: string + description: A description of the next task in the ingest process + before_property_create_validators: + - validate_in_admin_group + before_property_update_validators: + - validate_in_admin_group diff --git a/src/schema/schema_validators.py b/src/schema/schema_validators.py index 8c1269a5..ac495170 100644 --- a/src/schema/schema_validators.py +++ b/src/schema/schema_validators.py @@ -8,6 +8,7 @@ from schema import schema_errors from schema import schema_neo4j_queries from schema.schema_constants import SchemaConstants +from hubmap_commons import hm_auth logger = logging.getLogger(__name__) @@ -324,7 +325,7 @@ def validate_if_retraction_permitted(property_key, normalized_entity_type, reque # The property 'hmgroupids' is ALWAYS in the output with using schema_manager.get_user_info() # when the token in request is a nexus_token user_info = schema_manager.get_user_info(request) - hubmap_read_group_uuid = schema_manager.get_auth_helper_instance().groupNameToId('HuBMAP-READ')['uuid'] + hubmap_admin_group_uuid = schema_manager.get_auth_helper_instance().groupNameToId('HuBMAP-Data-Admin')['uuid'] except Exception as e: # Log the full stack trace, prepend a line with our message logger.exception(e) @@ -334,7 +335,7 @@ def validate_if_retraction_permitted(property_key, normalized_entity_type, reque # We treat such cases as the user not in the HuBMAP-READ group raise ValueError("Failed to parse the permission based on token, retraction is not allowed") - if hubmap_read_group_uuid not in user_info['hmgroupids']: + if hubmap_admin_group_uuid not in user_info['hmgroupids']: raise ValueError("Permission denied, retraction is not allowed") @@ -534,6 +535,70 @@ def validate_creation_action(property_key, normalized_entity_type, request, exis raise ValueError(f"The property {property_key} cannot be empty, when specified.") +""" +Validate that the user is in Hubmap-Data-Admin before creating or updating field 'assigned_to_group_name' + +Parameters +---------- +property_key : str + The target property key +normalized_type : str + Submission +request: Flask request object + The instance of Flask request passed in from application request +existing_data_dict : dict + A dictionary that contains all existing entity properties +new_data_dict : dict + The json data in request body, already after the regular validations +""" +def validate_in_admin_group(property_key, normalized_entity_type, request, existing_data_dict, new_data_dict): + try: + # The property 'hmgroupids' is ALWAYS in the output with using schema_manager.get_user_info() + # when the token in request is a nexus_token + user_info = schema_manager.get_user_info(request) + hubmap_admin_group_uuid = schema_manager.get_auth_helper_instance().groupNameToId('HuBMAP-Data-Admin')['uuid'] + except Exception as e: + # Log the full stack trace, prepend a line with our message + logger.exception(e) + + # If the token is not a groups token, no group information available + # The commons.hm_auth.AuthCache would return a Response with 500 error message + # We treat such cases as the user not in the HuBMAP-READ group + raise ValueError("Failed to parse the permission based on token, retraction is not allowed") + + if hubmap_admin_group_uuid not in user_info['hmgroupids']: + raise ValueError(f"Permission denied, not permitted to set property {property_key}") + + +""" +Validate that the provided group_name is one of the group name 'shortname' values where data_provider == true available +from hubmap-commons in the xxx-globus-groups.json file on entity creation + +Parameters +---------- +property_key : str + The target property key +normalized_type : str + Submission +request: Flask request object + The instance of Flask request passed in from application request +existing_data_dict : dict + A dictionary that contains all existing entity properties +new_data_dict : dict + The json data in request body, already after the regular validations +""" +def validate_group_name(property_key, normalized_entity_type, request, existing_data_dict, new_data_dict): + assigned_to_group_name = new_data_dict['assigned_to_group_name'] + globus_groups = schema_manager.get_auth_helper_instance().getHuBMAPGroupInfo() + shortnames = list({value.get("shortname") for value in globus_groups.values() if value.get("shortname") is not None}) + if assigned_to_group_name not in shortnames: + raise ValueError("Invalid value for 'assigned_to_group_name'") + is_data_provider = next((entry.get("data_provider", False) for entry in globus_groups.values() if entry.get("shortname") == assigned_to_group_name), False) + if not is_data_provider: + raise ValueError("Invalid group in 'assigned_to_group_name'. Must be a data provider") + + + #################################################################################################### ## Internal Functions ####################################################################################################