Exemplo n.º 1
0
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()
Exemplo n.º 2
0
    def test_protected_layers3(self):
        from c2cgeoportal_geoportal.lib.layers import get_protected_layers

        pl = get_protected_layers(self.role3_id, [self.ogc_server_id])
        self.assertEqual(
            {pl[l].name
             for l in pl},
            {"testpoint_protected", "testpoint_protected_query_with_collect"})
    def test_protected_layers3(self):
        from c2cgeoportal_geoportal.lib.layers import get_protected_layers

        pl = get_protected_layers(self._create_dummy_request("__test_user3"),
                                  [self.ogc_server_id])
        self.assertEqual(
            {pl[l].name
             for l in pl},
            {"testpoint_protected", "testpoint_protected_query_with_collect"})
    def test_protected_layers3(self):
        from c2cgeoportal_commons.models import DBSession, static
        from c2cgeoportal_geoportal.lib.layers import get_protected_layers

        pl = get_protected_layers(
            DBSession.query(static.User).get(self.user3_id),
            [self.ogc_server_id])
        self.assertEqual(
            {pl[l].name
             for l in pl},
            {"testpoint_protected", "testpoint_protected_query_with_collect"})
Exemplo n.º 5
0
    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)
Exemplo n.º 6
0
        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
Exemplo n.º 7
0
        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