changeset 438:b5e1e8d93dd4

backend, pgsql: new `overwrite_policy` node setting: /!\ pgsql schema needs to be updated /!\ this settings can be set currently to 2 values: - `original_publisher` (default), when only original publisher of an item can overwrite it (except node owner/admin) - `any_publisher` when any entity with publishing right can overwrite any item.
author Goffi <goffi@goffi.org>
date Sat, 27 Feb 2021 21:20:32 +0100
parents 454f61a32427
children 36c9fb677f1d
files db/pubsub.sql db/sat_pubsub_update_7_8.sql sat_pubsub/backend.py sat_pubsub/const.py sat_pubsub/pgsql_storage.py
diffstat 5 files changed, 53 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/db/pubsub.sql	Mon Feb 08 19:01:29 2021 +0100
+++ b/db/pubsub.sql	Sat Feb 27 21:20:32 2021 +0100
@@ -15,6 +15,8 @@
     deliver_payloads boolean NOT NULL DEFAULT TRUE,
     max_items integer NOT NULL DEFAULT 0
         CHECK (max_items >= 0),
+	overwrite_policy text NOT NULL DEFAULT 'original_publisher'
+		CHECK (overwrite_policy IN ('original_publisher', 'any_publisher')),
     serial_ids boolean NOT NULL DEFAULT FALSE,
     consistent_publisher boolean NOT NULL DEFAULT FALSE,
     fts_language text NOT NULL DEFAULT 'generic',
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/db/sat_pubsub_update_7_8.sql	Sat Feb 27 21:20:32 2021 +0100
@@ -0,0 +1,19 @@
+-- we check version of the database before doing anything
+-- and stop execution if not good
+\set ON_ERROR_STOP
+DO $$
+DECLARE ver text;
+BEGIN
+    SELECT value INTO ver FROM metadata WHERE key='version';
+    IF NOT FOUND OR ver!='7' THEN
+        RAISE EXCEPTION 'This update file needs to be applied on database schema version 7, you use version %',ver;
+    END IF;
+END$$;
+\unset ON_ERROR_STOP
+-- end of version check
+
+/* new "overwrite_policy" option */
+ALTER TABLE nodes ADD COLUMN overwrite_policy text NOT NULL DEFAULT 'original_publisher'
+	CHECK (overwrite_policy IN ('original_publisher', 'any_publisher'));
+
+UPDATE metadata SET value='8' WHERE key='version';
--- a/sat_pubsub/backend.py	Mon Feb 08 19:01:29 2021 +0100
+++ b/sat_pubsub/backend.py	Sat Feb 27 21:20:32 2021 +0100
@@ -179,6 +179,14 @@
                      const.VAL_PMODEL_SUBSCRIBERS: "Everybody which subscribed to the node",
                      }
                 },
+            const.OPT_OVERWRITE_POLICY:
+                {"type": "list-single",
+                 "label": "Who can overwrite an item",
+                 "options": {
+                     const.VAL_OWPOL_ORIGINAL: "Only original publisher of the item",
+                     const.VAL_OWPOL_ANY_PUB: "Any publisher",
+                     }
+                },
             const.OPT_SERIAL_IDS:
                 {"type": "boolean",
                  "label": "Use serial ids"},
@@ -408,20 +416,6 @@
             item_form.removeField(field)
         item_elt.addChild(item_form.toElement())
 
