예제 #1
0
    def read_many(self):
        set_common_headers(self.request, "layers", NO_CACHE)

        features = []
        for layer in self._get_layers_for_request():
            for f in self._proto_read(layer).features:
                f.properties["__layer_id__"] = layer.id
                features.append(f)

        return FeatureCollection(features)
예제 #2
0
    def enumerate_attribute_values(self) -> Dict[str, Any]:
        set_common_headers(self.request, "layers", Cache.PUBLIC)

        if self.layers_enum_config is None:
            raise HTTPInternalServerError("Missing configuration")
        layername = self.request.matchdict["layer_name"]
        fieldname = self.request.matchdict["field_name"]
        # TODO check if layer is public or not

        return cast(Dict[str, Any],
                    self._enumerate_attribute_values(layername, fieldname))
예제 #3
0
    def loginform403(self) -> Dict[str, Any]:
        if self.request.authenticated_userid:
            raise HTTPUnauthorized()

        set_common_headers(self.request, "login", Cache.NO)

        return {
            "lang": self.lang,
            "came_from": self.request.path,
            "two_fa": self.two_factor_auth
        }
예제 #4
0
def locale(request):
    response = HTTPFound(
        request.static_url(
            '{package}_geoportal:static-ngeo/build/{lang}.json'.format(
                package=request.registry.settings["package"],
                lang=request.locale_name),
            _query={
                'cache': get_cache_version(),
            }))
    set_common_headers(request, 'api', NO_CACHE, response=response)
    return response
예제 #5
0
    def enumerate_attribute_values(self):
        set_common_headers(self.request, "layers", PUBLIC_CACHE)

        if self.layers_enum_config is None:  # pragma: no cover
            raise HTTPInternalServerError("Missing configuration")
        layername = self.request.matchdict["layer_name"]
        fieldname = self.request.matchdict["field_name"]
        # TODO check if layer is public or not

        return self._enumerate_attribute_values(
            layername, fieldname
        )
예제 #6
0
    def _do(method, headers, credentials=False, settings=SETTINGS):
        request = DummyRequest({}, method=method, headers=headers)
        if settings is not None:
            request.registry.settings = {"headers": {"foo": settings}}
        else:
            request.registry.settings = {"headers": {}}
        set_common_headers(request,
                           "foo",
                           Cache.PRIVATE_NO,
                           credentials=credentials)

        return dict(request.response.headers)
예제 #7
0
    def create(self):
        set_common_headers(self.request, "layers", NO_CACHE)

        if self.request.user is None:
            raise HTTPForbidden()

        self.request.response.cache_control.no_cache = True

        layer = self._get_layer_for_request()

        def check_geometry(_, feature, obj):
            del obj  # unused
            geom = feature.geometry
            if geom and not isinstance(geom, geojson.geometry.Default):
                shape = asShape(geom)
                srid = self._get_geom_col_info(layer)[1]
                spatial_elt = from_shape(shape, srid=srid)
                allowed = models.DBSession.query(func.count(
                    RestrictionArea.id))
                allowed = allowed.join(RestrictionArea.roles)
                allowed = allowed.join(RestrictionArea.layers)
                allowed = allowed.filter(RestrictionArea.readwrite.is_(True))
                allowed = allowed.filter(
                    Role.id.in_([r.id for r in self.request.user.roles]))
                allowed = allowed.filter(Layer.id == layer.id)
                allowed = allowed.filter(
                    or_(RestrictionArea.area.is_(None),
                        RestrictionArea.area.ST_Contains(spatial_elt)))
                if allowed.scalar() == 0:
                    raise HTTPForbidden()

                # check if geometry is valid
                if self._get_validation_setting(layer):
                    self._validate_geometry(spatial_elt)

        protocol = self._get_protocol_for_layer(layer,
                                                before_create=check_geometry)
        try:
            features = protocol.create(self.request)
            for feature in features.features:
                self._log_last_update(layer, feature)
            return features
        except TopologicalError as e:
            self.request.response.status_int = 400
            return {"error_type": "validation_error", "message": str(e)}
        except exc.IntegrityError as e:
            log.error(str(e))
            self.request.response.status_int = 400
            return {
                "error_type": "integrity_error",
                "message": str(e.orig.diag.message_primary)
            }
