Exemple #1
0
 def remove_project_from_cache(sender, **kwargs):
     from qdjango.apps import QGS_SERVER, QgsConfigCache
     from qdjango.utils.data import QgisProject
     if not isinstance(sender, QgisProject):
         return
     path = sender.instance.qgis_file.path
     QgsConfigCache.instance().removeEntry(path)
     QGS_SERVER.serverInterface().capabilitiesCache(
     ).removeCapabilitiesDocument(path)
     logging.getLogger('g3wadmin.debug').warning(
         'settings.DEBUG is True: QGIS Server cached project invalidated: %s'
         % path)
Exemple #2
0
    def baseDoRequest(self, q):

        request = self.request

        # Uppercase REQUEST
        if 'REQUEST' in [k.upper() for k in q.keys()]:
            if request.method == 'GET':
                ows_request = q['REQUEST'].upper()
            else:
                if request.content_type == 'application/x-www-form-urlencoded':
                    ows_request = request.POST['REQUEST'].upper()
                else:
                    ows_request = request.POST['REQUEST'][0].upper()
            q['REQUEST'] = ows_request

        # FIXME: proxy or redirect in case of WMS/WFS/XYZ cascading?
        qgs_project = get_qgs_project(self.project.qgis_file.path)

        if qgs_project is None:
            raise Http404('The requested QGIS project could not be loaded!')

        data = None
        if request.method == 'GET':
            method = QgsBufferServerRequest.GetMethod
        elif request.method == 'POST':
            method = QgsBufferServerRequest.PostMethod
            data = request.body
        elif request.method == 'PUT':
            method = QgsBufferServerRequest.PutMethod
            data = request.body
        elif request.method == 'PATCH':
            method = QgsBufferServerRequest.PatchMethod
            data = request.body
        elif request.method == 'HEAD':
            method = QgsBufferServerRequest.HeadMethod
        elif request.method == 'DELETE':
            method = QgsBufferServerRequest.DeleteMethod
        else:
            logger.warning("Request method not supported: %s, assuming GET" %
                           request.method)
            method = QgsBufferServerRequest.GetMethod

        headers = {}
        for header_key in request.headers.keys():
            headers[header_key] = request.headers.get(header_key)
        uri = request.build_absolute_uri(request.path) + '?' + q.urlencode()
        logger.debug('Calling QGIS Server: %s' % uri)
        qgs_request = QgsBufferServerRequest(uri, method, headers, data)

        # Attach user and project to the server object to make them accessible by the
        # server access control plugins (constraints etc.)
        QGS_SERVER.user = request.user
        QGS_SERVER.project = self.project

        qgs_response = QgsBufferServerResponse()
        try:
            QGS_SERVER.handleRequest(qgs_request, qgs_response, qgs_project)
        except Exception as ex:
            return HttpResponseServerError(
                reason="Error handling server request: %s" % ex)

        response = HttpResponse(bytes(qgs_response.body()))
        response.status_code = qgs_response.statusCode()

        for key, value in qgs_response.headers().items():
            response[key] = value

        return response
Exemple #3
0
    """A filter that excludes columns from layers"""
    def __init__(self, server_iface):
        super().__init__(server_iface)

    def authorizedLayerAttributes(self, layer, attributes):
        """Retrieve and sets column acl"""

        try:
            qdjango_layer = Layer.objects.get(project=QGS_SERVER.project,
                                              qgs_layer_id=layer.id())
            if qdjango_layer.has_column_acl:
                user = QGS_SERVER.user
                return qdjango_layer.visible_fields_for_user(user)
        except Layer.DoesNotExist:
            pass

        return attributes

    def cacheKey(self):
        """Return a cache key, a constant value means that the cache works
        normally and this filter does not influence the cache, an empty value
        (which is the default implementation) means that the cache is disabled"""

        # Return a constant: the cache is not influenced by this filter
        return "ca"


# Register the filter, keep a reference because of the garbage collector
ac_filter = ColumnAclAccessControlFilter(QGS_SERVER.serverInterface())
QGS_SERVER.serverInterface().registerAccessControl(ac_filter, 1)
Exemple #4
0
                % (QGS_SERVER.user, layer.id(), rule), "", Qgis.Info)

        return rule

    def cacheKey(self):
        """Return a cache key, a constant value means that the cache works
        normally and this filter does not influence the cache, an empty value
        (which is the default implementation) means that the cache is disabled"""

        # Return a constant: the cache is not influenced by this filter
        return "sl"


# Register the filter, keep a reference because of the garbage collector
ac_filter = SingleLayerSubsetStringAccessControlFilter(
    QGS_SERVER.serverInterface())
# Note: this should be the last filter, set the priority to 10000
QGS_SERVER.serverInterface().registerAccessControl(ac_filter, 10000)


