Mercurial > libervia-pubsub
comparison sat_pubsub/backend.py @ 354:18b983fe9e1b
backend: added "presence" access_model:
- move presence checking method in separated method so they can be use for get and subscriptions
- added VAL_AMODEL_PRESENCE constant
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 08 Sep 2017 08:02:05 +0200 |
parents | 7c5d85c6fb3a |
children | c72fcbdcdab7 |
comparison
equal
deleted
inserted
replaced
353:7c5d85c6fb3a | 354:18b983fe9e1b |
---|---|
122 const.OPT_ACCESS_MODEL: | 122 const.OPT_ACCESS_MODEL: |
123 {"type": "list-single", | 123 {"type": "list-single", |
124 "label": "Who can subscribe to this node", | 124 "label": "Who can subscribe to this node", |
125 "options": { | 125 "options": { |
126 const.VAL_AMODEL_OPEN: "Public node", | 126 const.VAL_AMODEL_OPEN: "Public node", |
127 const.VAL_AMODEL_PRESENCE: "Node restricted to entites subscribed to owner presence", | |
127 const.VAL_AMODEL_PUBLISHER_ROSTER: "Node restricted to some groups of publisher's roster", | 128 const.VAL_AMODEL_PUBLISHER_ROSTER: "Node restricted to some groups of publisher's roster", |
128 const.VAL_AMODEL_WHITELIST: "Node restricted to some jids", | 129 const.VAL_AMODEL_WHITELIST: "Node restricted to some jids", |
129 } | 130 } |
130 }, | 131 }, |
131 const.OPT_ROSTER_GROUPS_ALLOWED: | 132 const.OPT_ROSTER_GROUPS_ALLOWED: |
469 if affiliation == 'outcast': | 470 if affiliation == 'outcast': |
470 raise error.Forbidden() | 471 raise error.Forbidden() |
471 | 472 |
472 access_model = node.getAccessModel() | 473 access_model = node.getAccessModel() |
473 | 474 |
474 if access_model != const.VAL_AMODEL_OPEN: | 475 if access_model == const.VAL_AMODEL_OPEN: |
476 d = defer.succeed(None) | |
477 elif access_model == const.VAL_AMODEL_PRESENCE: | |
478 d = self.checkPresenceSubscription(node, subscriber) | |
479 elif access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: | |
480 d = self.checkRosterGroups(node, subscriber) | |
481 elif access_model == const.VAL_AMODEL_WHITELIST: | |
482 d = self.checkNodeAffiliations(node, subscriber) | |
483 else: | |
475 raise NotImplementedError | 484 raise NotImplementedError |
476 | 485 |
477 def trapExists(failure): | 486 def trapExists(failure): |
478 failure.trap(error.SubscriptionExists) | 487 failure.trap(error.SubscriptionExists) |
479 return False | 488 return False |
764 item_elt.addChild(form.toElement()) | 773 item_elt.addChild(form.toElement()) |
765 | 774 |
766 for item_data in items_to_remove: | 775 for item_data in items_to_remove: |
767 items_data.remove(item_data) | 776 items_data.remove(item_data) |
768 | 777 |
778 def checkPresenceSubscription(self, node, requestor): | |
779 """check if requestor has presence subscription from node owner | |
780 | |
781 @param node(Node): node to check | |
782 @param requestor(jid.JID): entity who want to access node | |
783 """ | |
784 def gotRoster(roster): | |
785 if roster is None: | |
786 raise error.Forbidden() | |
787 | |
788 if requestor not in roster: | |
789 raise error.Forbidden() | |
790 | |
791 if not roster[requestor].subscriptionFrom: | |
792 raise error.Forbidden() | |
793 | |
794 d = self.getOwnerRoster(node) | |
795 d.addCallback(gotRoster) | |
796 return d | |
797 | |
798 @defer.inlineCallbacks | |
799 def checkRosterGroups(self, node, requestor): | |
800 """check if requestor is in allowed groups of a node | |
801 | |
802 @param node(Node): node to check | |
803 @param requestor(jid.JID): entity who want to access node | |
804 """ | |
805 roster = yield self.getOwnerRoster(node) | |
806 | |
807 if roster is None: | |
808 raise error.Forbidden() | |
809 | |
810 if requestor not in roster: | |
811 raise error.Forbidden() | |
812 | |
813 authorized_groups = yield node.getAuthorizedGroups() | |
814 | |
815 if not roster[requestor].groups.intersection(authorized_groups): | |
816 # requestor is in roster but not in one of the allowed groups | |
817 raise error.Forbidden() | |
818 | |
819 @defer.inlineCallbacks | |
820 def checkNodeAffiliations(self, node, requestor): | |
821 """check if requestor is in white list of a node | |
822 | |
823 @param node(Node): node to check | |
824 @param requestor(jid.JID): entity who want to access node | |
825 """ | |
826 def gotAffiliations(affiliations): | |
827 try: | |
828 affiliation = affiliations[requestor.userhostJID()] | |
829 except KeyError: | |
830 raise error.Forbidden() | |
831 else: | |
832 if affiliation not in ('owner', 'publisher', 'member'): | |
833 raise error.Forbidden() | |
834 | |
835 d = node.getAffiliations() | |
836 d.addCallback(gotAffiliations) | |
837 return d | |
838 | |
769 @defer.inlineCallbacks | 839 @defer.inlineCallbacks |
770 def checkNodeAccess(self, node, requestor): | 840 def checkNodeAccess(self, node, requestor): |
771 """check if a requestor can access data of a node | 841 """check if a requestor can access data of a node |
772 | 842 |
773 @param node(Node): node to check | 843 @param node(Node): node to check |
793 access_model = node.getAccessModel() | 863 access_model = node.getAccessModel() |
794 roster = None | 864 roster = None |
795 | 865 |
796 if access_model == const.VAL_AMODEL_OPEN or owner: | 866 if access_model == const.VAL_AMODEL_OPEN or owner: |
797 pass | 867 pass |
868 elif access_model == const.VAL_AMODEL_PRESENCE: | |
869 yield self.checkPresenceSubscription(node, requestor) | |
798 elif access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: | 870 elif access_model == const.VAL_AMODEL_PUBLISHER_ROSTER: |
799 # FIXME: publisher roster should be used, not owner | 871 # FIXME: for node, access should be renamed owner-roster, not publisher |
800 roster = yield self.getOwnerRoster(node) | 872 yield self.checkRosterGroups(node, requestor) |
801 | |
802 if roster is None: | |
803 raise error.Forbidden() | |
804 | |
805 if requestor not in roster: | |
806 raise error.Forbidden() | |
807 | |
808 authorized_groups = yield node.getAuthorizedGroups() | |
809 | |
810 if not roster[requestor].groups.intersection(authorized_groups): | |
811 # requestor is in roster but not in one of the allowed groups | |
812 raise error.Forbidden() | |
813 elif access_model == const.VAL_AMODEL_WHITELIST: | 873 elif access_model == const.VAL_AMODEL_WHITELIST: |
814 affiliations = yield node.getAffiliations() | 874 yield self.checkNodeAffiliations(node, requestor) |
815 try: | |
816 affiliation = affiliations[requestor.userhostJID()] | |
817 except KeyError: | |
818 raise error.Forbidden() | |
819 else: | |
820 if affiliation not in ('owner', 'publisher', 'member'): | |
821 raise error.Forbidden() | |
822 else: | 875 else: |
823 raise Exception(u"Unknown access_model") | 876 raise Exception(u"Unknown access_model") |
824 | 877 |
825 defer.returnValue((affiliation, owner, roster, access_model)) | 878 defer.returnValue((affiliation, owner, roster, access_model)) |
826 | 879 |
1499 self._isPep(request), | 1552 self._isPep(request), |
1500 request.recipient) | 1553 request.recipient) |
1501 return d.addErrback(self._mapErrors) | 1554 return d.addErrback(self._mapErrors) |
1502 | 1555 |
1503 def subscriptions(self, request): | 1556 def subscriptions(self, request): |
1504 d = self.backend.getSubscriptions(self._isPep(request), | 1557 d = self.backend.getSubscriptions(request.sender, |
1505 request.sender) | 1558 self._isPep(request), |
1559 request.recipient) | |
1506 return d.addErrback(self._mapErrors) | 1560 return d.addErrback(self._mapErrors) |
1507 | 1561 |
1508 def affiliations(self, request): | 1562 def affiliations(self, request): |
1509 """Retrieve affiliation for normal entity (cf. XEP-0060 §5.7) | 1563 """Retrieve affiliation for normal entity (cf. XEP-0060 §5.7) |
1510 | 1564 |