예제 #8
0
    def get(self) -> HTTPFound:
        ref = self.request.matchdict["ref"]
        short_urls = DBSession.query(Shorturl).filter(
            Shorturl.ref == ref).all()

        if len(short_urls) != 1:
            raise HTTPNotFound(f"Ref '{ref!s}' not found")

        short_urls[0].nb_hits += 1
        short_urls[0].last_hit = datetime.now()

        set_common_headers(self.request, "shortener", Cache.PUBLIC_NO)
        return HTTPFound(location=short_urls[0].url)
예제 #9
0
    def oauth2loginform(self) -> Dict[str, Any]:
        set_common_headers(self.request, "login", Cache.PUBLIC)

        if self.request.user:
            self._oauth2_login(self.request.user)

        login_param = {"type": "oauth2"}
        login_param.update(self.request.params)
        return {
            "lang": self.lang,
            "login_params": login_param,
            "two_fa": self.two_factor_auth,
        }
예제 #10
0
    def get(self):
        ref = self.request.matchdict["ref"]
        short_urls = DBSession.query(Shorturl).filter(
            Shorturl.ref == ref).all()

        if len(short_urls) != 1:
            raise HTTPNotFound("Ref '{0!s}' not found".format(ref))

        short_urls[0].nb_hits += 1
        short_urls[0].last_hit = datetime.now()

        set_common_headers(self.request, "shortener", NO_CACHE)
        return HTTPFound(location=short_urls[0].url)
예제 #11
0
    def get(self):
        ref = self.request.matchdict["ref"]
        short_urls = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all()

        if len(short_urls) != 1:
            raise HTTPNotFound("Ref '{0!s}' not found".format(ref))

        short_urls[0].nb_hits += 1
        short_urls[0].last_hit = datetime.now()

        set_common_headers(
            self.request, "shortener", NO_CACHE
        )
        return HTTPFound(location=short_urls[0].url)
예제 #12
0
    def update(self):
        set_common_headers(self.request, "layers", NO_CACHE)

        if self.request.user is None:
            raise HTTPForbidden()

        self.request.response.cache_control.no_cache = True

        feature_id = self.request.matchdict.get("feature_id")
        layer = self._get_layer_for_request()

        def check_geometry(r, feature, o):
            # we need both the "original" and "new" geometry to be
            # within the restriction area
            geom_attr, srid = self._get_geom_col_info(layer)
            geom_attr = getattr(o, geom_attr)
            geom = feature.geometry
            allowed = models.DBSession.query(func.count(RestrictionArea.id))
            allowed = allowed.join(RestrictionArea.roles)
            allowed = allowed.join(RestrictionArea.layers)
            allowed = allowed.filter(RestrictionArea.readwrite.is_(True))
            allowed = allowed.filter(Role.id == self.request.user.role.id)
            allowed = allowed.filter(Layer.id == layer.id)
            allowed = allowed.filter(
                or_(RestrictionArea.area.is_(None),
                    RestrictionArea.area.ST_Contains(geom_attr)))
            spatial_elt = None
            if geom and not isinstance(geom, geojson.geometry.Default):
                shape = asShape(geom)
                spatial_elt = from_shape(shape, srid=srid)
                allowed = allowed.filter(
                    or_(RestrictionArea.area.is_(None),
                        RestrictionArea.area.ST_Contains(spatial_elt)))
            if allowed.scalar() == 0:
                raise HTTPForbidden()

            # check is geometry is valid
            if self._get_validation_setting(layer):
                self._validate_geometry(spatial_elt)

        protocol = self._get_protocol_for_layer(layer,
                                                before_update=check_geometry)
        try:
            feature = protocol.update(self.request, feature_id)
            self._log_last_update(layer, feature)
            return feature
        except TopologicalError as e:
            self.request.response.status_int = 400
            return {"validation_error": str(e)}
