Example #1
0
    def test_editing_view_retrieve_data(self):
        """Test constraint filter for editing API - SELECT"""

        client = APIClient()
        editing_layer = Layer.objects.get(name='editing_layer')
        self.assertTrue(
            client.login(username=self.test_user2.username,
                         password=self.test_user2.username))
        assign_perm('change_layer', self.test_user2, editing_layer)
        self.assertTrue(
            self.test_user2.has_perm('qdjango.change_layer', editing_layer))
        response = client.post(
            '/vector/api/editing/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id), {},
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        fids = [int(f['id']) for f in jcontent['vector']['data']['features']]
        # All fids should be here
        self.assertEqual(fids, [1, 2, 3, 4])

        # Now add a constraint for user2
        constraint_layer = Layer.objects.get(name=self.constraint_layer_name)
        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer,
                                   for_editing=True)
        constraint.save()
        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user2,
                                 rule='name=\'bagnolo\'')
        rule.save()
        response = client.post(
            '/vector/api/editing/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id), {},
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        fids = [int(f['id']) for f in jcontent['vector']['data']['features']]
        # Only allowed fids
        self.assertEqual(fids, [1, 2])

        # Test with inactive constraint
        constraint.active = False
        constraint.save()
        response = client.post(
            '/vector/api/editing/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id), {},
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        fids = [int(f['id']) for f in jcontent['vector']['data']['features']]
        # All fids should be here
        self.assertEqual(fids, [1, 2, 3, 4])

        # reset test db
        self.reset_db_data()
Example #2
0
def validate_constraint(**kwargs):
    """Checks whether the instance validates the active constraints in commit mode
    kwargs: ["layer_metadata", "mode", "data", "user"]
    """

    mode = kwargs['mode']
    if mode not in (EDITING_POST_DATA_UPDATED, EDITING_POST_DATA_ADDED):
        return

    editing_layer = Layer.objects.get(pk=kwargs['layer_metadata'].layer_id)
    user = kwargs['user']

    # check rule presence for layer
    rules = GeoConstraintRule.get_active_constraints_for_user(user,
                                                              editing_layer,
                                                              context='e')

    if len(rules) == 0:
        return

    coords = kwargs['data']['feature']['geometry']['coordinates']
    geom_type = kwargs['data']['feature']['geometry']['type']
    geom_class = getattr(geos, geom_type)

    # For multi geometry type
    if geom_type == 'MultiPolygon':
        Polygon = getattr(geos, 'Polygon')
        coords = [Polygon(p) for p in coords[0]]

    if geom_type == 'MultiLineString':
        LineString = getattr(geos, 'LineString')
        coords = [LineString(p) for p in coords]

    if geom_type == 'MultiPoint':
        Point = getattr(geos, 'Point')
        coords = [Point(p) for p in coords]

    # set spatial predicate for validation
    spatial_predicate = getattr(settings,
                                'EDITING_CONSTRAINT_SPATIAL_PREDICATE',
                                'contains')

    for rule in rules:
        allowed_geom, __ = rule.get_constraint_geometry()
        geom = geom_class(coords)
        geom.srid = allowed_geom.srid
        predicate_method = getattr(allowed_geom, spatial_predicate)
        if not predicate_method(geom):
            raise IntegrityError(
                _('Constraint validation failed for geometry: %s') % geom.wkt)
Example #3
0
    def apply_filter(self, request, metadata_layer, qgis_feature_request, view):

        qgis_layer = metadata_layer.qgis_layer

        rule_parts = []

        rules = GeoConstraintRule.get_active_constraints_for_user(request.user, view.layer,
                                                                  context=getattr(view, 'context', 'v'))

        for rule in rules:
            expression = rule.get_qgis_expression()
            if expression:
                rule_parts.append(expression)

        if rule_parts:
            expression = ' AND '.join(rule_parts)

            qgis_feature_request.combineFilterExpression(expression)
Example #4
0
    def test_sql_validation(self):
        """Test SQL rule validation"""

        editing_layer = Layer.objects.get(name='editing_layer')
        constraint_layer = Layer.objects.get(name=self.constraint_layer_name)
        constraint = GeoConstraint(
            layer=editing_layer, constraint_layer=constraint_layer)
        constraint.save()
        rule = GeoConstraintRule(constraint=constraint,
                              user=self.test_user1, rule='int_f=1')
        self.assertTrue(rule.validate_sql()[0], rule.validate_sql()[1])

        rule.rule = 'dfs?Adfasdfs[đß+èèfsd+'
        self.assertFalse(rule.validate_sql()[0])
Example #5
0
    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())
        except Layer.DoesNotExist:
            QgsMessageLog.logMessage(
                "SingleLayerExpressionAccessControlFilter for user %s: layer id %s does not exist!"
                % (QGS_SERVER.user, layer.id()), "", Qgis.Warning)
            return ""

        rule = GeoConstraintRule.get_rule_definition_for_user(
            QGS_SERVER.user, qdjango_layer)
        if rule:
            QgsMessageLog.logMessage(
                "SingleLayerExpressionAccessControlFilter rule for user %s and layer id %s: %s"
                % (QGS_SERVER.user, layer.id(), rule), "", Qgis.Info)

        return rule
Example #6
0
    def apply_filter(self, request, qgis_layer, qgis_feature_request, view):

        rule_parts = []

        rules = GeoConstraintRule.get_active_constraints_for_user(
            request.user, view.layer, context=getattr(view, 'context', 'v'))

        for rule in rules:
            expression = rule.get_qgis_expression()
            if expression:
                rule_parts.append(expression)

        if rule_parts:
            expression = ' AND '.join(rule_parts)
            current_expression = qgis_feature_request.filterExpression()

            if current_expression:
                expression = f'({current_expression.expression()}) AND ({expression})'

            qgis_feature_request.setFilterExpression(expression)
Example #7
0
    def test_editing_view_insert_data(self):
        """Test constraint filter for editing API - INSERT"""

        client = APIClient()
        editing_layer = Layer.objects.get(name='editing_layer')
        self.assertTrue(
            client.login(username=self.test_user2.username,
                         password=self.test_user2.username))
        assign_perm('change_layer', self.test_user2, editing_layer)
        self.assertTrue(
            self.test_user2.has_perm('qdjango.change_layer', editing_layer))

        # Now add a constraint for user2: strict for editing
        constraint_layer = Layer.objects.get(name=self.constraint_layer_name)
        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer,
                                   for_editing=True,
                                   for_view=False)
        constraint.save()
        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user2,
                                 rule='name=\'bagnolo\'')
        rule.save()

        # Retrieve the data
        response = client.post(
            '/vector/api/editing/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id), {},
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        fids = [int(f['id']) for f in jcontent['vector']['data']['features']]
        # All fids should be here
        self.assertEqual(fids, [1, 2])

        # Get lock id for fid 1
        lock_id = [
            l['lockid'] for l in jcontent['featurelocks']
            if l['featureid'] == '1'
        ][0]

        # Add the geometry outside the allowed rule
        new_geom = [10, 55]
        payload = {
            "add": [{
                "geometry": {
                    "coordinates": new_geom,
                    "type": "Point"
                },
                "id": "_new_1564320704661",
                "properties": {
                    "name": "constraint violation"
                },
                "type": "Feature"
            }],
            "delete": [],
            "lockids": [{
                "featureid": "1",
                "lockid": "%s" % lock_id
            }],
            "relations": {},
            "update": []
        }

        # Verify that the update has failed
        response = client.post(
            '/vector/api/commit/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id),
            payload,
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        self.assertEqual(
            jcontent["errors"],
            "Constraint validation failed for geometry: POINT (10 55)")

        # Test with inactive constraint
        constraint.active = False
        constraint.save()
        # Add the geometry outside the allowed rule
        new_geom = [10, 55]
        payload = {
            "add": [{
                "geometry": {
                    "coordinates": new_geom,
                    "type": "Point"
                },
                "id": "_new_1564320704661",
                "properties": {
                    "name": "constraint violation"
                },
                "type": "Feature"
            }],
            "delete": [],
            "lockids": [{
                "featureid": "1",
                "lockid": "%s" % lock_id
            }],
            "relations": {},
            "update": []
        }

        # Verify that the update was successful
        response = client.post(
            '/vector/api/commit/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id),
            payload,
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        new_fid = int(jcontent['response']['new'][0]['id'])
        self.assertTrue(new_fid > 0)
        # Retrieve the data
        response = client.post(
            '/vector/api/editing/qdjango/%s/%s/' %
            (editing_layer.project_id, editing_layer.qgs_layer_id), {},
            format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        geom = jcontent['vector']['data']['features'][-1]['geometry'][
            'coordinates']
        self.assertEqual(geom, [10, 55])
        self.assertEqual(jcontent['vector']['data']['features'][-1]['id'],
                         str(new_fid))

        # reset test db
        self.reset_db_data()
Example #8
0
    def test_unique(self):
        """Check unique together conditions"""

        editing_layer = Layer.objects.get(name='editing_layer')
        constraint_layer = Layer.objects.get(name=self.constraint_layer_name)
        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer)
        constraint.save()

        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user1,
                                 rule='int_f=1')
        rule.save()

        # Check unique_together
        with transaction.atomic():
            with self.assertRaises(IntegrityError) as ex:
                rule_duplicate = GeoConstraintRule(constraint=constraint,
                                                   user=self.test_user1,
                                                   rule='int_f=1')
                rule_duplicate.save()

        rule3 = GeoConstraintRule(constraint=constraint,
                                  group=self.group,
                                  rule='int_f=1')
        rule3.save()
        with transaction.atomic():
            with self.assertRaises(IntegrityError) as ex:
                rule3_duplicate = GeoConstraintRule(constraint=constraint,
                                                    group=self.group,
                                                    rule='int_f=1')
                rule3_duplicate.save()
Example #9
0
    def test_create_constraint(self):
        """Test constraints creation"""

        editing_layer = Layer.objects.get(name='editing_layer')
        constraint_layer = Layer.objects.get(name=self.constraint_layer_name)
        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer)
        # Test validation
        constraint.clean()
        constraint.save()

        # Check layer types (PG or SL)
        with self.assertRaises(ValidationError) as ex:
            GeoConstraint(layer=editing_layer,
                          constraint_layer=Layer(layer_type='GDAL')).clean()

        with self.assertRaises(ValidationError) as ex:
            GeoConstraint(layer=Layer(layer_type='GDAL'),
                          constraint_layer=constraint_layer).clean()

        # Check if constraints layer is polygon
        with self.assertRaises(ValidationError) as ex:
            GeoConstraint(layer=constraint_layer,
                          constraint_layer=editing_layer).clean()

        # Check self constraint
        with self.assertRaises(ValidationError) as ex:
            GeoConstraint(layer=constraint_layer,
                          constraint_layer=constraint_layer).clean()

        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user1,
                                 rule='int_f=1')
        rule.save()

        # Test validation
        with self.assertRaises(ValidationError) as ex:
            rule2 = GeoConstraintRule(constraint=constraint,
                                      user=self.test_user1,
                                      group=self.group,
                                      rule='int_f=1')
            rule2.clean()

        # Test constraints for user
        rules = GeoConstraintRule.get_constraints_for_user(
            self.test_user1, editing_layer)
        self.assertEqual(len(rules), 1)
        self.assertEqual(rules[0], rule)

        # Test the other path with group
        rule3 = GeoConstraintRule(constraint=constraint,
                                  group=self.group,
                                  rule='int_f=1')
        rule3.save()
        rules = GeoConstraintRule.get_constraints_for_user(
            self.test_user3, editing_layer)
        self.assertEqual(len(rules), 1)
        self.assertEqual(rules[0], rule3)

        # Test we need a user OR a group
        with self.assertRaises(ValidationError) as ex:
            rule4 = GeoConstraintRule(constraint=constraint, rule='int_f=1')
            rule4.clean()

        # Test we get nothing for the other layer and user
        rules = GeoConstraintRule.get_constraints_for_user(
            self.test_user2, constraint_layer)
        self.assertEqual(len(rules), 0)

        # Test inactive constraints for user
        constraint.active = False
        constraint.save()
        rules = GeoConstraintRule.get_constraints_for_user(
            self.test_user3, editing_layer)
        self.assertEqual(len(rules), 1)
        self.assertEqual(rules[0], rule3)
        rules = GeoConstraintRule.get_active_constraints_for_user(
            self.test_user3, editing_layer)
        self.assertEqual(len(rules), 0)
