Esempio n. 1
0
    def test_url_update(self):
        url = Url("http://test:123/toto?map=123#456")
        url.hostname = "example"
        assert url.netloc == "example:123"
        assert url.port == 123
        assert url.url() == "http://example:123/toto?map=123#456"

        url = Url("http://test:123/toto?map=123#456")
        url.netloc = "example"
        assert url.hostname == "example"
        assert url.port is None
        assert url.url() == "http://example/toto?map=123#456"

        url = Url("http://test:123/toto?map=123#456")
        url.netloc = "example:234"
        assert url.hostname == "example"
        assert url.port == 234
        assert url.url() == "http://example:234/toto?map=123#456"

        url = Url("http://test:123/toto?map=123#456")
        url.port = 345
        assert url.netloc == "test:345"
        assert url.hostname == "test"
        assert url.url() == "http://test:345/toto?map=123#456"

        url = Url("http://test:123/toto?map=123#456")
        url.port = None
        assert url.netloc == "test"
        assert url.hostname == "test"
        assert url.url() == "http://test/toto?map=123#456"
Esempio n. 2
0
 def status(self) -> pyramid.response.Response:
     """ PDF status. """
     return self._proxy_response(
         "print",
         Url("{}/status/{}.json".format(self.config["print_url"],
                                        self.request.matchdict.get("ref"))),
     )
Esempio n. 3
0
 def get_url_internal_wfs(
     self, ogc_server: main.OGCServer, errors: Set[str]
 ) -> Tuple[Optional[Url], Optional[Url], Optional[Url]]:
     # required to do every time to validate the url.
     if ogc_server.auth != main.OGCSERVER_AUTH_NOAUTH:
         url: Optional[Url] = Url(
             self.request.route_url("mapserverproxy", _query={"ogcserver": ogc_server.name})
         )
         url_wfs: Optional[Url] = url
         url_internal_wfs = get_url2(
             f"The OGC server (WFS) '{ogc_server.name}'",
             ogc_server.url_wfs or ogc_server.url,
             self.request,
             errors=errors,
         )
     else:
         url = get_url2(f"The OGC server '{ogc_server.name}'", ogc_server.url, self.request, errors=errors)
         url_wfs = (
             get_url2(
                 f"The OGC server (WFS) '{ogc_server.name}'",
                 ogc_server.url_wfs,
                 self.request,
                 errors=errors,
             )
             if ogc_server.url_wfs is not None
             else url
         )
         url_internal_wfs = url_wfs
     return url_internal_wfs, url, url_wfs
Esempio n. 4
0
 def report_get(self) -> pyramid.response.Response:
     """ Get the PDF. """
     url = Url("{0!s}/report/{1!s}".format(
         self.config["print_url"], self.request.matchdict.get("ref")))
     if self.config.get("print_get_redirect", False):
         raise HTTPFound(location=url.url())
     return self._proxy_response("print", url)
Esempio n. 5
0
 def status(self) -> pyramid.response.Response:
     """PDF status."""
     return self._proxy_response(
         "print",
         Url(f"{self.request.get_organization_print_url()}/status/{self.request.matchdict.get('ref')}.json"
             ),
     )
Esempio n. 6
0
    def _capabilities(self, templates: List[str], query_string: Dict[str, str],
                      method: str,
                      referrer: str) -> Tuple[requests.Response, str]:
        del query_string  # Just for caching
        del method  # Just for caching
        del referrer  # Just for caching
        # get URL
        _url = self.request.get_organization_print_url() + "/capabilities.json"

        response = self._proxy(Url(_url))
        response.raise_for_status()

        if self.request.method == "GET":
            try:
                capabilities = response.json()
            except json.decoder.JSONDecodeError:
                LOG.exception("Unable to parse capabilities: %s",
                              response.text)
                raise HTTPBadGateway(response.text)  # pylint: disable=raise-missing-from

            capabilities["layouts"] = list(
                layout for layout in capabilities["layouts"]
                if layout["name"] in templates)

            pretty = self.request.params.get("pretty", "false") == "true"
            content = json.dumps(capabilities,
                                 separators=None if pretty else (",", ":"),
                                 indent=4 if pretty else None)
        else:
            content = ""

        return response, content
Esempio n. 7
0
 def dev(self) -> pyramid.response.Response:
     path = self.THEME_RE.sub("", self.request.path_info)
     if self.request.path.endswith("/dynamic.js"):
         return HTTPFound(location=self.request.route_url(
             "dynamic", _query=self.request.params))
     return self._proxy_response(
         "dev", Url(f"{self.dev_url.rstrip('/')}/{path.lstrip('/')}"))
