diff sat_pubsub/backend.py @ 243:42048e37699e

added experimental roster access_model (use remote_roster)
author Goffi <goffi@goffi.org>
date Sun, 27 May 2012 15:55:25 +0200
parents 70c8bb90d75f
children 50f6ee966da8
line wrap: on
line diff
--- a/sat_pubsub/backend.py	Sun May 27 15:36:06 2012 +0200
+++ b/sat_pubsub/backend.py	Sun May 27 15:55:25 2012 +0200
@@ -416,24 +416,62 @@
                        itemIdentifiers=None):
         d = self.storage.getNode(nodeIdentifier)
         d.addCallback(_getAffiliation, requestor)
-        d.addCallback(self._doGetItems, maxItems, itemIdentifiers)
+        d.addCallback(self._doGetItems, requestor, maxItems, itemIdentifiers)
         return d
 
+    def checkGroup(self, roster_groups, entity):
+        """Check that requester is in roster
+        @param roster_group: tuple which 2 items:
+                        - roster: mapping of jid to RosterItem as given by self.roster.getRoster
+                        - groups: list of authorized groups
+        @param entity: entity which must be in group 
+        @return: True if requestor is in roster"""
+        roster, authorized_groups = roster_groups
+        _entity = entity.userhost()
+        
+        if not _entity in roster:
+            raise error.NotInRoster
+        if roster[_entity].groups.intersection(authorized_groups):
+            return True
+        raise error.NotInRoster
 
-    def _doGetItems(self, result, maxItems, itemIdentifiers):
+    def _getNodeGroups(self, roster, nodeIdentifier):
+        d = self.storage.getNodeGroups(nodeIdentifier)
+        d.addCallback(lambda groups: (roster, groups))
+        return d
+
+    def _doGetItems(self, result, requestor, maxItems, itemIdentifiers):
         node, affiliation = result
 
+        def access_checked(authorized):
+            if not authorized:
+                raise error.NotAuthorized()
+
+            if itemIdentifiers:
+                return node.getItemsById(itemIdentifiers)
+            else:
+                return node.getItems(maxItems)
+
+
         if not ILeafNode.providedBy(node):
             return []
 
         if affiliation == 'outcast':
             raise error.Forbidden()
 
-        if itemIdentifiers:
-            return node.getItemsById(itemIdentifiers)
-        else:
-            return node.getItems(maxItems)
+        access_model = node.getConfiguration()["pubsub#access_model"]
+        
+        if access_model == 'open' or affiliation == 'owner':
+            d = defer.succeed(True)
+            d.addCallback(access_checked)
+        elif access_model == 'roster':
+            d = node.getNodeOwner()
+            d.addCallback(self.roster.getRoster)
+            d.addCallback(self._getNodeGroups,node.nodeIdentifier)
+            d.addCallback(self.checkGroup, requestor)
+            d.addCallback(access_checked)
 
+        return d
 
     def retractItem(self, nodeIdentifier, itemIdentifiers, requestor):
         d = self.storage.getNode(nodeIdentifier)
@@ -575,6 +613,8 @@
         error.NodeNotFound: ('item-not-found', None, None),
         error.NodeExists: ('conflict', None, None),
         error.Forbidden: ('forbidden', None, None),
+        error.NotAuthorized: ('not-authorized', None, None),
+        error.NotInRoster: ('not-authorized', 'not-in-roster-group', None),
         error.ItemForbidden: ('bad-request', 'item-forbidden', None),
         error.ItemRequired: ('bad-request', 'item-required', None),
         error.NoInstantNodes: ('not-acceptable',