Example #10
0
    def test_trace_api(self):
        """/qplotly/api/trace API"""

        qplotlywidget_id = QplotlyWidget.objects.all()[0].pk
        qplotlywidget_3857_id = QplotlyWidget.objects.all()[1].pk

        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project.instance.pk, qplotlywidget_id])

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 51)
        self.assertIn('Italia', trace_data[0]['x'])

        # for 3857 projetc
        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project_3857.instance.pk, qplotlywidget_3857_id])

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 51)
        self.assertIn('Italia', trace_data[0]['x'])

        # With a session token filter
        # ---------------------------

        countries = Layer.objects.get(
            project_id=self.project.instance.pk,
            qgs_layer_id='countries_d53dfb9a_98e1_4196_a601_eed9a33f47c3')

        # create a token filter
        session_token = SessionTokenFilter.objects.create(
            user=self.test_user1)  # as admin01
        session_filter = session_token.stf_layers.create(
            layer=countries, qgs_expr="NAME_IT = 'Albania'")

        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project.instance.pk, qplotlywidget_id],
            kwargs={'filtertoken': session_token.token})

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 1)
        self.assertNotIn('Italia', trace_data[0]['x'])

        # Geometry contraint layer
        # ------------------------
        constraint = SingleLayerConstraint(layer=countries, active=True)
        constraint.save()

        rule = ConstraintExpressionRule(
            constraint=constraint,
            user=self.test_user1,
            rule=
            "intersects_bbox( $geometry,  geom_from_wkt( 'POLYGON((8 51, 11 51, 11 52, 11 52, 8 51))') )"
        )
        rule.save()

        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project.instance.pk, qplotlywidget_id])

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 1)
        self.assertIn('Germania', trace_data[0]['x'])

        # add new plotly widget for cities layer
        # ======================================
        cities = self.project.instance.layer_set.get(
            qgs_layer_id='cities10000eu_399beab0_e385_4ce1_9b59_688d02930517')
        widget = QplotlyWidget.objects.create(
            xml=self.cities_histogram_plot_xml,
            datasource=cities.datasource,
            type='histogram',
            title='',
            project=self.project.instance)

        widget.layers.add(cities)

        cities_3857 = self.project_3857.instance.layer_set.get(
            qgs_layer_id='cities10000eu_399beab0_e385_4ce1_9b59_688d02930517')
        widget_3857 = QplotlyWidget.objects.create(
            xml=self.cities_histogram_plot_xml,
            datasource=cities_3857.datasource,
            type='histogram',
            title='',
            project=self.project_3857.instance)

        widget_3857.layers.add(cities_3857)

        response = self._testApiCall(
            'qplotly-api-trace', args=[self.project.instance.pk, widget.pk])

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 8965)
        self.assertIn('IT', trace_data[0]['x'])
        self.assertIn('DE', trace_data[0]['x'])

        # check relation one to many
        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project.instance.pk, widget.pk],
            kwargs={
                'relationonetomany':
                'cities1000_ISO2_CODE_countries__ISOCODE|18'
            })

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 1124)
        self.assertIn('IT', trace_data[0]['x'])
        self.assertNotIn('DE', trace_data[0]['x'])

        # test in_bbox filter
        # -------------------------------------

        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project.instance.pk, widget.pk],
            kwargs={'in_bbox': '9.7,41.4,13.0,45.6'})

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 329)
        self.assertIn('IT', trace_data[0]['x'])
        self.assertNotIn('DE', trace_data[0]['x'])

        # for 3857 and reproject
        response = self._testApiCall(
            'qplotly-api-trace',
            args=[self.project_3857.instance.pk, widget_3857.pk],
            kwargs={
                'in_bbox':
                '1079799.06069475435651839,5071521.81142560951411724,1447153.38031255709938705,5716479.01532683055847883'
            })

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 329)
        self.assertIn('IT', trace_data[0]['x'])
        self.assertNotIn('DE', trace_data[0]['x'])

        # Geocontraint
        # ------------------------
        constraint = GeoConstraint(layer=cities,
                                   constraint_layer=countries,
                                   active=True)
        constraint.save()

        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user1,
                                 rule="ISOCODE = 'IT'")
        rule.save()

        response = self._testApiCall(
            'qplotly-api-trace', args=[self.project.instance.pk, widget.pk])

        jcontent = json.loads(response.content)
        trace_data = json.loads(response.content)['data']

        self.assertEqual(len(trace_data), 1)
        self.assertEqual(trace_data[0]['type'], 'histogram')
        self.assertEqual(len(trace_data[0]['x']), 1115)
        self.assertIn('IT', trace_data[0]['x'])
        self.assertNotIn('DE', trace_data[0]['x'])

        widget.delete()