class SingleLayerExpressionAccessControlFilter(QgsAccessControlFilter):
    """A filter that sets an expression filter from the layer constraints"""
    def __init__(self, server_iface):
        super().__init__(server_iface)

    def layerFilterExpression(self, layer):
        """Retrieve and sets user layer constraints"""

        try:
            qdjango_layer = Layer.objects.get(project=QGS_SERVER.project,
                                              qgs_layer_id=layer.id())
Exemple #5
0
            return ""

        # check for filtertoken
        request_data = QGS_SERVER.djrequest.POST if QGS_SERVER.djrequest.method == 'POST' \
            else QGS_SERVER.djrequest.GET

        filtertoken = request_data.get('filtertoken')
        if not filtertoken:
            return ""

        rule = SessionTokenFilter.get_expr_for_token(filtertoken,
                                                     qdjango_layer)
        QgsMessageLog.logMessage(
            "SingleLayerSessionTokenAccessControlFilter expression for filtertoken %s layer id %s: %s"
            % (filtertoken, layer.id(), rule), "", Qgis.Info)
        return rule

    def cacheKey(self):
        """Return a cache key, a contant value means that the cache works
        normally and this filter does not influence the cache, an empty value
        (which is the default implementation) means that the cache is disabled"""

        # Return a constant: the cache is not influenced by this filter
        return "slt"


# Register the filter, keep a reference because of the garbage collector
ac_filter3 = SingleLayerSessionTokenAccessControlFilter(
    QGS_SERVER.serverInterface())
QGS_SERVER.serverInterface().registerAccessControl(ac_filter3, 9998)
Exemple #6
0
                if qlayer.dataProvider().name() == Layer.TYPES.gdal and rlayer == qlayer.id():

                    self.layers_render.append({
                       'qlayer': qlayer,
                       'renderer': qlayer.renderer().clone()
                    })

                    rts = RTS(qlayer)
                    rts.setDateIndex(int(rband))

    def responseComplete(self):

        # Restore renderer
        for l in self.layers_render:
            l['qlayer'].setRenderer(l['renderer'])











