comparison sat_pubsub/backend.py @ 422:c21f31355ab9

configuration: "max_items" option: "max_items" is implemented using a text-single field, as it is done in the XEP-0060 example (there is no real formal description). When changing the node configuration, the max_items can't be set to a number lower than the total number of items in the node (the configuration will then be rejected), this is to avoid accidental deletion of items.
author Goffi <goffi@goffi.org>
date Tue, 10 Mar 2020 11:11:38 +0100
parents 794593086517
children 5a0ada3b61ca
comparison
equal deleted inserted replaced
421:f124ed5ea78b 422:c21f31355ab9
136 136
137 nodeOptions = { 137 nodeOptions = {
138 const.OPT_PERSIST_ITEMS: 138 const.OPT_PERSIST_ITEMS:
139 {"type": "boolean", 139 {"type": "boolean",
140 "label": "Persist items to storage"}, 140 "label": "Persist items to storage"},
141 const.OPT_MAX_ITEMS:
142 {"type": "text-single",
143 "label": 'number of items to keep ("max" for unlimited)'},
141 const.OPT_DELIVER_PAYLOADS: 144 const.OPT_DELIVER_PAYLOADS:
142 {"type": "boolean", 145 {"type": "boolean",
143 "label": "Deliver payloads with event notifications"}, 146 "label": "Deliver payloads with event notifications"},
144 const.OPT_SEND_LAST_PUBLISHED_ITEM: 147 const.OPT_SEND_LAST_PUBLISHED_ITEM:
145 {"type": "list-single", 148 {"type": "list-single",
668 if not nodeIdentifier: 671 if not nodeIdentifier:
669 return defer.fail(error.NoRootNode()) 672 return defer.fail(error.NoRootNode())
670 673
671 d = self.storage.getNode(nodeIdentifier, pep, recipient) 674 d = self.storage.getNode(nodeIdentifier, pep, recipient)
672 d.addCallback(_getAffiliation, requestor) 675 d.addCallback(_getAffiliation, requestor)
673 d.addCallback(self._doSetNodeConfiguration, requestor, options) 676 d.addCallback(
674 return d 677 lambda result: defer.ensureDeferred(
675 678 self._doSetNodeConfiguration(result, requestor, options))
676 def _doSetNodeConfiguration(self, result, requestor, options): 679 )
680 return d
681
682 async def _doSetNodeConfiguration(self, result, requestor, options):
677 node, affiliation = result 683 node, affiliation = result
678 684
679 if affiliation != 'owner' and not self.isAdmin(requestor): 685 if affiliation != 'owner' and not self.isAdmin(requestor):
680 raise error.Forbidden() 686 raise error.Forbidden()
681 687
682 return node.setConfiguration(options) 688 max_items = options.get(const.OPT_MAX_ITEMS, '').strip().lower()
689 if not max_items:
690 pass
691 elif max_items == 'max':
692 # FIXME: we use "0" for max for now, but as "0" may be used as legal value
693 # in XEP-0060 ("max" is used otherwise), we should use "None" instead.
694 # This require a schema update, as NULL is not allowed at the moment
695 options.fields[const.OPT_MAX_ITEMS].value = "0"
696 else:
697 # max_items is a number, we have to check that it's not bigger than the
698 # total number of items on this node
699 try:
700 max_items = int(max_items)
701 except ValueError:
702 raise error.InvalidConfigurationValue('Invalid "max_items" value')
703 else:
704 options.fields[const.OPT_MAX_ITEMS].value = str(max_items)
705 if max_items:
706 items_count = await node.getItemsCount(None, True)
707 if max_items < items_count:
708 raise error.ConstraintFailed(
709 "\"max_items\" can't be set to a value lower than the total "
710 "number of items on this node. Please increase \"max_items\" "
711 "or delete items from this node")
712
713 return await node.setConfiguration(options)
683 714
684 def getNodeSchema(self, nodeIdentifier, pep, recipient): 715 def getNodeSchema(self, nodeIdentifier, pep, recipient):
685 if not nodeIdentifier: 716 if not nodeIdentifier:
686 return defer.fail(error.NoRootNode()) 717 return defer.fail(error.NoRootNode())
687 718