diff --git a/backend/geonature/core/notifications/models.py b/backend/geonature/core/notifications/models.py index c41fdf846b..849535477f 100644 --- a/backend/geonature/core/notifications/models.py +++ b/backend/geonature/core/notifications/models.py @@ -3,10 +3,13 @@ """ import datetime +from math import perm +from geonature.core.gn_commons.models.base import TModules +from geonature.core.gn_permissions.models import PermAction, PermObject +from geonature.core.gn_permissions.tools import get_user_permissions import sqlalchemy as sa from sqlalchemy import ForeignKey -from sqlalchemy.sql import select from sqlalchemy.orm import relationship from flask import g from utils_flask_sqla.models import qfilter @@ -44,6 +47,26 @@ class NotificationCategory(db.Model): label = db.Column(db.Unicode) description = db.Column(db.UnicodeText) + id_module = db.Column(db.Integer, ForeignKey("gn_commons.t_modules.id_module")) + module = relationship(TModules) + id_object = db.Column(db.Integer, ForeignKey("gn_permissions.t_objects.id_object")) + object = relationship(PermObject) + id_action = db.Column(db.Integer, ForeignKey("gn_permissions.bib_actions.id_action")) + action = relationship(PermAction) + + def is_allowed(self, user=None) -> bool: + if user is None: + user = g.current_user + id_role = user.id_role + permissions = get_user_permissions(id_role) + if self.id_module: + permissions = [p for p in permissions if p.id_module == self.id_module] + if self.id_object: + permissions = [p for p in permissions if p.id_object == self.id_object] + if self.id_action: + permissions = [p for p in permissions if p.id_action == self.id_action] + return bool(permissions) + @property def display(self): if self.label: diff --git a/backend/geonature/core/notifications/routes.py b/backend/geonature/core/notifications/routes.py index 3aff7f97f3..fbcc70f634 100644 --- a/backend/geonature/core/notifications/routes.py +++ b/backend/geonature/core/notifications/routes.py @@ -1,5 +1,3 @@ -import json - import logging from flask import ( @@ -193,17 +191,19 @@ def list_notification_methods(): @routes.route("/categories", methods=["GET"]) @permissions.login_required def list_notification_categories(): - notificationCategories = db.session.scalars( + categories = db.session.scalars( select(NotificationCategory).order_by(NotificationCategory.code.asc()) ).all() - result = [ - notificationsCategory.as_dict( - fields=[ - "code", - "label", - "description", - ] - ) - for notificationsCategory in notificationCategories - ] - return jsonify(result) + categories = [category for category in categories if category.is_allowed()] + return jsonify( + [ + category.as_dict( + fields=[ + "code", + "label", + "description", + ] + ) + for category in categories + ] + ) diff --git a/backend/geonature/migrations/versions/0bea266db3ec_hide_unauthorized_notifications.py b/backend/geonature/migrations/versions/0bea266db3ec_hide_unauthorized_notifications.py new file mode 100644 index 0000000000..460d7267b4 --- /dev/null +++ b/backend/geonature/migrations/versions/0bea266db3ec_hide_unauthorized_notifications.py @@ -0,0 +1,75 @@ +"""hide unauthorized notifications categories + +Revision ID: 0bea266db3ec +Revises: 7b6a578eccd7 +Create Date: 2024-11-20 17:23:42.017660 + +""" + +from alembic import op +import sqlalchemy as sa +from sqlalchemy.sql import column + + +# revision identifiers, used by Alembic. +revision = "0bea266db3ec" +down_revision = "7b6a578eccd7" +branch_labels = None +depends_on = None + + +def upgrade(): + op.add_column( + schema="gn_notifications", + table_name="bib_notifications_categories", + column=sa.Column( + "id_module", + sa.Integer, + sa.ForeignKey("gn_commons.t_modules.id_module"), + ), + ) + op.add_column( + schema="gn_notifications", + table_name="bib_notifications_categories", + column=sa.Column( + "id_object", + sa.Integer, + sa.ForeignKey("gn_permissions.t_objects.id_object"), + ), + ) + op.add_column( + schema="gn_notifications", + table_name="bib_notifications_categories", + column=sa.Column( + "id_action", + sa.Integer, + sa.ForeignKey("gn_permissions.bib_actions.id_action"), + ), + ) + op.execute( + """ + UPDATE gn_notifications.bib_notifications_categories + SET + id_module = (SELECT id_module FROM gn_commons.t_modules WHERE module_code = 'IMPORT'), + id_object = (SELECT id_object FROM gn_permissions.t_objects WHERE code_object = 'IMPORT') + WHERE code = 'IMPORT-DONE' + """ + ) + + +def downgrade(): + op.drop_column( + table_name="bib_notifications_categories", + column_name="id_action", + schema="gn_notifications", + ) + op.drop_column( + table_name="bib_notifications_categories", + column_name="id_object", + schema="gn_notifications", + ) + op.drop_column( + table_name="bib_notifications_categories", + column_name="id_module", + schema="gn_notifications", + ) diff --git a/backend/geonature/migrations/versions/95acee9f0452_add_comment_notification.py b/backend/geonature/migrations/versions/95acee9f0452_add_comment_notification.py index 1ceb659b08..02e755f519 100644 --- a/backend/geonature/migrations/versions/95acee9f0452_add_comment_notification.py +++ b/backend/geonature/migrations/versions/95acee9f0452_add_comment_notification.py @@ -9,12 +9,6 @@ import sqlalchemy as sa from alembic import op -from geonature.core.notifications.models import ( - NotificationCategory, - NotificationRule, - NotificationTemplate, -) - # revision identifiers, used by Alembic. revision = "95acee9f0452" down_revision = "e2a94808cf76" @@ -36,34 +30,45 @@ def upgrade(): - bind = op.get_bind() - session = sa.orm.Session(bind=bind) + conn = op.get_bind() + metadata = sa.MetaData(bind=conn) # Add category - category = NotificationCategory( - code=CATEGORY_CODE, - label="Nouveau commentaire sur une observation", - description=( - "Se déclenche lorsqu'un nouveau commentaire est ajouté à une de vos observations, ou une observation que vous avez commenté" - ), + notification_category = sa.Table( + "bib_notifications_categories", metadata, schema="gn_notifications", autoload_with=conn + ) + op.execute( + sa.insert(notification_category).values( + { + "code": CATEGORY_CODE, + "label": "Nouveau commentaire sur une observation", + "description": "Se déclenche lorsqu'un nouveau commentaire est ajouté à une de vos observations, ou une observation que vous avez commenté", + } + ) ) - session.add(category) - - for method, content in (("EMAIL", EMAIL_CONTENT), ("DB", DB_CONTENT)): - template = NotificationTemplate(category=category, code_method=method, content=content) - session.add(template) - - session.commit() + notification_template = sa.Table( + "bib_notifications_templates", metadata, schema="gn_notifications", autoload_with=conn + ) + op.execute( + sa.insert(notification_template).values( + [ + {"code_category": CATEGORY_CODE, "code_method": "EMAIL", "content": EMAIL_CONTENT}, + {"code_category": CATEGORY_CODE, "code_method": "DB", "content": DB_CONTENT}, + ] + ) + ) + notification_rule = sa.Table( + "t_notifications_rules", metadata, schema="gn_notifications", autoload_with=conn + ) op.execute( - f""" - INSERT INTO - gn_notifications.t_notifications_rules (code_category, code_method) - VALUES - ('{CATEGORY_CODE}', 'DB'), - ('{CATEGORY_CODE}', 'EMAIL') - """ + sa.insert(notification_rule).values( + [ + {"code_category": CATEGORY_CODE, "code_method": "EMAIL"}, + {"code_category": CATEGORY_CODE, "code_method": "DB"}, + ] + ) )