Esempio n. 8
0
 def cancel(self) -> pyramid.response.Response:
     """PDF cancel."""
     return self._proxy_response(
         "print",
         Url(f"{self.request.get_organization_print_url()}/cancel/{self.request.matchdict.get('ref')}"
             ),
     )
Esempio n. 9
0
 def report_create(self) -> pyramid.response.Response:
     """ Create PDF. """
     return self._proxy_response(
         "print",
         Url("{}/report.{}".format(self.config["print_url"],
                                   self.request.matchdict.get("format"))),
     )
Esempio n. 10
0
 def report_create(self) -> pyramid.response.Response:
     """Create PDF."""
     return self._proxy_response(
         "print",
         Url(f"{ self.request.get_organization_print_url()}/report.{self.request.matchdict.get('format')}"
             ),
     )
Esempio n. 11
0
 def test_url_encode3(self):
     url = Url("http://example.com/toto?%C3%A0=%C3%A9")
     url.add_query({"1": "2"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.netloc, "example.com")
     self.assertEqual(url.path, "/toto")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {"à": "é", "1": "2"})
Esempio n. 12
0
 def report_get(self) -> pyramid.response.Response:
     """Get the PDF."""
     url = Url(
         f"{self.request.get_organization_print_url()}/report/{self.request.matchdict.get('ref')}"
     )
     if self.request.registry.settings.get("print_get_redirect", False):
         raise HTTPFound(location=url.url())
     return self._proxy_response("print", url)
Esempio n. 13
0
 def test_url_port(self):
     url = Url("http://example.com:8480/toto")
     url.add_query({"1": "2"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.hostname, "example.com")
     self.assertEqual(url.netloc, "example.com:8480")
     self.assertEqual(url.path, "/toto")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {"1": "2"})
Esempio n. 14
0
 def test_url(self):
     url = Url("http://test/")
     url.add_query({"Name": "Bob", "Age": "18", "Nationality": "Việt Nam"})
     self.assertEqual(url.scheme, "http")
     self.assertEqual(url.netloc, "test")
     self.assertEqual(url.path, "/")
     self.assertEqual(url.fragment, "")
     self.assertEqual(url.query, {
         "Name": "Bob",
         "Age": "18",
         "Nationality": "Việt Nam"
     })
Esempio n. 15
0
    def _do_print(self, spec: Dict[str, Any]) -> pyramid.response.Response:
        """ Create and get report PDF. """

        headers = dict(self.request.headers)
        headers["Content-Type"] = "application/json"
        response = self._proxy(
            Url("{0!s}/buildreport.{1!s}".format(self.config["print_url"], spec["outputFormat"])),
            method="POST",
            body=dumps(spec).encode("utf-8"),
            headers=headers,
        )

        return self._build_response(response, response.content, Cache.NO, "pdfreport")
Esempio n. 16
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)
Esempio n. 17
0
 def test_url_noparam(self):
     url = Url("http://example.com/")
     url.add_query({})
     self.assertEqual(url.url(), "http://example.com/")
Esempio n. 18
0
 def cancel(self) -> pyramid.response.Response:
     """ PDF cancel. """
     return self._proxy_response(
         "print",
         Url("{}/cancel/{}".format(self.config["print_url"],
                                   self.request.matchdict.get("ref"))))
Esempio n. 19
0
 def _get_wfs_url(self, errors: Set[str]) -> Optional[Url]:
     return Url(self.settings.get("tinyows_url"))
