# HG changeset patch # User Goffi # Date 1614457232 -3600 # Node ID b5e1e8d93dd4e7cb71bcec985952b1bdc368152f # Parent 454f61a32427e2782a64370522b3123d0cf09e78 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. diff -r 454f61a32427 -r b5e1e8d93dd4 db/pubsub.sql --- 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', diff -r 454f61a32427 -r b5e1e8d93dd4 db/sat_pubsub_update_7_8.sql --- /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'; diff -r 454f61a32427 -r b5e1e8d93dd4 sat_pubsub/backend.py --- 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 diff -r 454f61a32427 -r b5e1e8d93dd4 sat_pubsub/const.py --- 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' diff -r 454f61a32427 -r b5e1e8d93dd4 sat_pubsub/pgsql_storage.py --- 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],