# Register the filter, keep a reference because of the garbage collector
ac_filter10 = QRasterTimeSeriesFilter(QGS_SERVER.serverInterface())
QGS_SERVER.serverInterface().registerFilter(ac_filter10, 9995)
Exemple #7
0
    in the query string"""
    def __init__(self, server_iface):
        super().__init__(server_iface)

    def layerPermissions(self, layer):
        """Return the layer rights canRead, canInsert, canUpdate, canDelete """

        rh = self.serverInterface().requestHandler()
        if rh.parameterMap().get("TEST_ACCESS_CONTROL", "") == layer.name():
            permissions = QgsAccessControlFilter.LayerPermissions()
            permissions.canRead = False
            permissions.canUpdate = False
            permissions.canDelete = False
            permissions.canCreate = False
            return permissions
        else:
            return super().layerPermissions(layer)

    def cacheKey(self):
        """Return a cache key, a constant value means that the cache works
        normally and this filter does not influence the cache, an empty value
        (which is the default implementation) means that the cache is disabled"""

        # Return a constant: the cache is not influenced by this filter
        return "tac"


# Register the filter, keep a reference because of the garbage collector
ac_filter = TestAccessControlFilter(QGS_SERVER.serverInterface())
QGS_SERVER.serverInterface().registerAccessControl(ac_filter, 100)
Exemple #8
0
    def baseDoRequest(self, q):

        request = self.request

        # Uppercase REQUEST
        if 'REQUEST' in [k.upper() for k in q.keys()]:
            if request.method == 'GET':
                ows_request = q['REQUEST'].upper()
            else:
                if request.content_type == 'application/x-www-form-urlencoded':
                    ows_request = request.POST['REQUEST'].upper()
                else:
                    ows_request = request.POST['REQUEST'][0].upper()
            q['REQUEST'] = ows_request

        # FIXME: proxy or redirect in case of WMS/WFS/XYZ cascading?
        qgs_project = get_qgs_project(self.project.qgis_file.path)

        if qgs_project is None:
            raise Http404('The requested QGIS project could not be loaded!')

        data = None
        if request.method == 'GET':
            method = QgsBufferServerRequest.GetMethod
        elif request.method == 'POST':
            method = QgsBufferServerRequest.PostMethod
            data = request.body
        elif request.method == 'PUT':
            method = QgsBufferServerRequest.PutMethod
            data = request.body
        elif request.method == 'PATCH':
            method = QgsBufferServerRequest.PatchMethod
            data = request.body
        elif request.method == 'HEAD':
            method = QgsBufferServerRequest.HeadMethod
        elif request.method == 'DELETE':
            method = QgsBufferServerRequest.DeleteMethod
        else:
            logger.warning(
                "Request method not supported: %s, assuming GET" % request.method)
            method = QgsBufferServerRequest.GetMethod

        headers = {}
        for header_key in request.headers.keys():
            headers[header_key] = request.headers.get(header_key)
        uri = request.build_absolute_uri(request.path) + '?' + q.urlencode()
        logger.debug('Calling QGIS Server: %s' % uri)
        qgs_request = QgsBufferServerRequest(uri, method, headers, data)

        # Attach user and project to the server object to make them accessible by the
        # server access control plugins (constraints etc.)
        QGS_SERVER.djrequest = request
        QGS_SERVER.user = request.user
        QGS_SERVER.project = self.project


        # For GetPrint QGIS functions that rely on layers visibility, we need to check
        # the layers from LAYERS
        use_ids = QgsServerProjectUtils.wmsUseLayerIds(qgs_project)
        tree_root = qgs_project.layerTreeRoot()

        # Loop through the layers and make them visible
        for layer_name in qgs_request.queryParameter('LAYERS').split(','):
            layer_name = urllib.parse.unquote(layer_name)
            layer = None
            if use_ids:
                layer = qgs_project.mapLayer(layer_name)
            else:
                try:
                    layer = qgs_project.mapLayersByName(layer_name)[0]
                except:  # short name?
                    for l in qgs_project.mapLayers().values():
                        if l.shortName() == layer_name:
                            layer = l
                            break

            if layer is None:
                logger.warning(
                    'Could not find layer "{}" when configuring OWS call'.format(layer_name))
            else:
                layer_node = tree_root.findLayer(layer)
                if layer_node is not None:
                    layer_node.setItemVisibilityCheckedParentRecursive(True)
                else:
                    logger.warning(
                        'Could not find layer tree node "{}" when configuring OWS call'.format(layer_name))


        qgs_response = QgsBufferServerResponse()
        try:
            QGS_SERVER.handleRequest(qgs_request, qgs_response, qgs_project)
        except Exception as ex:
            return HttpResponseServerError(reason="Error handling server request: %s" % ex)

        response = HttpResponse(bytes(qgs_response.body()))
        response.status_code = qgs_response.statusCode()

        for key, value in qgs_response.headers().items():
            response[key] = value

        return response
Exemple #9
0
    def layerFilterSubsetString(self, layer):
        """Retrieve and sets user layer constraints"""

        try:
            qdjango_layer = Layer.objects.get(project=QGS_SERVER.project, qgs_layer_id=layer.id())
        except Layer.DoesNotExist:
            return ""

        rule = ConstraintSubsetStringRule.get_rule_definition_for_user(QGS_SERVER.user, qdjango_layer.pk)
        QgsMessageLog.logMessage("SingleLayerSubsetStringAccessControlFilter rule for user %s and layer id %s: %s" % (QGS_SERVER.user, layer.id(), rule), "", Qgis.Info)
        return rule



# Register the filter, keep a reference because of the garbage collector
ac_filter = SingleLayerSubsetStringAccessControlFilter(QGS_SERVER.serverInterface())
# Note: this should be the last filter, set the priority to 10000
QGS_SERVER.serverInterface().registerAccessControl(ac_filter, 10000)


class SingleLayerExpressionAccessControlFilter(QgsAccessControlFilter):
    """A filter that sets an expression filter from the layer constraints"""

    def __init__(self, server_iface):
        super().__init__(server_iface)

    def layerFilterExpression(self, layer):
        """Retrieve and sets user layer constraints"""

        try:
            qdjango_layer = Layer.objects.get(project=QGS_SERVER.project, qgs_layer_id=layer.id())
Exemple #10
0
        handler = self.server_iface.requestHandler()
        params = handler.parameterMap()

        service = params.get('SERVICE')
        if not service:
            return

        if service.lower() != 'wms':
            return

        # Check request to change atlas one
        if 'REQUEST' not in params or params['REQUEST'].lower() not in [
                'getprintatlas', 'getcapabilitiesatlas'
        ]:
            return

        request = params['REQUEST'].lower()

        handler.setParameter('SERVICE', 'ATLAS')
        handler.setParameter('VERSION', '1.0.0')

        if request == 'getcapabilitiesatlas':
            handler.setParameter('REQUEST', 'GetCapabilities')
        elif request == 'getprintatlas':
            handler.setParameter('REQUEST', 'GetPrint')


# Register the filter, keep a reference because of the garbage collector
altas_filter = AtlasPrintFilter(QGS_SERVER.serverInterface())
# Note: this should be the last filter, set the priority to 10000
QGS_SERVER.serverInterface().registerFilter(altas_filter, 50)
Exemple #11
0
 def tearDownClass(cls):
     super().tearDownClass()
     iface = QGS_SERVER.serverInterface()
     iface.removeConfigCacheEntry(
         cls.qdjango_project.qgis_project.fileName())