Esempio n. 20
0
    def __init__(self, server_iface: qgis.server.QgsServerInterface):
        super().__init__(server_iface)

        self.server_iface = server_iface
        self.initialized = False

        try:
            config.init(
                os.environ.get("GEOMAPFISH_CONFIG",
                               "/etc/qgisserver/geomapfish.yaml"))

            c2cwsgiutils.broadcast.init()

            DBSession = create_session_factory(  # noqa: ignore=N806
                config.get("sqlalchemy_slave.url"),
                config.get_config().get("sqlalchemy", {}))

            if "GEOMAPFISH_OGCSERVER" in os.environ:
                self.single = True
                self.ogcserver_accesscontrol = OGCServerAccessControl(
                    server_iface,
                    os.environ["GEOMAPFISH_OGCSERVER"],
                    os.environ["QGIS_PROJECT_FILE"],
                    config.get("srid"),
                    DBSession,
                )

                LOG.info("Use OGC server named '%s'.",
                         os.environ["GEOMAPFISH_OGCSERVER"])
                self.initialized = True
            elif "GEOMAPFISH_ACCESSCONTROL_CONFIG" in os.environ:
                self.single = False
                self.ogcserver_accesscontrols = {}
                with open(os.environ["GEOMAPFISH_ACCESSCONTROL_CONFIG"],
                          encoding="utf-8") as ac_config_file:
                    ac_config = yaml.safe_load(ac_config_file.read())

                for map_, map_config in ac_config.get("map_config").items():
                    map_config["access_control"] = OGCServerAccessControl(
                        server_iface, map_config["ogc_server"], map_,
                        config.get("srid"), DBSession)
                    self.ogcserver_accesscontrols[map_] = map_config
                LOG.info("Use config '%s'.",
                         os.environ["GEOMAPFISH_ACCESSCONTROL_CONFIG"])
                self.initialized = True
            elif "GEOMAPFISH_ACCESSCONTROL_BASE_URL" in os.environ:
                self.ogcserver_accesscontrols = {}
                single_ogc_server = None
                base_url = Url(os.environ["GEOMAPFISH_ACCESSCONTROL_BASE_URL"])
                session = DBSession()
                try:
                    from c2cgeoportal_commons.models.main import (  # pylint: disable=import-outside-toplevel
                        OGCServer, )

                    for ogcserver in session.query(OGCServer).all():
                        errors: Set[str] = set()
                        url = get_url2(
                            f"The OGC server '{ogcserver.name}'",
                            ogcserver.url,
                            None,
                            errors,
                            config.get_config().get("servers", {}),
                        )

                        if errors:
                            LOG.warning(
                                "Ignoring OGC server '%s', get error on parsing URL:\n%s",
                                ogcserver.name,
                                "\n".join(errors),
                            )
                            continue
                        if url is None:
                            LOG.warning(
                                "Ignoring OGC server '%s', the URL is None",
                                ogcserver.name)
                            continue
                        if (base_url.scheme == url.scheme
                                and base_url.netloc == url.netloc
                                and base_url.path == url.path):
                            query = url.query_lower
                            if "map" not in query:
                                if single_ogc_server is None:
                                    single_ogc_server = ogcserver
                                    LOG.debug(
                                        "OGC server '%s', 'map' is not in the parameters => single server?",
                                        ogcserver.name,
                                    )
                                else:
                                    LOG.error(
                                        "OGC server '%s', 'map' is not in the parameters and we already have a single OCG server '%s'",
                                        ogcserver.name,
                                        single_ogc_server.name,
                                    )
                                continue

                            map_ = url.query_lower["map"]
                            self.ogcserver_accesscontrols[map_] = {
                                "ogcserver":
                                ogcserver.name,
                                "access_control":
                                OGCServerAccessControl(
                                    server_iface,
                                    ogcserver.name,
                                    map_,
                                    config.get("srid"),
                                    DBSession,
                                    ogcserver=ogcserver,
                                ),
                            }
                            LOG.info("OGC server '%s' registered for map",
                                     ogcserver.name)
                        else:
                            LOG.debug(
                                "Ignoring OGC server '%s', Don't match the base URL '%s' and '%s'",
                                ogcserver.name,
                                base_url,
                                url,
                            )
                    if self.ogcserver_accesscontrols and single_ogc_server is not None:
                        if os.environ.get("QGIS_PROJECT_FILE"):
                            LOG.error(
                                "We have OGC servers with and without parameter MAP and a value in QGIS_PROJECT_FILE, fallback to single OGC server mode."
                            )
                            self.ogcserver_accesscontrols = {}
                        else:
                            LOG.error(
                                "We have OGC servers with and without parameter MAP but no value in QGIS_PROJECT_FILE, fallback to multiple OGC server mode."
                            )
                            single_ogc_server = None
                    if single_ogc_server is not None:
                        self.single = True
                        self.ogcserver_accesscontrol = OGCServerAccessControl(
                            server_iface,
                            single_ogc_server.name,
                            os.environ["QGIS_PROJECT_FILE"],
                            config.get("srid"),
                            DBSession,
                            single_ogc_server,
                        )

                        LOG.info("Use OGC server named '%s'.",
                                 single_ogc_server.name)
                    else:
                        self.single = False
                    self.initialized = True
                finally:
                    session.close()
            else:
                LOG.error(
                    "The environment variable 'GEOMAPFISH_OGCSERVER', 'GEOMAPFISH_ACCESSCONTROL_CONFIG' "
                    "or 'GEOMAPFISH_ACCESSCONTROL_BASE_URL' should be defined.",
                )

        except Exception:  # pylint: disable=broad-except
            LOG.error("Cannot setup GeoMapFishAccessControl", exc_info=True)

        server_iface.registerAccessControl(
            self, int(os.environ.get("GEOMAPFISH_POSITION", 100)))