def _parse_operations_metadata(self, upper_elem): """ Parses the <Operation> elements inside of <OperationsMetadata> Args: upper_elem (Element): The upper xml element Returns: """ operations_objs = xml_helper.try_get_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Operation"), upper_elem ) attribute_map = { OGCOperationEnum.GET_CAPABILITIES.value: 'get_capabilities_uri', OGCOperationEnum.DESCRIBE_RECORD.value: 'describe_record_uri', OGCOperationEnum.GET_RECORDS.value: 'get_records_uri', OGCOperationEnum.GET_RECORD_BY_ID.value: 'get_record_by_id_uri', } for operation in operations_objs: operation_name = xml_helper.try_get_attribute_from_xml_element( operation, "name", ) get_uri = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation ) get_uri = xml_helper.get_href_attribute(get_uri) if get_uri is not None else None post_uri = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation ) post_uri = xml_helper.get_href_attribute(post_uri) if post_uri is not None else None if attribute_map.get(operation_name): setattr(self, attribute_map.get(operation_name)+'_GET', get_uri) setattr(self, attribute_map.get(operation_name)+'_POST', post_uri) else: # the given operation is not supported for now pass parameters = self._parse_parameter_metadata(operation) output_format = parameters.get("outputFormat", None) if output_format is not None: self.formats_list.append( MimeType.objects.get_or_create( operation=operation_name, mime_type=output_format, )[0] )
def _get_axis_order(self, identifier: str): """ Returns the axis order for a given spatial result system Args: identifier: Returns: """ id = self.get_real_identifier(identifier) axis_order = self.cacher.get(str(id)) if axis_order is not None: axis_order = json.loads(axis_order) return axis_order XML_NAMESPACES["gml"] = "http://www.opengis.net/gml/3.2" uri = self.registry_uri + self.id_prefix + str(id) response = requests.request("Get", url=uri, proxies=PROXIES) response = xml_helper.parse_xml(str(response.content.decode())) type = xml_helper.try_get_text_from_xml_element(xml_elem=response, elem="//epsg:type") if type == "projected": cartes_elem = xml_helper.try_get_single_element_from_xml( "//gml:cartesianCS", response) second_level_srs_uri = xml_helper.get_href_attribute( xml_elem=cartes_elem) elif type == "geographic 2D": geogr_elem = xml_helper.try_get_single_element_from_xml( "//gml:ellipsoidalCS", response) second_level_srs_uri = xml_helper.get_href_attribute( xml_elem=geogr_elem) else: second_level_srs_uri = "" uri = self.registry_uri + second_level_srs_uri response = requests.request("Get", url=uri, proxies=PROXIES) response = xml_helper.parse_xml(str(response.content.decode())) axis = xml_helper.try_get_element_from_xml("//gml:axisDirection", response) order = [] for a in axis: order.append(a.text) order = { "first_axis": order[0], "second_axis": order[1], } # Write this to cache, so it can be used on another request! self.cacher.set(str(id), json.dumps(order)) return order
def _get_axis_order(self, identifier: str): """ Returns the axis order for a given spatial result system Args: identifier: Returns: """ id = self.get_real_identifier(identifier) axis_order = self.cacher.get(str(id)) if axis_order is not None: axis_order = json.loads(axis_order) return axis_order XML_NAMESPACES["gml"] = "http://www.opengis.net/gml/3.2" XML_NAMESPACES["epsg"] = "urn:x-ogp:spec:schema-xsd:EPSG:2.2:dataset" uri = self.registry_uri.replace("{CRS_IDENTIFIER}", str(id)) # change header headers = {'Accept': 'application/xml'} response = requests.request("Get", url=uri, proxies=PROXIES, headers=headers) response = xml_helper.parse_xml(str(response.content.decode())) type = xml_helper.try_get_text_from_xml_element(xml_elem=response, elem="//epsg:type") if type == "projected": cartes_elem = xml_helper.try_get_single_element_from_xml("//gml:cartesianCS", response) second_level_srs_uri = xml_helper.get_href_attribute(xml_elem=cartes_elem) elif type in ["geographic 2D", "geographic 2d"]: geogr_elem = xml_helper.try_get_single_element_from_xml("//gml:ellipsoidalCS", response) second_level_srs_uri = xml_helper.get_href_attribute(xml_elem=geogr_elem) else: second_level_srs_uri = "" uri = second_level_srs_uri headers = {'Accept': 'application/xml'} response = requests.request("Get", url=uri, proxies=PROXIES, headers=headers) response = xml_helper.parse_xml(str(response.content.decode())) axis = xml_helper.try_get_element_from_xml("//gml:axisDirection", response) order = [] for a in axis: order.append(a.text) order = { "first_axis": order[0], "second_axis": order[1], } # Write this to cache, so it can be used on another request! self.cacher.set(str(id), json.dumps(order)) return order
def parse_style(self, layer, layer_obj): style_xml = xml_helper.try_get_single_element_from_xml( "./" + GENERIC_NAMESPACE_TEMPLATE.format("Style"), layer) if style_xml is None: # no <Style> element found return style_obj = Style() style_obj.name = xml_helper.try_get_text_from_xml_element( style_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Name")) style_obj.title = xml_helper.try_get_text_from_xml_element( style_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Title")) legend_elem = xml_helper.try_get_single_element_from_xml( elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), xml_elem=style_xml) style_obj.legend_uri = xml_helper.get_href_attribute(legend_elem) style_obj.width = int( xml_helper.try_get_attribute_from_xml_element( style_xml, "width", "./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL")) or 0) style_obj.height = int( xml_helper.try_get_attribute_from_xml_element( style_xml, "height", "./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL")) or 0) style_obj.mime_type = MimeType.objects.filter( mime_type=xml_helper.try_get_text_from_xml_element( style_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("LegendURL") + "/ " + GENERIC_NAMESPACE_TEMPLATE.format("Format"))).first() layer_obj.style = style_obj
def parse_request_uris(self, layer, layer_obj): suffix_get = GENERIC_NAMESPACE_TEMPLATE.format("DCPType") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("HTTP") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("Get") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource") suffix_post = GENERIC_NAMESPACE_TEMPLATE.format("DCPType") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("HTTP") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("Post") + \ "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource") # shortens the usage of our constant values get_cap = OGCOperationEnum.GET_CAPABILITIES.value get_map = OGCOperationEnum.GET_MAP.value get_feat = OGCOperationEnum.GET_FEATURE_INFO.value descr_lay = OGCOperationEnum.DESCRIBE_LAYER.value get_leg = OGCOperationEnum.GET_LEGEND_GRAPHIC.value get_sty = OGCOperationEnum.GET_STYLES.value attributes = { "cap_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_cap) + "/" + suffix_get, "cap_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_cap) + "/" + suffix_post, "map_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_map) + "/" + suffix_get, "map_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_map) + "/" + suffix_post, "feat_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_feat) + "/" + suffix_get, "feat_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_feat) + "/" + suffix_post, "desc_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(descr_lay) + "/" + suffix_get, "desc_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(descr_lay) + "/" + suffix_post, "leg_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_leg) + "/" + suffix_get, "leg_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_leg) + "/" + suffix_post, "style_GET": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_sty) + "/" + suffix_get, "style_POST": "//" + GENERIC_NAMESPACE_TEMPLATE.format(get_sty) + "/" + suffix_post, } for key, val in attributes.items(): try: tmp = layer.xpath(val)[0] link = xml_helper.get_href_attribute(tmp) attributes[key] = link except (AttributeError, IndexError) as error: attributes[key] = None layer_obj.get_capabilities_uri_GET = attributes.get("cap_GET") layer_obj.get_capabilities_uri_POST = attributes.get("cap_POST") layer_obj.get_map_uri_GET = attributes.get("map_GET") layer_obj.get_map_uri_POST = attributes.get("map_POST") layer_obj.get_feature_info_uri_GET = attributes.get("feat_GET") layer_obj.get_feature_info_uri_POST = attributes.get("feat_POST") layer_obj.describe_layer_uri_GET = attributes.get("desc_GET") layer_obj.describe_layer_uri_POST = attributes.get("desc_POST") layer_obj.get_legend_graphic_uri_GET = attributes.get("leg_GET") layer_obj.get_legend_graphic_uri_POST = attributes.get("leg_POST") layer_obj.get_styles_uri_GET = attributes.get("style_GET") layer_obj.get_styles_uri_POST = attributes.get("style_POST")
def parse_dataset_md(self, layer, layer_obj): # check for possible dataset metadata if self.has_dataset_metadata(layer): iso_metadata_xml_elements = xml_helper.try_get_element_from_xml( xml_elem=layer, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("MetadataURL") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource") ) for iso_xml in iso_metadata_xml_elements: iso_uri = xml_helper.get_href_attribute(xml_elem=iso_xml) try: iso_metadata = ISOMetadata(uri=iso_uri, origin=ResourceOriginEnum.CAPABILITIES.value) except Exception as e: # there are iso metadatas that have been filled wrongly -> if so we will drop them continue layer_obj.iso_metadata.append(iso_metadata)
def get_service_metadata_from_capabilities(self, xml_obj): """ Parses all <Service> element information which can be found in every wms specification since 1.0.0 Args: xml_obj: The iterable xml object tree Returns: Nothing """ service_xml = xml_helper.try_get_single_element_from_xml( "//" + GENERIC_NAMESPACE_TEMPLATE.format("Service"), xml_obj) self.service_file_identifier = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Name")) self.service_identification_abstract = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Abstract")) self.service_identification_title = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Title")) if current_task: current_task.update_state(state=states.STARTED, meta={ 'service': self.service_identification_title, 'phase': "Parsing main capabilities", }) self.service_identification_fees = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("Fees")) self.service_identification_accessconstraints = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("AccessConstraints")) self.service_provider_providername = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactPersonPrimary") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactOrganization")) authority_elem = xml_helper.try_get_single_element_from_xml( elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("AuthorityURL"), xml_elem=xml_obj) self.service_provider_url = xml_helper.get_href_attribute( authority_elem) self.service_provider_contact_contactinstructions = xml_helper.try_get_text_from_xml_element( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation")) self.service_provider_responsibleparty_individualname = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactPersonPrimary") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactPerson")) self.service_provider_responsibleparty_positionname = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactPersonPrimary") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactPosition")) self.service_provider_telephone_voice = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactVoiceTelephone")) self.service_provider_telephone_facsimile = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactFacsimileTelephone")) self.service_provider_address_electronicmailaddress = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactElectronicMailAddress")) keywords = xml_helper.try_get_element_from_xml( "./" + GENERIC_NAMESPACE_TEMPLATE.format("KeywordList") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("Keyword"), service_xml) kw = [] for keyword in keywords: if keyword is None: continue kw.append(keyword.text) self.service_identification_keywords = kw online_res_elem = xml_helper.try_get_single_element_from_xml( "//" + GENERIC_NAMESPACE_TEMPLATE.format("Service") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), xml_obj) link = xml_helper.get_href_attribute(online_res_elem) self.service_provider_onlineresource_linkage = link self.service_provider_address_country = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactAddress") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("Country")) self.service_provider_address_postalcode = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactAddress") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("PostCode")) self.service_provider_address_city = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactAddress") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("City")) self.service_provider_address_state_or_province = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactAddress") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("StateOrProvince")) self.service_provider_address = xml_helper.try_get_text_from_xml_element( service_xml, "./" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInformation") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("ContactAddress") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("Address")) # parse request uris from capabilities document self.parse_request_uris(xml_obj, self)
def get_service_metadata_from_capabilities(self, xml_obj): """ Parse the capability document <Service> metadata into the self object Args: xml_obj: A minidom object which holds the xml content Returns: Nothing """ service_xml = xml_helper.try_get_single_element_from_xml( "//" + GENERIC_NAMESPACE_TEMPLATE.format("ServiceIdentification"), xml_obj ) self.service_identification_title = xml_helper.try_get_text_from_xml_element( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Title") ) if current_task: current_task.update_state( state=states.STARTED, meta={'service': self.service_identification_title, 'phase': 'Parsing main capabilities'} ) self.service_identification_abstract = xml_helper.try_get_text_from_xml_element( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Abstract") ) self.service_identification_fees = xml_helper.try_get_text_from_xml_element( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Fees") ) self.service_identification_accessconstraints = xml_helper.try_get_text_from_xml_element( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("AccessConstraints") ) keywords = xml_helper.try_get_element_from_xml( xml_elem=service_xml, elem="./" + GENERIC_NAMESPACE_TEMPLATE.format("Keywords") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("Keyword") ) kw = [] for keyword in keywords: text = keyword.text if text is None: continue try: kw.append(text) except AttributeError: pass self.service_identification_keywords = kw self.service_provider_providername = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("ProviderName") ) provider_site_elem = xml_helper.try_get_single_element_from_xml( "//" + GENERIC_NAMESPACE_TEMPLATE.format("ProviderSite"), xml_obj ) self.service_provider_url = xml_helper.get_href_attribute(xml_elem=provider_site_elem) self.service_provider_responsibleparty_individualname = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("IndividualName") ) self.service_provider_responsibleparty_positionname = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("PositionName") ) self.service_provider_telephone_voice = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Voice") ) self.service_provider_telephone_facsimile = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Facsimile") ) self.service_provider_address = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("DeliveryPoint") ) self.service_provider_address_city = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("City") ) self.service_provider_address_state_or_province = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("AdministrativeArea") ) self.service_provider_address_postalcode = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("PostalCode") ) self.service_provider_address_country = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Country") ) self.service_provider_address_electronicmailaddress = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("ElectronicMailAddress") ) online_resource_elem = xml_helper.try_get_single_element_from_xml( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource") ) self.service_provider_onlineresource_linkage = xml_helper.get_href_attribute(online_resource_elem) if self.service_provider_onlineresource_linkage is None or self.service_provider_onlineresource_linkage == "": # There are metadatas where no online resource link is given. We need to generate it manually therefore... self.service_provider_onlineresource_linkage = service_helper.split_service_uri(self.service_connect_url).get("base_uri") self.service_provider_onlineresource_linkage = service_helper.prepare_original_uri_stump(self.service_provider_onlineresource_linkage) self.service_provider_contact_hoursofservice = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("HoursOfService") ) self.service_provider_contact_contactinstructions = xml_helper.try_get_text_from_xml_element( xml_elem=xml_obj, elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("ContactInstructions") )
def _parse_operations_metadata(self, upper_elem): """ Parses the <Operation> elements inside of <OperationsMetadata> Args: upper_elem (Element): The upper xml element Returns: """ operations_objs = xml_helper.try_get_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Operation"), upper_elem) attribute_map = { OGCOperationEnum.GET_CAPABILITIES.value: 'get_capabilities_uri', OGCOperationEnum.DESCRIBE_RECORD.value: 'describe_record_uri', OGCOperationEnum.GET_RECORDS.value: 'get_records_uri', OGCOperationEnum.GET_RECORD_BY_ID.value: 'get_record_by_id_uri', } for operation in operations_objs: operation_name = xml_helper.try_get_attribute_from_xml_element( operation, "name", ) get_uri = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation) csw_logger.error("Type of returned object of get_uri: {}".format( type(get_uri))) get_uri = xml_helper.get_href_attribute( get_uri) if get_uri is not None else None post_uris = xml_helper.try_get_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation) number_of_post_endpoints = post_uris.__len__() if (number_of_post_endpoints > 1): post_uri = xml_helper.try_get_single_element_from_xml( ".//*[local-name()='Post'][.//ows:Constraint/ows:Value='XML']", operation) else: post_uri = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation) csw_logger.error( "Number of Entries of Post endpoints: {} for operation {}". format(number_of_post_endpoints, operation_name)) csw_logger.error("Type of returned object of post_uri: {}".format( type(post_uri))) post_uri = xml_helper.get_href_attribute( post_uri) if post_uri is not None else None if attribute_map.get(operation_name): setattr(self, attribute_map.get(operation_name) + '_GET', get_uri) setattr(self, attribute_map.get(operation_name) + '_POST', post_uri) else: # the given operation is not supported for now pass parameters = self._parse_parameter_metadata(operation) output_format = parameters.get("outputFormat", None) if output_format is not None: self.formats_list.append( MimeType.objects.get_or_create( operation=operation_name, mime_type=output_format, )[0])
def test_proxy_setting(self): return """ Tests whether the proxy can be set properly. Returns: """ metadata = self.service_wms.metadata # To avoid running celery in a separate test instance, we do not call the route. Instead we call the logic, which # is used to process access settings directly. async_process_securing_access( metadata.id, use_proxy=True, log_proxy=True, restrict_access=False, ) self.cap_doc_wms.refresh_from_db() doc_unsecured = self.cap_doc_wms.content doc_secured = Document.objects.get( metadata=metadata, document_type=DocumentEnum.CAPABILITY.value, is_original=False, ).content # Check for all operations if the uris has been changed! # Do not check for GetCapabilities, since we always change this uri during registration! # Make sure all versions can be matched by the code - the xml structure differs a lot from version to version service_version = metadata.get_service_version() if metadata.is_service_type(OGCServiceEnum.WMS): operations = [ OGCOperationEnum.GET_MAP.value, OGCOperationEnum.GET_FEATURE_INFO.value, OGCOperationEnum.DESCRIBE_LAYER.value, OGCOperationEnum.GET_LEGEND_GRAPHIC.value, OGCOperationEnum.GET_STYLES.value, OGCOperationEnum.PUT_STYLES.value, ] elif metadata.is_service_type(OGCServiceEnum.WFS): operations = [ OGCOperationEnum.GET_FEATURE.value, OGCOperationEnum.TRANSACTION.value, OGCOperationEnum.LOCK_FEATURE.value, OGCOperationEnum.DESCRIBE_FEATURE_TYPE.value, ] else: operations = [] # create xml documents from string documents and fetch only the relevant <Request> element for each xml_unsecured = xml_helper.parse_xml(doc_unsecured) request_unsecured = xml_helper.try_get_single_element_from_xml(elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Request"), xml_elem=xml_unsecured) xml_secured = xml_helper.parse_xml(doc_secured) request_secured = xml_helper.try_get_single_element_from_xml(elem="//" + GENERIC_NAMESPACE_TEMPLATE.format("Request"), xml_elem=xml_secured) for operation in operations: # Get <OPERATION> element operation_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format(operation), request_unsecured) operation_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format(operation), request_secured) if service_version == OGCServiceVersionEnum.V_1_0_0: if metadata.is_service_type(OGCServiceEnum.WMS): # The WMS 1.0.0 specification uses <OPERATION> instead of <GetOPERATION> for any operation element. operation = operation.replace("Get", "") # Get <OPERATION> element again operation_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format(operation), request_unsecured) operation_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format(operation), request_secured) # Version 1.0.0 holds the uris in the "onlineResource" attribute of <Get> and <Post> get_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation_unsecured) get_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation_secured) post_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation_unsecured) post_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation_secured) online_res = "onlineResource" get_unsecured = xml_helper.try_get_attribute_from_xml_element(get_unsecured, online_res) get_secured = xml_helper.try_get_attribute_from_xml_element(get_secured, online_res) post_unsecured = xml_helper.try_get_attribute_from_xml_element(post_unsecured, online_res) post_secured = xml_helper.try_get_attribute_from_xml_element(post_secured, online_res) # Assert that all get/post elements are not None self.assertIsNotNone(get_secured, msg="The secured uri of '{}' is None!".format(operation)) self.assertIsNotNone(post_secured, msg="The secured uri of '{}' is None!".format(operation)) # Assert that the secured version is different from the unsecured one self.assertNotEqual(get_unsecured, get_secured, msg="The uri of '{}' has not been secured!".format(operation)) self.assertNotEqual(post_unsecured, post_secured, msg="The uri of '{}' has not been secured!".format(operation)) # Assert that the HOST_NAME constant appears in the secured uri self.assertContains(get_secured, HOST_NAME) self.assertContains(post_secured, HOST_NAME) elif service_version == OGCServiceVersionEnum.V_1_1_0 \ or service_version == OGCServiceVersionEnum.V_2_0_0 \ or service_version == OGCServiceVersionEnum.V_2_0_2: # Only WFS # Get <OPERATION> element again, since the operation is now identified using an attribute, not an element tag operation_unsecured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Operation") + "[@name='" + operation + "']", request_unsecured ) operation_secured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Operation") + "[@name='" + operation + "']", request_secured ) # Version 1.1.0 holds the uris in the href attribute of <Get> and <Post> get_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation_unsecured) get_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get"), operation_secured) post_unsecured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation_unsecured) post_secured = xml_helper.try_get_single_element_from_xml(".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post"), operation_secured) get_unsecured = xml_helper.get_href_attribute(get_unsecured) get_secured = xml_helper.get_href_attribute(get_secured) post_unsecured = xml_helper.get_href_attribute(post_unsecured) post_secured = xml_helper.get_href_attribute(post_secured) # Assert that all get/post elements are not None self.assertIsNotNone(get_secured, msg="The secured uri of '{}' is None!".format(operation)) self.assertIsNotNone(post_secured, msg="The secured uri of '{}' is None!".format(operation)) # Assert that the secured version is different from the unsecured one self.assertNotEqual(get_unsecured, get_secured, msg="The uri of '{}' has not been secured!".format(operation)) self.assertNotEqual(post_unsecured, post_secured, msg="The uri of '{}' has not been secured!".format(operation)) # Assert that the HOST_NAME constant appears in the secured uri self.assertContains(get_secured, HOST_NAME) self.assertContains(post_secured, HOST_NAME) elif service_version == OGCServiceVersionEnum.V_1_1_1 or service_version == OGCServiceVersionEnum.V_1_3_0: # Version 1.1.1 holds the uris in the <OnlineResource> element inside <Get> and <Post> get_unsecured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), operation_unsecured ) get_secured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Get") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), operation_secured ) post_unsecured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), operation_unsecured ) post_secured = xml_helper.try_get_single_element_from_xml( ".//" + GENERIC_NAMESPACE_TEMPLATE.format("Post") + "/" + GENERIC_NAMESPACE_TEMPLATE.format("OnlineResource"), operation_secured ) get_unsecured = xml_helper.get_href_attribute(get_unsecured) get_secured = xml_helper.get_href_attribute(get_secured) post_unsecured = xml_helper.get_href_attribute(post_unsecured) post_secured = xml_helper.get_href_attribute(post_secured) # Assert that both (secure/unsecure) uris are None or none of them # This is possible for operations that are not supported by the service if get_secured is not None and get_unsecured is not None: self.assertIsNotNone(get_secured, msg="The secured uri of '{}' is None!".format(operation)) # Assert that the secured version is different from the unsecured one self.assertNotEqual(get_unsecured, get_secured, msg="The uri of '{}' has not been secured!".format(operation)) # Assert that the HOST_NAME constant appears in the secured uri self.assertTrue(HOST_NAME in get_secured) if post_secured is not None and post_unsecured is not None: self.assertIsNotNone(post_secured, msg="The secured uri of '{}' is None!".format(operation)) self.assertNotEqual(post_unsecured, post_secured, msg="The uri of '{}' has not been secured!".format(operation)) self.assertTrue(HOST_NAME in post_secured) else: pass