Example #11
0
    def test_initconfig_plugin_start(self):
        """ Test initconfig api"""

        # activate editing plugins: set editing_layer as editing layer
        G3WEditingLayer.objects.create(app_name='qdjango',
                                       layer_id=self.editing_layer.pk)

        # api client instance
        client = APIClient()
        self.assertTrue(
            client.login(username=self.test_user_admin1.username,
                         password=self.test_user_admin1.username))

        url = reverse('group-map-config',
                      args=[
                          self.project_group.slug, 'qdjango',
                          self.project.instance.pk
                      ])

        response = client.get(url)
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)

        # check editing into plugins section
        self.assertTrue('editing' in jcontent['group']['plugins'])

        plugin = jcontent['group']['plugins']['editing']

        # check gid and TYPES
        self.assertEqual(plugin['gid'],
                         'qdjango:{}'.format(self.project.instance.pk))

        client.logout()

        # check for constraint
        # ===================================

        # add constraints
        editing_layer = Layer.objects.get(name='editing_layer')
        constraint_layer = Layer.objects.get(name='constraint_layer')

        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer)
        constraint.save()

        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user3,
                                 rule='name=\'bagnolo\'')
        rule.save()

        self.assertTrue(
            client.login(username=self.test_user3.username,
                         password=self.test_user3.username))

        response = client.get(url)
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)

        # check archiweb into plugins section
        self.assertTrue('editing' in jcontent['group']['plugins'])

        plugin = jcontent['group']['plugins']['editing']

        # check gid and TYPES
        self.assertEqual(plugin['gid'],
                         'qdjango:{}'.format(self.project.instance.pk))

        self.assertTrue('constraints' in plugin)
        self.assertEqual(
            plugin['constraints'][editing_layer.qgs_layer_id]
            ['geometry_api_url'],
            reverse('geoconstraint-api-geometry',
                    kwargs={'layer_id': editing_layer.pk}))

        constraint.delete()
