Skip to content

Commit

Permalink
feat(synthese): implement taxonomic filters
Browse files Browse the repository at this point in the history
  • Loading branch information
bouttier committed Oct 8, 2024
1 parent 5127edd commit 656d2fb
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 2 deletions.
8 changes: 7 additions & 1 deletion backend/geonature/core/gn_synthese/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -459,7 +459,7 @@ def _has_permissions_grant(self, permissions) -> bool:
if not permissions:
return False
for perm in permissions:
if perm.has_other_filters_than("SCOPE", "SENSITIVITY", "GEOGRAPHIC"):
if perm.has_other_filters_than("SCOPE", "SENSITIVITY", "GEOGRAPHIC", "TAXONOMIC"):
continue # unsupported filters
if perm.sensitivity_filter:
if current_app.config["SYNTHESE"]["BLUR_SENSITIVE_OBSERVATIONS"]:
Expand All @@ -482,6 +482,11 @@ def _has_permissions_grant(self, permissions) -> bool:
if set(perm.areas_filter).isdisjoint(self.areas):
# the permission does not allows any area overlapping the observation areas
continue
if perm.taxons_filter:
if set(map(int, self.taxref.tree.path.split("."))).isdisjoint(
[t.cd_ref for t in perm.taxons_filter]
):
continue
return True # no filter exclude this permission
return False

Expand Down Expand Up @@ -658,6 +663,7 @@ class VSyntheseForWebApp(DB.Model):
secondaryjoin=corAreaSynthese.c.id_area == LAreas.id_area,
overlaps="areas,synthese_obs",
)
taxref = relationship(Taxref, primaryjoin=foreign(cd_nom) == Taxref.cd_nom)
medias = relationship(
TMedias, primaryjoin=(TMedias.uuid_attached_row == foreign(unique_id_sinp)), uselist=True
)
Expand Down
12 changes: 11 additions & 1 deletion backend/geonature/core/gn_synthese/utils/query_select_sqla.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ def build_permissions_filter(self, user, permissions):
permissions_filters = []
excluded_sensitivity = None
for perm in permissions:
if perm.has_other_filters_than("SCOPE", "SENSITIVITY", "GEOGRAPHIC"):
if perm.has_other_filters_than("SCOPE", "SENSITIVITY", "GEOGRAPHIC", "TAXONOMIC"):
continue
perm_filters = []
if perm.sensitivity_filter:
Expand Down Expand Up @@ -193,6 +193,16 @@ def build_permissions_filter(self, user, permissions):
LAreas.id_area.in_([a.id_area for a in perm.areas_filter])
)
perm_filters.append(where_clause)
if perm.taxons_filter:
noms_lqueries = [f"'*.{t.cd_nom}.*'" for t in perm.taxons_filter]
where_clause = self.model.taxref.has(
Taxref.tree.has(
sa.text(
f"taxonomie.vm_taxref_tree.path ? array[{','.join(noms_lqueries)}]::lquery[]"
)
)
)
perm_filters.append(where_clause)
if perm_filters:
permissions_filters.append(and_(*perm_filters))
else:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -88,6 +88,26 @@ def upgrade():
m.module_code = 'SYNTHESE' AND o.code_object = 'ALL' and a.code_action = 'R'
"""
)
op.execute(
"""
UPDATE
gn_permissions.t_permissions_available pa
SET
taxons_filter = True
FROM
gn_commons.t_modules m,
gn_permissions.t_objects o,
gn_permissions.bib_actions a
WHERE
pa.id_module = m.id_module
AND
pa.id_object = o.id_object
AND
pa.id_action = a.id_action
AND
m.module_code = 'SYNTHESE' AND o.code_object = 'ALL' and a.code_action = 'R'
"""
)


def downgrade():
Expand Down
43 changes: 43 additions & 0 deletions backend/geonature/tests/test_synthese.py
Original file line number Diff line number Diff line change
Expand Up @@ -1888,3 +1888,46 @@ def test_geographic_filter_list_obs(self, synthese_data, synthese_read_permissio
assert synthese_data["obs1"].id_synthese in response_ids
assert synthese_data["obs2"].id_synthese not in response_ids
assert synthese_data["obs3"].id_synthese in response_ids


@pytest.mark.usefixtures("client_class", "temporary_transaction")
class TestSyntheseTaxonomicFilter:
def test_taxonomic_filter_get_obs(self, synthese_data, synthese_read_permissions):
with db.session.begin_nested():
user = User()
db.session.add(user)
taxon1 = synthese_data["obs1"].taxref
taxon2 = synthese_data["obs2"].taxref.parent
synthese_read_permissions(user, scope_value=None, taxons_filter=[taxon1, taxon2])
set_logged_user(self.client, user)
response = self.client.get(
url_for("gn_synthese.get_one_synthese", id_synthese=synthese_data["obs1"].id_synthese)
)
assert response.status_code == 200, response.data
response = self.client.get(
url_for("gn_synthese.get_one_synthese", id_synthese=synthese_data["obs2"].id_synthese)
)
assert response.status_code == 200, response.data
response = self.client.get(
url_for("gn_synthese.get_one_synthese", id_synthese=synthese_data["obs3"].id_synthese)
)
assert response.status_code == Forbidden.code, response.data

def test_taxonomic_filter_list_obs(self, synthese_data, synthese_read_permissions):
with db.session.begin_nested():
user = User()
db.session.add(user)
taxon1 = synthese_data["obs1"].taxref
taxon2 = synthese_data["obs2"].taxref.parent
synthese_read_permissions(user, scope_value=None, taxons_filter=[taxon1, taxon2])
set_logged_user(self.client, user)
response = self.client.get(
url_for(
"gn_synthese.get_observations_for_web",
)
)
assert response.status_code == 200, response.data
response_ids = [f["properties"]["id_synthese"] for f in response.json["features"]]
assert synthese_data["obs1"].id_synthese in response_ids
assert synthese_data["obs2"].id_synthese in response_ids
assert synthese_data["obs3"].id_synthese not in response_ids

0 comments on commit 656d2fb

Please sign in to comment.