-    def _checkOverwrite(self, node, itemIdentifiers, publisher):
-        """Check that publisher can overwrite items
-
-        current publisher must correspond to each item publisher
-        """
-        def doCheck(item_pub_map):
-            for item_publisher in item_pub_map.values():
-                if item_publisher.userhost() != publisher.userhost():
-                    raise error.ItemForbidden()
-
-        d = node.getItemsPublishers(itemIdentifiers)
-        d.addCallback(doCheck)
-        return d
-
     def _getFDPSubmittedNode(
         self,
         nodeIdentifier: str,
@@ -527,10 +521,15 @@
                             requestor = publishers.pop()
                             for item in items:
                                 item['publisher'] = requestor.full()
-                else:
+                elif configuration[const.OPT_OVERWRITE_POLICY] == const.VAL_OWPOL_ORIGINAL:
                     # we don't want a publisher to overwrite the item
                     # of an other publisher
-                    await self._checkOverwrite(node, itemIdentifiers, requestor)
+                    item_pub_map = await node.getItemsPublishers(itemIdentifiers)
+                    for item_publisher in item_pub_map.values():
+                        if item_publisher.userhost() != requestor.userhost():
+                            raise error.ItemForbidden(
+                                "Item can only be overwritten by original publisher"
+                            )
 
             if node.nodeIdentifier.startswith(const.FDP_TEMPLATE_PREFIX):
                 schema_item = items_data[-1].item
--- a/sat_pubsub/const.py	Mon Feb 08 19:01:29 2021 +0100
+++ b/sat_pubsub/const.py	Sat Feb 27 21:20:32 2021 +0100
@@ -69,8 +69,9 @@
 OPT_DELIVER_PAYLOADS = "pubsub#deliver_payloads"
 OPT_SEND_LAST_PUBLISHED_ITEM = "pubsub#send_last_published_item"
 OPT_PUBLISH_MODEL = 'pubsub#publish_model'
+OPT_OVERWRITE_POLICY = "pubsub#overwrite_policy"
+OPT_CONSISTENT_PUBLISHER = 'pubsub#consistent_publisher'
 OPT_SERIAL_IDS = 'pubsub#serial_ids'
-OPT_CONSISTENT_PUBLISHER = 'pubsub#consistent_publisher'
 OPT_FTS_LANGUAGE = 'pubsub#fts_language'
 VAL_AMODEL_OPEN = 'open'
 VAL_AMODEL_PRESENCE = 'presence'
@@ -86,6 +87,9 @@
 VAL_PMODEL_DEFAULT = VAL_PMODEL_PUBLISHERS
 VAL_RSM_MAX_DEFAULT = 10 # None for no limit
 VAL_FTS_GENERIC = 'generic'
+VAL_OWPOL_ORIGINAL = "original_publisher"
+VAL_OWPOL_ANY_PUB = "any_publisher"
+VAL_OWPOL_DEFAUT = VAL_OWPOL_ORIGINAL
 FLAG_ENABLE_RSM = True
 FLAG_ENABLE_MAM = True
 MAM_FILTER_CATEGORY = 'http://salut-a-toi.org/protocols/mam_filter_category'
--- a/sat_pubsub/pgsql_storage.py	Mon Feb 08 19:01:29 2021 +0100
+++ b/sat_pubsub/pgsql_storage.py	Sat Feb 27 21:20:32 2021 +0100
@@ -79,7 +79,7 @@
 parseXml = lambda unicode_data: generic.parseXml(unicode_data.encode('utf-8'))
 ITEMS_SEQ_NAME = 'node_{node_id}_seq'
 PEP_COL_NAME = 'pep'
-CURRENT_VERSION = '7'
+CURRENT_VERSION = '8'
 # retrieve the maximum integer item id + 1
 NEXT_ITEM_ID_QUERY = r"SELECT COALESCE(max(item::integer)+1,1) as val from items where node_id={node_id} and item ~ E'^\\d+$'"
 
@@ -114,6 +114,7 @@
                 const.OPT_SEND_LAST_PUBLISHED_ITEM: 'on_sub',
                 const.OPT_ACCESS_MODEL: const.VAL_AMODEL_DEFAULT,
                 const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_DEFAULT,
+                const.OPT_OVERWRITE_POLICY: const.VAL_OWPOL_DEFAUT,
                 const.OPT_SERIAL_IDS: False,
                 const.OPT_CONSISTENT_PUBLISHER: False,
                 const.OPT_FTS_LANGUAGE: const.VAL_FTS_GENERIC,
@@ -155,11 +156,12 @@
                     const.OPT_SEND_LAST_PUBLISHED_ITEM: row[6],
                     const.OPT_ACCESS_MODEL:row[7],
                     const.OPT_PUBLISH_MODEL:row[8],
-                    const.OPT_SERIAL_IDS:row[9],
-                    const.OPT_CONSISTENT_PUBLISHER:row[10],
-                    const.OPT_FTS_LANGUAGE: row[11],
+                    const.OPT_OVERWRITE_POLICY: row[9],
+                    const.OPT_SERIAL_IDS:row[10],
+                    const.OPT_CONSISTENT_PUBLISHER:row[11],
+                    const.OPT_FTS_LANGUAGE: row[12],
                     }
-            schema = row[12]
+            schema = row[13]
             if schema is not None:
                 schema = parseXml(schema)
             node = LeafNode(row[0], row[1], configuration, schema)
@@ -207,6 +209,7 @@
                                  send_last_published_item,
                                  access_model,
                                  publish_model,
+                                 overwrite_policy,
                                  serial_ids,
                                  consistent_publisher,
                                  fts_language,
@@ -231,6 +234,7 @@
                                           send_last_published_item,
                                           access_model,
                                           publish_model,
+                                          overwrite_policy,
                                           serial_ids,
                                           consistent_publisher,
                                           fts_language,
@@ -286,19 +290,21 @@
                                send_last_published_item,
                                access_model,
                                publish_model,
+                               overwrite_policy,
                                serial_ids,
                                consistent_publisher,
                                fts_language,
                                schema,
                                pep)
                               VALUES
-                              (%s, 'leaf', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
+                              (%s, 'leaf', %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)""",
                            (nodeIdentifier,
                             config['pubsub#persist_items'],
                             config['pubsub#deliver_payloads'],
                             config['pubsub#send_last_published_item'],
                             config[const.OPT_ACCESS_MODEL],
                             config[const.OPT_PUBLISH_MODEL],
+                            config[const.OPT_OVERWRITE_POLICY],
                             config[const.OPT_SERIAL_IDS],
                             config[const.OPT_CONSISTENT_PUBLISHER],
                             config[const.OPT_FTS_LANGUAGE],