예제 #13
0
    def loginform403(self) -> Union[Dict[str, Any], pyramid.response.Response]:
        if self.request.authenticated_userid is not None:
            return HTTPForbidden()

        set_common_headers(self.request, "login", Cache.PRIVATE_NO)

        return {
            "lang": self.lang,
            "login_params": {
                "came_from":
                (f"{self.request.path}?{urllib.parse.urlencode(self.request.GET)}"
                 )
            },
            "two_fa": self.two_factor_auth,
        }
예제 #14
0
def exportgpxkml(request):
    """
    View used to export a GPX or KML document.
    """

    fmt = request.params.get("format")
    if fmt is None:
        return HTTPBadRequest("format parameter is required")
    if fmt not in _CONTENT_TYPES:
        return HTTPBadRequest("format is not supported")

    name = request.params.get("name")
    if name is None:
        return HTTPBadRequest("name parameter is required")

    doc = request.params.get("doc")
    if doc is None:
        return HTTPBadRequest("doc parameter is required")

    charset = "utf-8"
    response = request.response
    response.body = doc.encode(charset)
    response.charset = charset
    response.content_disposition = ("attachment; filename={0!s}.{1!s}".format(
        name.replace(" ", "_"), fmt))
    return set_common_headers(request,
                              "exportgpxkml",
                              NO_CACHE,
                              content_type=_CONTENT_TYPES[fmt])
예제 #15
0
def exportgpxkml(request):
    """
    View used to export a GPX or KML document.
    """

    fmt = request.params.get("format")
    if fmt is None:
        return HTTPBadRequest("format parameter is required")
    if fmt not in _CONTENT_TYPES:
        return HTTPBadRequest("format is not supported")

    name = request.params.get("name")
    if name is None:
        return HTTPBadRequest("name parameter is required")

    doc = request.params.get("doc")
    if doc is None:
        return HTTPBadRequest("doc parameter is required")

    charset = "utf-8"
    response = request.response
    response.body = doc.encode(charset)
    response.charset = charset
    response.content_disposition = ("attachment; filename={0!s}.{1!s}".format(name.replace(" ", "_"), fmt))
    return set_common_headers(
        request, "exportgpxkml", NO_CACHE,
        content_type=_CONTENT_TYPES[fmt]
    )
예제 #16
0
def exportcsv(request):
    csv = request.params.get("csv")
    if csv is None:
        return HTTPBadRequest("csv parameter is required")

    request.response.cache_control.no_cache = True

    csv_extension = request.params.get("csv_extension", DEFAULT_CSV_EXTENSION)
    csv_encoding = request.params.get("csv_encoding", DEFAULT_CSV_ENCODING)
    name = request.params.get("name", "export")

    response = request.response
    content = b""
    if csv_encoding == DEFAULT_CSV_ENCODING:
        content += codecs.BOM_UTF8
    content += csv.encode(csv_encoding)
    request.response.body = content
    response.charset = csv_encoding.encode(csv_encoding)
    response.content_disposition = "attachment; filename={0!s}.{1!s}".format(
        name.replace(" ", "_"), csv_extension
    )
    return set_common_headers(
        request, "csvecho", NO_CACHE,
        content_type="text/csv"
    )
예제 #17
0
    def csv(self):
        """answers to /profile.csv"""
        layers, points = self._compute_points()

        result = _("distance") + "," + ",".join(layers) + ",x,y"
        template = ",".join("%s" for l in layers)
        for point in points:
            # Handles cases when a layer is undefined, thus when not all raster
            # have the same geographical coverage
            for l in layers:
                if l not in point["values"]:
                    point["values"][l] = -9999

            r = template % tuple((str(point["values"][l]) for l in layers))
            result += "\n{},{},{:.1f},{:.1f}".format(str(point["dist"]), r,
                                                     point["x"], point["y"])

        return set_common_headers(self.request,
                                  "profile",
                                  NO_CACHE,
                                  response=Response(
                                      result,
                                      headers={
                                          "Content-Disposition":
                                          'attachment; filename="profile.csv"',
                                      }),
                                  content_type="text/csv; charset=utf-8",
                                  vary=True)
