def filter_capabilities(content, wms, url, headers, request): wms_structure_ = wms_structure(url, headers.get("Host"), request) ogc_server_ids = (get_ogc_server_wms_url_ids(request) if wms else get_ogc_server_wfs_url_ids(request)).get(url) gmf_private_layers = copy.copy(get_private_layers(ogc_server_ids)) for id_ in list(get_protected_layers(request, ogc_server_ids).keys()): if id_ in gmf_private_layers: del gmf_private_layers[id_] private_layers = set() for gmflayer in list(gmf_private_layers.values()): for ogclayer in gmflayer.layer.split(","): private_layers.add(ogclayer) if ogclayer in wms_structure_: private_layers.update(wms_structure_[ogclayer]) parser = defusedxml.expatreader.create_parser(forbid_external=False) # skip inclusion of DTDs parser.setFeature(xml.sax.handler.feature_external_ges, False) parser.setFeature(xml.sax.handler.feature_external_pes, False) result = StringIO() downstream_handler = XMLGenerator(result, "utf-8") filter_handler = _CapabilitiesFilter(parser, downstream_handler, "Layer" if wms else "FeatureType", layers_blacklist=private_layers) filter_handler.parse(StringIO(content)) return result.getvalue()
def test_private_layer(self): from c2cgeoportal_geoportal.lib.layers import get_private_layers pl = get_private_layers([self.ogc_server_id]) self.assertEqual( {pl[l].name for l in pl}, {"testpoint_protected", "testpoint_protected_query_with_collect"})
def get_report(self) -> pyramid.response.Response: self.layername = self.request.matchdict["layername"] layer_config = self.config["layers"].get(self.layername) multiple = layer_config.get("multiple", False) ids = self.request.matchdict["ids"] if multiple: ids = ids.split(",") if layer_config is None: raise HTTPBadRequest("Layer not found") features_ids = ([self.layername + "." + id_ for id_ in ids] if multiple else [self.layername + "." + ids]) if layer_config["check_credentials"]: # FIXME: support of mapserver groups ogc_server = (models.DBSession.query(main.OGCServer).filter( main.OGCServer.name == layer_config["ogc_server"]).one()) ogc_server_ids = [ogc_server] private_layers_object = get_private_layers(ogc_server_ids) private_layers_names = [ private_layers_object[oid].name for oid in private_layers_object ] protected_layers_object = get_protected_layers( self.request.user, ogc_server_ids) protected_layers_names = [ protected_layers_object[oid].name for oid in protected_layers_object ] if self.layername in private_layers_names and self.layername not in protected_layers_names: raise HTTPForbidden srs = layer_config["srs"] mapserv_url = self.request.route_url( "mapserverproxy", _query={"ogcserver": layer_config["ogc_server"]}) url = Url(mapserv_url) url.add_query({ "service": "WFS", "version": "1.1.0", "outputformat": "gml3", "request": "GetFeature", "typeName": self.layername, "featureid": ",".join(features_ids), "srsName": srs, }) vector_request_url = url.url() spec = layer_config["spec"] if spec is None: spec = { "layout": self.layername, "outputFormat": "pdf", "attributes": { "ids": [{ "id": id_ } for id_ in ids] } if multiple else { "id": id }, } map_config = layer_config.get("map") if map_config is not None: spec["attributes"]["map"] = self._build_map( mapserv_url, vector_request_url, srs, map_config) maps_config = layer_config.get("maps") if maps_config is not None: spec["attributes"]["maps"] = [] for map_config in maps_config: spec["attributes"]["maps"].append( self._build_map(mapserv_url, vector_request_url, srs, map_config)) else: datasource = layer_config.get("datasource", True) if multiple and datasource: data = dumps(layer_config["data"]) data_list = [ loads( data % { "layername": self.layername, "id": id_, "srs": srs, "mapserv_url": mapserv_url, "vector_request_url": vector_request_url, }) for id_ in ids ] self.walker(spec, "%(datasource)s", data_list) spec = loads( dumps(spec) % { "layername": self.layername, "srs": srs, "mapserv_url": mapserv_url, "vector_request_url": vector_request_url, }) elif multiple: spec = loads( dumps(spec) % { "layername": self.layername, "ids": ",".join(ids), "srs": srs, "mapserv_url": mapserv_url, "vector_request_url": vector_request_url, }) else: spec = loads( dumps(spec) % { "layername": self.layername, "id": ids, "srs": srs, "mapserv_url": mapserv_url, "vector_request_url": vector_request_url, }) return self._do_print(spec)
async def get_theme() -> Dict[str, Union[Dict[str, Any], List[str]]]: export_themes = sets in ("all", "themes") export_group = group is not None and sets in ("all", "group") export_background = background_layers_group is not None and sets in ("all", "background") result: Dict[str, Union[Dict[str, Any], List[Any]]] = {} all_errors: Set[str] = set() LOG.debug("Start preload") start_time = time.time() await self.preload(all_errors) LOG.debug("End preload") # Don't log if it looks to be already preloaded. if (time.time() - start_time) > 1: LOG.info("Do preload in %.3fs.", time.time() - start_time) result["ogcServers"] = {} for ogc_server in models.DBSession.query(main.OGCServer).all(): nb_layers = ( models.DBSession.query(sqlalchemy.func.count(main.LayerWMS.id)) .filter(main.LayerWMS.ogc_server_id == ogc_server.id) .one() ) if nb_layers[0] == 0: # QGIS Server langing page requires an OGC server that can't be used here. continue url_internal_wfs, url, url_wfs = self.get_url_internal_wfs(ogc_server, all_errors) attributes = None namespace = None if ogc_server.wfs_support: assert url_internal_wfs attributes, namespace, errors = await self._get_features_attributes( url_internal_wfs, ogc_server.name ) # Create a local copy (don't modify the cache) if attributes is not None: attributes = dict(attributes) all_errors |= errors all_private_layers = get_private_layers([ogc_server.id]).values() protected_layers_name = [ layer.name for layer in get_protected_layers(self.request, [ogc_server.id]).values() ] private_layers_name: List[str] = [] for layers in [ v.layer for v in all_private_layers if v.name not in protected_layers_name ]: private_layers_name.extend(layers.split(",")) if attributes is not None: for name in private_layers_name: if name in attributes: del attributes[name] result["ogcServers"][ogc_server.name] = { "url": url.url() if url else None, "urlWfs": url_wfs.url() if url_wfs else None, "type": ogc_server.type, "credential": ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH, "imageType": ogc_server.image_type, "wfsSupport": ogc_server.wfs_support, "isSingleTile": ogc_server.is_single_tile, "namespace": namespace, "attributes": attributes, } if export_themes: themes, errors = await self._themes(interface, True, min_levels) result["themes"] = themes all_errors |= errors if export_group: exported_group, errors = await self._get_group(group, interface) if exported_group is not None: result["group"] = exported_group all_errors |= errors if export_background: exported_group, errors = await self._get_group(background_layers_group, interface) result["background_layers"] = exported_group["children"] if exported_group is not None else [] all_errors |= errors result["errors"] = list(all_errors) if all_errors: LOG.info("Theme errors:\n%s", "\n".join(all_errors)) return result
def get_theme(): export_themes = sets in ("all", "themes") export_group = group is not None and sets in ("all", "group") export_background = background_layers_group is not None and sets in ( "all", "background") result: Dict[str, Union[Dict[str, Dict[str, Any]], List[str]]] = {} all_errors: Set[str] = set() LOG.debug("Start preload") start_time = time.time() asyncio.run(self.preload(all_errors)) LOG.debug("End preload") LOG.info("Do preload in %.3fs.", time.time() - start_time) result["ogcServers"] = {} for ogc_server in models.DBSession.query(main.OGCServer).all(): url_internal_wfs, url, url_wfs = self.get_url_internal_wfs( ogc_server, all_errors) attributes = None namespace = None if ogc_server.wfs_support: attributes, namespace, errors = self._get_features_attributes( url_internal_wfs) all_errors |= errors all_private_layers = get_private_layers([ogc_server.id ]).values() protected_layers_name = [ l.name for l in get_protected_layers( self.request, [ogc_server.id]).values() ] private_layers_name: List[str] = [] for layers in [ v.layer for v in all_private_layers if v.name not in protected_layers_name ]: private_layers_name.extend(layers.split(",")) if attributes is not None: for name in private_layers_name: if name in attributes: del attributes[name] result["ogcServers"][ogc_server.name] = { "url": url, "urlWfs": url_wfs, "type": ogc_server.type, "credential": ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH, "imageType": ogc_server.image_type, "wfsSupport": ogc_server.wfs_support, "isSingleTile": ogc_server.is_single_tile, "namespace": namespace, "attributes": attributes, } if export_themes: themes, errors = self._themes(interface, True, min_levels) result["themes"] = themes all_errors |= errors if export_group: exported_group, errors = self._get_group(group, interface) if exported_group is not None: result["group"] = exported_group all_errors |= errors if export_background: exported_group, errors = self._get_group( background_layers_group, interface) result["background_layers"] = exported_group[ "children"] if exported_group is not None else [] all_errors |= errors result["errors"] = list(all_errors) if all_errors: LOG.info("Theme errors:\n%s", "\n".join(all_errors)) return result