diff --git a/backend/geonature/core/gn_permissions/admin.py b/backend/geonature/core/gn_permissions/admin.py index 01f19b80a5..caaa2dab2a 100644 --- a/backend/geonature/core/gn_permissions/admin.py +++ b/backend/geonature/core/gn_permissions/admin.py @@ -3,7 +3,7 @@ from geonature.utils.env import db from geonature.core.admin.admin import admin from geonature.core.admin.utils import CruvedProtectedMixin -from geonature.core.gn_permissions.models import PermObject, Permission +from geonature.core.gn_permissions.models import PermObject, Permission, PermissionAvailable class ObjectAdmin(CruvedProtectedMixin, ModelView): @@ -37,6 +37,21 @@ class PermissionAdmin(CruvedProtectedMixin, ModelView): } +class PermissionAvailableAdmin(CruvedProtectedMixin, ModelView): + module_code = "ADMIN" + object_code = "PERMISSIONS" + + column_labels = { + "scope": "Portée", + "object": "Objet", + "scope_filter": "Filtre appartenance", + } + column_formatters = { + "module": lambda v, c, m, p: m.module.module_code, + "object": lambda v, c, m, p: m.object.code_object, + } + + admin.add_view( ObjectAdmin( PermObject, @@ -55,3 +70,13 @@ class PermissionAdmin(CruvedProtectedMixin, ModelView): category="Permissions", ) ) + + +admin.add_view( + PermissionAvailableAdmin( + PermissionAvailable, + db.session, + name="Permissions disponibles", + category="Permissions", + ) +) diff --git a/backend/geonature/core/gn_permissions/models.py b/backend/geonature/core/gn_permissions/models.py index 67a14e942d..d0bbdf75bb 100644 --- a/backend/geonature/core/gn_permissions/models.py +++ b/backend/geonature/core/gn_permissions/models.py @@ -2,8 +2,10 @@ Models of gn_permissions schema """ +import sqlalchemy as sa from sqlalchemy import ForeignKey from sqlalchemy.sql import select +from sqlalchemy.orm import foreign from utils_flask_sqla.serializers import serializable from pypnusershub.db.models import User @@ -82,6 +84,31 @@ def __str__(self): TObjects = PermObject +class PermissionAvailable(db.Model): + __tablename__ = "t_permissions_available" + __table_args__ = {"schema": "gn_permissions"} + id_module = db.Column( + db.Integer, ForeignKey("gn_commons.t_modules.id_module"), primary_key=True + ) + id_object = db.Column( + db.Integer, + ForeignKey(PermObject.id_object), + default=select([PermObject.id_object]).where(PermObject.code_object == "ALL"), + primary_key=True, + ) + id_action = db.Column(db.Integer, ForeignKey(PermAction.id_action), primary_key=True) + label = db.Column(db.Unicode) + + module = db.relationship("TModules") + object = db.relationship(PermObject) + action = db.relationship(PermAction) + + scope_filter = db.Column(db.Boolean, server_default=sa.false()) + + def __str__(self): + return self.label + + @serializable class Permission(db.Model): __tablename__ = "t_permissions" @@ -104,6 +131,15 @@ class Permission(db.Model): scope_value = db.Column(db.Integer, ForeignKey(PermScope.value), nullable=True) scope = db.relationship(PermScope) + availability = db.relationship( + PermissionAvailable, + primaryjoin=sa.and_( + foreign(id_module) == PermissionAvailable.id_module, + foreign(id_object) == PermissionAvailable.id_object, + foreign(id_action) == PermissionAvailable.id_action, + ), + ) + def has_other_filters_than(self, *args): if scope_value is not None and "SCOPE" not in args: return True diff --git a/backend/geonature/migrations/versions/f051b88a57fd_permissions_available.py b/backend/geonature/migrations/versions/f051b88a57fd_permissions_available.py new file mode 100644 index 0000000000..d8af00391c --- /dev/null +++ b/backend/geonature/migrations/versions/f051b88a57fd_permissions_available.py @@ -0,0 +1,104 @@ +"""permissions available + +Revision ID: f051b88a57fd +Revises: 7fe46b0e4729 +Create Date: 2023-04-14 17:19:36.490766 + +""" +from alembic import op +import sqlalchemy as sa +from sqlalchemy.types import Integer, Boolean, Unicode + + +# revision identifiers, used by Alembic. +revision = "f051b88a57fd" +down_revision = "7fe46b0e4729" +branch_labels = None +depends_on = None + + +def upgrade(): + op.create_table( + "t_permissions_available", + sa.Column( + "id_module", + Integer, + sa.ForeignKey("gn_commons.t_modules.id_module"), + primary_key=True, + ), + sa.Column( + "id_object", + Integer, + sa.ForeignKey("gn_permissions.t_objects.id_object"), + primary_key=True, + ), + sa.Column( + "id_action", + Integer, + sa.ForeignKey("gn_permissions.bib_actions.id_action"), + primary_key=True, + ), + sa.Column( + "label", + Unicode, + ), + sa.Column( + "scope_filter", + Boolean, + server_default=sa.false(), + ), + schema="gn_permissions", + ) + op.execute( + """ + INSERT INTO + gn_permissions.t_permissions_available ( + id_module, + id_object, + id_action, + label, + scope_filter + ) + SELECT + m.id_module, + o.id_object, + a.id_action, + v.label, + v.scope_filter + FROM + ( + VALUES + ('ADMIN', 'PERMISSIONS', 'C', False, 'Créer des permissions') + ,('ADMIN', 'PERMISSIONS', 'R', False, 'Voir les permissions') + ,('ADMIN', 'PERMISSIONS', 'U', False, 'Modifier les permissions') + ,('ADMIN', 'PERMISSIONS', 'E', False, 'Exporter les permissions') + ,('ADMIN', 'PERMISSIONS', 'D', False, 'Supprimer des permissions') + ,('ADMIN', 'NOMENCLATURES', 'C', False, 'Créer des nomenclatures') + ,('ADMIN', 'NOMENCLATURES', 'R', False, 'Voir les nomenclatures') + ,('ADMIN', 'NOMENCLATURES', 'U', False, 'Modifier les nomenclatures') + ,('ADMIN', 'NOMENCLATURES', 'E', False, 'Exporter les nomenclatures') + ,('ADMIN', 'NOMENCLATURES', 'D', False, 'Supprimer des nomenclatures') + ,('ADMIN', 'NOTIFICATIONS', 'C', False, 'Créer des entrées dans l’administration des notifications') + ,('ADMIN', 'NOTIFICATIONS', 'R', False, 'Voir les entrées dans l’administration des notifications') + ,('ADMIN', 'NOTIFICATIONS', 'U', False, 'Modifier des entrées dans l’administration des notifications') + ,('ADMIN', 'NOTIFICATIONS', 'E', False, 'Exporter les entrées dans l’administration des notifications') + ,('ADMIN', 'NOTIFICATIONS', 'D', False, 'Supprimer des entrées dans l’administration des notifications') + ,('METADATA', 'ALL', 'C', False, 'Créer des métadonnées') + ,('METADATA', 'ALL', 'R', True, 'Voir les métadonnées') + ,('METADATA', 'ALL', 'U', True, 'Modifier les métadonnées') + ,('METADATA', 'ALL', 'D', True, 'Supprimer des métadonnées') + ,('SYNTHESE', 'ALL', 'R', True, 'Voir les observations') + ,('SYNTHESE', 'ALL', 'E', True, 'Exporter les observations') + ) AS v (module_code, object_code, action_code, scope_filter, label) + JOIN + gn_commons.t_modules m ON m.module_code = v.module_code + JOIN + gn_permissions.t_objects o ON o.code_object = v.object_code + JOIN + gn_permissions.bib_actions a ON a.code_action = v.action_code + """ + ) + + +def downgrade(): + op.drop_table(schema="gn_permissions", table_name="t_permissions_available")