예제 #18
0
    def oauth2token(self) -> pyramid.response.Response:
        LOG.debug(
            "Call OAuth create_token_response with:\nurl: %s\nmethod: %s\nbody:\n%s",
            self.request.current_route_url(_query=self.request.GET),
            self.request.method,
            self.request.body,
        )
        headers, body, status = oauth2.get_oauth_client(
            self.request.registry.settings).create_token_response(
                self.request.current_route_url(_query=self.request.GET),
                self.request.method,
                self.request.body,
                self.request.headers,
                {},
            )
        LOG.debug("OAuth create_token_response return status: %s", status)

        if hasattr(self.request, "tm"):
            self.request.tm.commit()

        # All requests to /token will return a json response, no redirection.
        if status != 200:
            if body:
                raise exception_response(status, detail=body)
            raise exception_response(status)
        return set_common_headers(
            self.request,
            "login",
            Cache.PRIVATE_NO,
            response=Response(body, headers=headers.items()),
        )
예제 #19
0
    def _oauth2_login(self, user: static.User) -> pyramid.response.Response:
        self.request.user_ = user
        LOG.debug(
            "Call OAuth create_authorization_response with:\nurl: %s\nmethod: %s\nbody:\n%s",
            self.request.current_route_url(_query=self.request.GET),
            self.request.method,
            self.request.body,
        )
        headers, body, status = oauth2.get_oauth_client(
            self.request.registry.settings).create_authorization_response(
                self.request.current_route_url(_query=self.request.GET),
                self.request.method,
                self.request.body,
                self.request.headers,
            )
        if hasattr(self.request, "tm"):
            self.request.tm.commit()
        LOG.debug(
            "OAuth create_authorization_response return\nstatus: %s\nbody:\n%s",
            status, body)

        if status == 302:
            raise HTTPFound(location=headers["Location"])
        if status != 200:
            if body:
                raise exception_response(status, details=body)
            raise exception_response(status)
        return set_common_headers(
            self.request,
            "login",
            Cache.PRIVATE_NO,
            response=Response(body, headers=headers.items()),
        )
예제 #20
0
def error_handler(http_exception, request):  # pragma: no cover
    """
    View callable for handling all the exceptions that are not already handled.
    """
    LOG.warning("%s returned status code %s", request.url,
                http_exception.status_code)
    return caching.set_common_headers(request, "error", caching.NO_CACHE,
                                      http_exception)
예제 #21
0
def error_handler(
        http_exception: HTTPException,
        request: pyramid.request.Request) -> pyramid.response.Response:
    """View callable for handling all the exceptions that are not already handled."""
    LOG.warning("%s returned status code %s", request.url,
                http_exception.status_code)
    return caching.set_common_headers(request, "error",
                                      caching.Cache.PRIVATE_NO, http_exception)
예제 #22
0
    def metadata(self):
        set_common_headers(self.request, "layers", PRIVATE_CACHE)

        layer = self._get_layer_for_request()
        if not layer.public and self.request.user is None:
            raise HTTPForbidden()

        # exclude the columns used to record the last features update
        exclude = [] if layer.exclude_properties is None else layer.exclude_properties.split(
            ",")
        last_update_date = self._get_metadata(layer, "lastUpdateDateColumn")
        if last_update_date is not None:
            exclude.append(last_update_date)
        last_update_user = self._get_metadata(layer, "lastUpdateUserColumn")
        if last_update_user is not None:
            exclude.append(last_update_user)

        return get_class(layer.geo_table, exclude_properties=exclude)
예제 #23
0
def error_handler(http_exception, request):  # pragma: no cover
    """
    View callable for handling all the exceptions that are not already handled.
    """
    log.warning("%s returned status code %s", request.url,
                http_exception.status_code)
    return caching.set_common_headers(
        request, "error", caching.NO_CACHE, http_exception, vary=True
    )