Example #12
0
    def test_constraintrule_api_permissions(self):
        """Test API constraint rule permissions"""

        client = APIClient()
        self.assertTrue(
            client.login(username=self.test_user1.username,
                         password=self.test_user1.username))

        editing_layer = Layer.objects.get(name='editing_layer')
        constraint_layer = Layer.objects.get(name='constraint_layer')
        constraint = GeoConstraint(layer=editing_layer,
                                   constraint_layer=constraint_layer)
        constraint.save()

        rule = GeoConstraintRule(constraint=constraint,
                                 user=self.test_user3,
                                 group=None,
                                 rule="name='pinerolo'")
        rule.save()

        # check 403 for rule list by constraint
        url = reverse('geoconstraintrule-api-filter-by-constraint',
                      kwargs={'constraint_id': constraint.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 403)

        # check 403 for rule list by editing layer
        url = reverse('geoconstraintrule-api-filter-by-layer',
                      kwargs={'layer_id': editing_layer.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 403)

        # check 403 for rule list by rule user
        url = reverse('geoconstraintrule-api-filter-by-user',
                      kwargs={'user_id': self.test_user3.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 403)

        # check 403 for rule detail
        url = reverse('geoconstraintrule-api-detail', kwargs={'pk': rule.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 403)

        # check pass for rule list by constraint
        client.logout()
        self.assertTrue(
            client.login(username=self.test_user2.username,
                         password=self.test_user2.username))

        url = reverse('geoconstraintrule-api-filter-by-constraint',
                      kwargs={'constraint_id': constraint.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 200)

        # check 200 for rule list by editing layer
        url = reverse('geoconstraintrule-api-filter-by-layer',
                      kwargs={'layer_id': editing_layer.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 200)

        # check 403 for rule list by rule user (only admin can query rules by user)
        url = reverse('geoconstraintrule-api-filter-by-user',
                      kwargs={'user_id': self.test_user3.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 403)

        # check 200 for rule detail
        url = reverse('geoconstraintrule-api-detail', kwargs={'pk': rule.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 200)

        client.logout()

        self.assertTrue(
            client.login(username=self.test_user3.username,
                         password=self.test_user3.username))
        # Test get Geometries constraint for request user
        url = reverse('geoconstraint-api-geometry',
                      kwargs={'layer_id': editing_layer.pk})
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        self.assertTrue(len(jcontent['geometries']) == 1)
        self.assertEqual(jcontent['geometries'][0]['type'], 'MultiPolygon')

        client.logout()
        self.assertTrue(
            client.login(username=self.test_user_admin1.username,
                         password=self.test_user_admin1.username))
        response = client.get(url, {}, format='json')
        self.assertEqual(response.status_code, 200)
        jcontent = json.loads(response.content)
        self.assertTrue(len(jcontent['geometries']) == 0)
Example #13
0
def set_initconfig_value(sender, **kwargs):
    """
    Set base editing data for initconfig
    """
    Project = apps.get_app_config(kwargs['projectType']).get_model('project')
    project_layers = {
        pl.pk: pl
        for pl in Project.objects.get(pk=kwargs['project']).layer_set.all()
    }

    # get every layer editable for the project, il list == 0 return
    layers_to_edit = G3WEditingLayer.objects.filter(
        app_name=kwargs['projectType'])
    editable_layers_id = []
    editable_layers_constraints = {}
    for el in layers_to_edit:

        # check for permissions
        if el.layer_id in project_layers and sender.request.user.has_perm(
                'change_layer', project_layers[el.layer_id]):
            editable_layers_id.append(el.layer_id)

            # check if layers has constraints
            constraints = GeoConstraintRule.get_constraints_for_user(
                sender.request.user, project_layers[el.layer_id])
            envelope = []
            for constraint in constraints:
                geom = constraint.get_constraint_geometry()
                if geom[1] > 0:
                    env = geom[0].envelope
                    xmin, ymin = env[0][0]
                    xmax, ymax = env[0][2]
                    if 'xmin' in envelope and xmin > envelope['xmin']:
                        xmin = envelope['xmin']
                    if 'ymin' in envelope and ymin > envelope['ymin']:
                        ymin = envelope['ymin']
                    if 'xmax' in envelope and xmax < envelope['xmax']:
                        xmax = envelope['xmax']
                    if 'ymax' in envelope and ymax < envelope['ymax']:
                        ymax = envelope['ymax']
                    envelope = [xmin, ymin, xmax, ymax]

            if len(envelope) > 0:
                # FIXME: if qgs_layer_id is not unique it shouldn't be used as a key here:
                editable_layers_constraints.update({
                    project_layers[el.layer_id].qgs_layer_id: {
                        'geometry_api_url':
                        reverse('geoconstraint-api-geometry',
                                kwargs={'layer_id': el.layer_id}),
                        'bbox':
                        envelope
                    }
                })

    if len(editable_layers_id) == 0:
        return None

    toret = {
        'editing': {
            'gid': "{}:{}".format(kwargs['projectType'], kwargs['project']),
        },
    }

    if len(editable_layers_constraints) > 0:
        toret['editing']['constraints'] = editable_layers_constraints

    return toret