comparison sat_pubsub/backend.py @ 259:6fe7da6b4b32

node "roster" access model management
author Goffi <goffi@goffi.org>
date Mon, 06 May 2013 00:11:44 +0200
parents e5b83fbb0219
children f0cd02c032b3
comparison
equal deleted inserted replaced
258:e5b83fbb0219 259:6fe7da6b4b32
114 "label": "When to send the last published item", 114 "label": "When to send the last published item",
115 "options": { 115 "options": {
116 "never": "Never", 116 "never": "Never",
117 "on_sub": "When a new subscription is processed"} 117 "on_sub": "When a new subscription is processed"}
118 }, 118 },
119 const.OPT_ACCESS_MODEL:
120 {"type": "list-single",
121 "label": "Who can subscribe to this node",
122 "options": {
123 const.VAL_AMODEL_OPEN: "Public node",
124 const.VAL_AMODEL_ROSTER: "Node restricted to some roster groups",
125 const.VAL_AMODEL_JID: "Node restricted to some jids",
126 }
127 },
128 const.OPT_ROSTER_GROUPS_ALLOWED:
129 {"type": "list-multi",
130 "label": "Groups of the roster allowed to access the node",
131 },
119 } 132 }
120 133
121 subscriptionOptions = { 134 subscriptionOptions = {
122 "pubsub#subscription_type": 135 "pubsub#subscription_type":
123 {"type": "list-single", 136 {"type": "list-single",
197 def parseItemConfig(self, item): 210 def parseItemConfig(self, item):
198 """Get and remove item configuration information 211 """Get and remove item configuration information
199 @param item: 212 @param item:
200 """ 213 """
201 item_config = None 214 item_config = None
202 access_model = const.VAL_DEFAULT 215 access_model = const.VAL_AMODEL_DEFAULT
203 for i in range(len(item.children)): 216 for i in range(len(item.children)):
204 elt = item.children[i] 217 elt = item.children[i]
205 if not (elt.uri,elt.name)==(data_form.NS_X_DATA,'x'): 218 if not (elt.uri,elt.name)==(data_form.NS_X_DATA,'x'):
206 continue 219 continue
207 form = data_form.Form.fromElement(elt) 220 form = data_form.Form.fromElement(elt)
209 item_config = form 222 item_config = form
210 del item.children[i] #we need to remove the config from item 223 del item.children[i] #we need to remove the config from item
211 break 224 break
212 225
213 if item_config: 226 if item_config:
214 access_model = item_config.get(const.OPT_ACCESS_MODEL, const.VAL_DEFAULT) 227 access_model = item_config.get(const.OPT_ACCESS_MODEL, const.VAL_AMODEL_DEFAULT)
215 228
216 return (access_model, item_config) 229 return (access_model, item_config)
217 230
218 231
219 def publish(self, nodeIdentifier, items, requestor): 232 def publish(self, nodeIdentifier, items, requestor):
379 392
380 def supportsInstantNodes(self): 393 def supportsInstantNodes(self):
381 return True 394 return True
382 395
383 396
384 def createNode(self, nodeIdentifier, requestor): 397 def createNode(self, nodeIdentifier, requestor, options = None):
385 if not nodeIdentifier: 398 if not nodeIdentifier:
386 nodeIdentifier = 'generic/%s' % uuid.uuid4() 399 nodeIdentifier = 'generic/%s' % uuid.uuid4()
400
401 if not options:
402 options = {}
387 403
388 if self.supportsCreatorCheck(): 404 if self.supportsCreatorCheck():
389 groupblog = nodeIdentifier.startswith(const.NS_GROUPBLOG_PREFIX) 405 groupblog = nodeIdentifier.startswith(const.NS_GROUPBLOG_PREFIX)
390 try: 406 try:
391 nodeIdentifierJID = JID(nodeIdentifier[len(const.NS_GROUPBLOG_PREFIX):] if groupblog else nodeIdentifier) 407 nodeIdentifierJID = JID(nodeIdentifier[len(const.NS_GROUPBLOG_PREFIX):] if groupblog else nodeIdentifier)
400 raise error.Forbidden() 416 raise error.Forbidden()
401 417
402 nodeType = 'leaf' 418 nodeType = 'leaf'
403 config = self.storage.getDefaultConfiguration(nodeType) 419 config = self.storage.getDefaultConfiguration(nodeType)
404 config['pubsub#node_type'] = nodeType 420 config['pubsub#node_type'] = nodeType
421 config.update(options)
405 422
406 d = self.storage.createNode(nodeIdentifier, requestor, config) 423 d = self.storage.createNode(nodeIdentifier, requestor, config)
407 d.addCallback(lambda _: nodeIdentifier) 424 d.addCallback(lambda _: nodeIdentifier)
408 return d 425 return d
409 426
452 d.addCallback(_getAffiliation, requestor) 469 d.addCallback(_getAffiliation, requestor)
453 d.addCallback(self._doGetItems, requestor, maxItems, itemIdentifiers) 470 d.addCallback(self._doGetItems, requestor, maxItems, itemIdentifiers)
454 return d 471 return d
455 472
456 def checkGroup(self, roster_groups, entity): 473 def checkGroup(self, roster_groups, entity):
457 """Check that requester is in roster 474 """Check that entity is authorized and in roster
458 @param roster_group: tuple which 2 items: 475 @param roster_group: tuple which 2 items:
459 - roster: mapping of jid to RosterItem as given by self.roster.getRoster 476 - roster: mapping of jid to RosterItem as given by self.roster.getRoster
460 - groups: list of authorized groups 477 - groups: list of authorized groups
461 @param entity: entity which must be in group 478 @param entity: entity which must be in group
462 @return: True if requestor is in roster""" 479 @return: (True, roster) if entity is in roster and authorized
480 (False, roster) if entity is in roster but not authorized
481 @raise: error.NotInRoster if entity is not in roster"""
463 roster, authorized_groups = roster_groups 482 roster, authorized_groups = roster_groups
464 _entity = entity.userhostJID() 483 _entity = entity.userhostJID()
465 484
466 if not _entity in roster: 485 if not _entity in roster:
467 raise error.NotInRoster 486 raise error.NotInRoster
468 if roster[_entity].groups.intersection(authorized_groups): 487 return (roster[_entity].groups.intersection(authorized_groups), roster)
469 return (True, roster)
470 raise error.NotInRoster
471 488
472 def _getNodeGroups(self, roster, nodeIdentifier): 489 def _getNodeGroups(self, roster, nodeIdentifier):
473 d = self.storage.getNodeGroups(nodeIdentifier) 490 d = self.storage.getNodeGroups(nodeIdentifier)
474 d.addCallback(lambda groups: (roster, groups)) 491 d.addCallback(lambda groups: (roster, groups))
475 return d 492 return d
479 496
480 def append_item_config(items_data): 497 def append_item_config(items_data):
481 ret = [] 498 ret = []
482 for data in items_data: 499 for data in items_data:
483 item, access_model, access_list = data 500 item, access_model, access_list = data
484 if access_model == const.VAL_OPEN: 501 if access_model == const.VAL_AMODEL_OPEN:
485 pass 502 pass
486 elif access_model == const.VAL_ROSTER: 503 elif access_model == const.VAL_AMODEL_ROSTER:
487 form = data_form.Form('submit', formNamespace=const.NS_ITEM_CONFIG) 504 form = data_form.Form('submit', formNamespace=const.NS_ITEM_CONFIG)
488 access = data_form.Field(None, const.OPT_ACCESS_MODEL, value=const.VAL_ROSTER) 505 access = data_form.Field(None, const.OPT_ACCESS_MODEL, value=const.VAL_AMODEL_ROSTER)
489 allowed = data_form.Field(None, const.OPT_ROSTER_GROUPS_ALLOWED, values=access_list) 506 allowed = data_form.Field(None, const.OPT_ROSTER_GROUPS_ALLOWED, values=access_list)
490 form.addField(access) 507 form.addField(access)
491 form.addField(allowed) 508 form.addField(allowed)
492 item.addChild(form.toElement()) 509 item.addChild(form.toElement())
493 elif access_model == const.VAL_JID: 510 elif access_model == const.VAL_AMODEL_JID:
494 #FIXME: manage jid 511 #FIXME: manage jid
495 raise NotImplementedError 512 raise NotImplementedError
496 else: 513 else:
497 raise error.BadAccessTypeError(access_model) 514 raise error.BadAccessTypeError(access_model)
498 515
526 access_model = node.getConfiguration()["pubsub#access_model"] 543 access_model = node.getConfiguration()["pubsub#access_model"]
527 d = node.getNodeOwner() 544 d = node.getNodeOwner()
528 d.addCallback(self.roster.getRoster) 545 d.addCallback(self.roster.getRoster)
529 546
530 if access_model == 'open' or affiliation == 'owner': 547 if access_model == 'open' or affiliation == 'owner':
531 d.addCallback(lambda roster: (True,roster)) 548 d.addCallback(lambda roster: (True, roster))
532 d.addCallback(access_checked) 549 d.addCallback(access_checked)
533 elif access_model == 'roster': 550 elif access_model == 'roster':
534 d.addCallback(self._getNodeGroups,node.nodeIdentifier) 551 d.addCallback(self._getNodeGroups,node.nodeIdentifier)
535 d.addCallback(self.checkGroup, requestor) 552 d.addCallback(self.checkGroup, requestor)
536 d.addCallback(access_checked) 553 d.addCallback(access_checked)
917 return d.addErrback(self._mapErrors) 934 return d.addErrback(self._mapErrors)
918 935
919 936
920 def create(self, request): 937 def create(self, request):
921 d = self.backend.createNode(request.nodeIdentifier, 938 d = self.backend.createNode(request.nodeIdentifier,
922 request.sender) 939 request.sender, request.options)
923 return d.addErrback(self._mapErrors) 940 return d.addErrback(self._mapErrors)
924 941
925 942
926 def default(self, request): 943 def default(self, request):
927 d = self.backend.getDefaultConfiguration(request.nodeType) 944 d = self.backend.getDefaultConfiguration(request.nodeType)