예제 #24
0
    def raster(self):
        lon = float(self.request.params["lon"])
        lat = float(self.request.params["lat"])
        if "layers" in self.request.params:
            rasters = {}
            layers = self.request.params["layers"].split(",")
            for layer in layers:
                if layer in self.rasters:
                    rasters[layer] = self.rasters[layer]
                else:
                    raise HTTPNotFound("Layer {0!s} not found".format(layer))
        else:
            rasters = self.rasters

        result = {}
        for ref in list(rasters.keys()):
            result[ref] = self._get_raster_value(rasters[ref], lon, lat)

        set_common_headers(self.request, "raster", NO_CACHE)
        return result
예제 #25
0
    def loginresetpassword(self) -> Dict[str, Any]:
        set_common_headers(self.request, "login", Cache.NO)

        user, username, password, error = self._loginresetpassword()
        if error is not None:
            LOG.info(error)
            raise HTTPUnauthorized("See server logs for details")
        assert user is not None
        assert password is not None
        if user.deactivated:
            LOG.info("The user '%s' is deactivated", username)
            raise HTTPUnauthorized("See server logs for details")

        send_email_config(self.request.registry.settings,
                          "reset_password",
                          user.email,
                          user=username,
                          password=password)

        return {"success": True}
예제 #26
0
    def raster(self):
        lon = float(self.request.params["lon"])
        lat = float(self.request.params["lat"])
        if "layers" in self.request.params:
            rasters = {}
            layers = self.request.params["layers"].split(",")
            for layer in layers:
                if layer in self.rasters:
                    rasters[layer] = self.rasters[layer]
                else:
                    raise HTTPNotFound("Layer {0!s} not found".format(layer))
        else:
            rasters = self.rasters

        result = {}
        for ref in list(rasters.keys()):
            result[ref] = self._get_raster_value(rasters[ref], lon, lat)

        set_common_headers(self.request, "raster", NO_CACHE)
        return result
예제 #27
0
    def raster(self) -> Dict[str, Any]:
        lon = self._get_required_finite_float_param("lon")
        lat = self._get_required_finite_float_param("lat")

        if "layers" in self.request.params:
            rasters = {}
            layers = self.request.params["layers"].split(",")
            for layer in layers:
                if layer in self.rasters:
                    rasters[layer] = self.rasters[layer]
                else:
                    raise HTTPNotFound(f"Layer {layer} not found")
        else:
            rasters = self.rasters

        result = {}
        for ref in list(rasters.keys()):
            result[ref] = self._get_raster_value(rasters[ref], ref, lon, lat)

        set_common_headers(self.request, "raster", Cache.PUBLIC_NO)
        return result
예제 #28
0
def canvas_view(request: pyramid.request.Request,
                interface_config: Dict[str, Any]) -> Dict[str, Any]:
    """Get view used as entry point of a canvas interface."""

    js_files = _get_ngeo_resources(
        f"{interface_config.get('layout', interface_config['name'])}*.js")
    css_files = _get_ngeo_resources(
        f"{interface_config.get('layout', interface_config['name'])}*.css")
    css = "\n    ".join([
        f'<link href="{request.static_url(css)}" rel="stylesheet" crossorigin="anonymous">'
        for css in css_files
    ])

    set_common_headers(request,
                       "index",
                       Cache.PUBLIC_NO,
                       content_type="text/html")

    spinner = ""
    spinner_filenames = _get_ngeo_resources("spinner*.svg")
    if spinner_filenames:
        with open(spinner_filenames[0], encoding="utf-8") as spinner_file:
            spinner = spinner_file.read()

    return {
        "request":
        request,
        "header":
        f"""
<meta name="dynamicUrl" content="{request.route_url("dynamic")}">
<meta name="interface" content="{interface_config['name']}">
{css}""",
        "footer":
        "\n    ".join([
            f'<script src="{request.static_url(js)}" crossorigin="anonymous"></script>'
            for js in js_files
        ]),
        "spinner":
        spinner,
    }
예제 #29
0
    def _build_response(self,
                        response,
                        content,
                        cache_control,
                        service_name,
                        headers=None,
                        headers_update=None,
                        content_type=None):
        if isinstance(content, str):
            content = content.encode("utf-8")
        if headers_update is None:
            headers_update = {}
        headers = response.headers if headers is None else headers

        # Hop-by-hop Headers are not supported by WSGI
        # See:
        # https://www.python.org/dev/peps/pep-3333/#other-http-features
        # chapter 13.5.1 at https://www.faqs.org/rfcs/rfc2616.html
        for header in [
                "Connection",
                "Keep-Alive",
                "Proxy-Authenticate",
                "Proxy-Authorization",
                "te",
                "Trailers",
                "Transfer-Encoding",
                "Upgrade",
        ]:  # pragma: no cover
            if header in headers:
                del headers[header]
        # Other problematic headers
        for header in [
                "Content-Length",
                "Content-Location",
                "Content-Encoding",
        ]:  # pragma: no cover
            if header in headers:
                del headers[header]

        headers.update(headers_update)

        response = Response(content,
                            status=response.status_code,
                            headers=headers)

        return set_common_headers(
            self.request,
            service_name,
            cache_control,
            response=response,
            content_type=content_type,
        )
예제 #30
0
    def read_one(self):
        from c2cgeoportal_commons.models.main import (  # pylint: disable=import-outside-toplevel
            Layer, RestrictionArea, Role,
        )

        set_common_headers(self.request, "layers", NO_CACHE)

        layer = self._get_layer_for_request()
        protocol = self._get_protocol_for_layer(layer)
        feature_id = self.request.matchdict.get("feature_id")
        feature = protocol.read(self.request, id=feature_id)
        if not isinstance(feature, Feature):
            return feature
        if layer.public:
            return feature
        if self.request.user is None:
            raise HTTPForbidden()
        geom = feature.geometry
        if not geom or isinstance(
                geom, geojson.geometry.Default):  # pragma: no cover
            return feature
        shape = asShape(geom)
        srid = self._get_geom_col_info(layer)[1]
        spatial_elt = from_shape(shape, srid=srid)
        allowed = models.DBSession.query(func.count(RestrictionArea.id))
        allowed = allowed.join(RestrictionArea.roles)
        allowed = allowed.join(RestrictionArea.layers)
        allowed = allowed.filter(Role.id.in_(get_roles_id(self.request)))
        allowed = allowed.filter(Layer.id == layer.id)
        allowed = allowed.filter(
            or_(RestrictionArea.area.is_(None),
                RestrictionArea.area.ST_Contains(spatial_elt)))
        if allowed.scalar() == 0:
            raise HTTPForbidden()

        return feature
예제 #31
0
    def logout(self) -> pyramid.response.Response:
        headers = forget(self.request)

        if not self.request.user:
            LOG.info("Logout on non login user.")
            raise HTTPUnauthorized("See server logs for details")

        LOG.info("User '%s' (%s) logging out.", self.request.user.username,
                 self.request.user.id)

        headers.append(("Content-Type", "text/json"))
        return set_common_headers(self.request,
                                  "login",
                                  Cache.PRIVATE_NO,
                                  response=Response("true", headers=headers))
예제 #32
0
    def _build_response(
        self,
        response: pyramid.response.Response,
        content: str,
        cache_control: Cache,
        service_name: str,
        headers: Dict[str, str] = None,
        headers_update: Dict[str, str] = None,
        content_type: str = None,
    ) -> pyramid.response.Response:
        if headers_update is None:
            headers_update = {}
        headers = response.headers if headers is None else headers

        # Hop-by-hop Headers are not supported by WSGI
        # See:
        # https://www.python.org/dev/peps/pep-3333/#other-http-features
        # chapter 13.5.1 at https://www.faqs.org/rfcs/rfc2616.html
        for header in [
                "Connection",
                "Keep-Alive",
                "Proxy-Authenticate",
                "Proxy-Authorization",
                "te",
                "Trailers",
                "Transfer-Encoding",
                "Upgrade",
        ]:
            if header in headers:
                del headers[header]
        # Other problematic headers
        for header in [
                "Content-Length", "Content-Location", "Content-Encoding"
        ]:
            if header in headers:
                del headers[header]

        headers.update(headers_update)

        response = pyramid.response.Response(content,
                                             status=response.status_code,
                                             headers=headers)

        return set_common_headers(self.request,
                                  service_name,
                                  cache_control,
                                  response=response,
                                  content_type=content_type)
예제 #33
0
    def get(self):
        """ Get created PDF. """

        resp, content = self._proxy("{0!s}{1!s}.printout".format(
            self.config["print_url"], self.request.matchdict.get("file")))

        headers = {}
        if "content-type" in resp:
            headers["content-type"] = resp["content-type"]
        if "content-disposition" in resp:
            headers["content-disposition"] = resp["content-disposition"]

        return set_common_headers(
            self.request,
            "print",
            NO_CACHE,
            response=Response(content, status=resp.status, headers=headers),
        )
예제 #34
0
    def echo_csv(self):

        name = self.request.params.get("name")
        if name is None:
            return HTTPBadRequest("name parameter is required")

        csv = self.request.params.get("csv")
        if csv is None:
            return HTTPBadRequest("csv parameter is required")

        charset = "utf-8"
        response = self.request.response
        response.body = csv.encode(charset)
        response.charset = charset
        response.content_disposition = ("attachment; filename=%s.csv"
                                        % (name.replace(" ", "_")))
        return set_common_headers(
            self.request, "exportcsv", NO_CACHE,
            content_type="application/csv"
        )
예제 #35
0
def echo(request):
    """
    Echo an uploaded file back to the client as an text/html document so it can
    be handled by Ext.

    The response is JSON-wrapped and base64-encoded to ensure that there are no
    special HTML characters or charset problems and so that braindead ext
    does not barf on it.

    See:
    http://docs.sencha.com/ext-js/3-4/#!/api/Ext.form.BasicForm-cfg-fileUpload
    """
    try:
        file_ = request.POST["file"]
    except KeyError:
        return HTTPBadRequest()
    response = Response()
    response.app_iter = json_base64_encode(file_.filename, file_.file)
    return set_common_headers(
        request, "echo", NO_CACHE,
        response=response, content_type="text/html"
    )
예제 #36
0
    def csv(self):
        """answers to /profile.csv"""
        layers, points = self._compute_points()

        result = _("distance") + "," + ",".join(layers) + ",x,y"
        template = ",".join("%s" for l in layers)
        for point in points:
            # Handles cases when a layer is undefined, thus when not all raster
            # have the same geographical coverage
            for l in layers:
                if l not in point["values"]:
                    point["values"][l] = -9999

            r = template % tuple((str(point["values"][l]) for l in layers))
            result += "\n{},{},{:.1f},{:.1f}".format(str(point["dist"]), r, point["x"], point["y"])

        return set_common_headers(
            self.request, "profile", NO_CACHE,
            response=Response(result, headers={
                "Content-Disposition": 'attachment; filename="profile.csv"',
            }), content_type="text/csv; charset=utf-8", vary=True
        )
예제 #37
0
    def _build_response(
        self, resp, content, cache_control, service_name,
        headers=None, headers_update=None, content_type=None
    ):
        if headers_update is None:
            headers_update = {}
        headers = dict(resp) if headers is None else headers

        # Hop-by-hop Headers are not supported by WSGI
        # See:
        # https://www.python.org/dev/peps/pep-3333/#other-http-features
        # chapter 13.5.1 at http://www.faqs.org/rfcs/rfc2616.html
        for header in [
                "connection",
                "keep-alive",
                "proxy-authenticate",
                "proxy-authorization",
                "te",
                "trailers",
                "transfer-encoding",
                "upgrade"
        ]:  # pragma: no cover
            if header in headers:
                del headers[header]
        # Other problematic headers
        for header in ["content-length", "content-location"]:  # pragma: no cover
            if header in headers:
                del headers[header]

        headers.update(headers_update)

        response = Response(content, status=resp.status, headers=headers)

        return set_common_headers(
            self.request, service_name, cache_control,
            response=response,
            content_type=content_type,
        )
예제 #38
0
 def view(request):  # pragma: no cover
     from c2cgeoportal_geoportal.lib.caching import set_common_headers, NO_CACHE
     return set_common_headers(request, service, NO_CACHE)
예제 #39
0
    def create(self):

        if "url" not in self.request.params:
            raise HTTPBadRequest("The parameter url is required")

        url = self.request.params["url"]

        # see: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline
        if len(url) > 8190:  # pragma: no cover
            raise HTTPBadRequest("The parameter url is too long ({} > {})".format(len(url), 8190))

        # Check that it is an internal URL...
        uri_parts = urlparse(url)
        hostname = uri_parts.hostname
        if "allowed_hosts" in self.settings:
            if hostname not in self.settings["allowed_hosts"]:  # pragma: no cover
                raise HTTPBadRequest("The requested host is not allowed.")
        else:
            if hostname != self.request.server_name:
                raise HTTPBadRequest("The requested host '{0!s}' should be '{1!s}'".format(
                    hostname, self.request.server_name
                ))

        shortened = False

        for base in self.short_bases:
            base_parts = urlparse(base)
            if uri_parts.path.startswith(base_parts.path):
                shortened = True
                ref = uri_parts.path.split("/")[-1]

        tries = 0
        while not shortened:
            ref = "".join(
                random.choice(string.ascii_letters + string.digits)
                for i in range(self.settings.get("length", 4))
            )
            test_url = DBSession.query(Shorturl).filter(Shorturl.ref == ref).all()
            if len(test_url) == 0:
                break
            tries += 1  # pragma: no cover
            if tries > 20:  # pragma: no cover
                message = "No free ref found, considere to increase the length"
                logging.error(message)
                raise HTTPInternalServerError(message)

        user_email = self.request.user.email \
            if self.request.user is not None else None
        email = self.request.params.get("email")
        if not shortened:
            short_url = Shorturl()
            short_url.url = url
            short_url.ref = ref
            short_url.creator_email = user_email
            short_url.creation = datetime.now()
            short_url.nb_hits = 0

            DBSession.add(short_url)

        if "base_url" in self.settings:
            s_url = self.settings["base_url"] + ref
        else:
            s_url = self.request.route_url("shortener_get", ref=ref)

        email = email or user_email

        smtp_config = self.request.registry.settings.get("smtp", {})
        if \
                email is not None and \
                "email_from" in self.settings and \
                "email_subject" in self.settings and \
                "email_body" in self.settings:  # pragma: no cover
            text = self.settings["email_body"] % {
                "full_url": url,
                "short_url": s_url,
                "message": self.request.params.get("message", ""),
            }
            send_email(
                self.settings["email_from"],
                [email],
                text.encode("utf-8"),
                self.settings["email_subject"],
                smtp_config
            )

        set_common_headers(
            self.request, "shortener", NO_CACHE
        )
        return {"short_url": s_url}
예제 #40
0
 def __init__(self, request):
     self.request = request
     set_common_headers(request, "fulltextsearch", NO_CACHE)
     self.settings = request.registry.settings.get("fulltextsearch", {})
     self.languages = self.settings.get("languages", {})
예제 #41
0
 def json(self):
     """answers to /profile.json"""
     _, points = self._compute_points()
     set_common_headers(self.request, "profile", NO_CACHE)
     return {"profile": points}
예제 #42
0
def other_error(exception, request):  # pragma: no cover
    set_common_headers(request, "index", NO_CACHE)
    return _do_error(request, 500, exception)