annotate sat_pubsub/privilege.py @ 367:a772f7dac930

backend, storage(pgsql): creation/update date + serial ids: /!\ this patch updates pgqsl schema /!\ Had to set 2 features in the same patch, to avoid updating 2 times the schema. 1) creation/last modification date: column keeping the date of creation of items is renamed from "date" to "created" the date of last modification of items is saved in the new "updated" column 2) serial ids: this experimental feature allows to have ids in series (i.e. 1, 2, 3, etc.) instead of UUID. This is a convenience feature and there are some drawbacks: - PostgreSQL sequences are used, so gaps can happen (see PostgreSQL documentation for more details) - if somebody create an item with a future id in the series, the series will adapt, which can have undesired effect, and may lead to item fail if several items are created at the same time. For instance if next id in series is "8", and somebody hads already created item "8" and "256", the item will be created with biggest value in items +1 (i.e. 257). if 2 people want to create item in this situation, the second will fail with a conflict error.
author Goffi <goffi@goffi.org>
date Sat, 04 Nov 2017 21:31:32 +0100
parents d1f63ae1eaf4
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
1 #!/usr/bin/python
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
2 #-*- coding: utf-8 -*-
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
3 #
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
4 # Copyright (c) 2015 Jérôme Poisson
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
5
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
6
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
7 # This program is free software: you can redistribute it and/or modify
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
8 # it under the terms of the GNU Affero General Public License as published by
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
9 # the Free Software Foundation, either version 3 of the License, or
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
10 # (at your option) any later version.
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
11
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
12 # This program is distributed in the hope that it will be useful,
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
15 # GNU Affero General Public License for more details.
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
16
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
17 # You should have received a copy of the GNU Affero General Public License
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
19
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
20 # ---
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
21
312
5d7c3787672e fixed copyright put in docstring instead of comments
Goffi <goffi@goffi.org>
parents: 293
diff changeset
22 # This module implements XEP-0356 (Privileged Entity) to manage rosters, messages and presences
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
23
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
24 from wokkel import xmppim
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
25 from wokkel.compat import IQ
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
26 from wokkel import pubsub
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
27 from wokkel import disco
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
28 from wokkel.iwokkel import IPubSubService
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
29 from twisted.python import log
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
30 from twisted.python import failure
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
31 from twisted.internet import defer
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
32 from twisted.words.xish import domish
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
33 from twisted.words.protocols.jabber import jid
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
34 import time
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
35
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
36 FORWARDED_NS = 'urn:xmpp:forward:0'
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
37 PRIV_ENT_NS = 'urn:xmpp:privilege:1'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
38 PRIV_ENT_ADV_XPATH = '/message/privilege[@xmlns="{}"]'.format(PRIV_ENT_NS)
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
39 ROSTER_NS = 'jabber:iq:roster'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
40 PERM_ROSTER = 'roster'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
41 PERM_MESSAGE = 'message'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
42 PERM_PRESENCE = 'presence'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
43 ALLOWED_ROSTER = ('none', 'get', 'set', 'both')
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
44 ALLOWED_MESSAGE = ('none', 'outgoing')
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
45 ALLOWED_PRESENCE = ('none', 'managed_entity', 'roster')
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
46 TO_CHECK = {PERM_ROSTER:ALLOWED_ROSTER, PERM_MESSAGE:ALLOWED_MESSAGE, PERM_PRESENCE:ALLOWED_PRESENCE}
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
47
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
48
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
49 class InvalidStanza(Exception):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
50 pass
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
51
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
52 class NotAllowedError(Exception):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
53 pass
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
54
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
55 class PrivilegesHandler(disco.DiscoClientProtocol):
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
56 #FIXME: need to manage updates, and database sync
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
57 #TODO: cache
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
58
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
59 def __init__(self, service_jid):
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
60 super(PrivilegesHandler, self).__init__()
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
61 self._permissions = {PERM_ROSTER: 'none',
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
62 PERM_MESSAGE: 'none',
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
63 PERM_PRESENCE: 'none'}
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
64 self._pubsub_service = None
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
65 self._backend = None
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
66 # FIXME: we use a hack supposing that our privilege come from hostname
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
67 # and we are a component named [name].hostname
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
68 # but we need to manage properly server
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
69 # TODO: do proper server handling
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
70 self.server_jid = jid.JID(service_jid.host.split('.', 1)[1])
343
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
71 self.caps_map = {} # key: bare jid, value: dict of resources with caps hash
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
72 self.hash_map = {} # key: (hash,version), value: dict with DiscoInfo instance (infos) and nodes to notify (notify)
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
73 self.roster_cache = {} # key: jid, value: dict with "timestamp" and "roster"
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
74 self.presence_map = {} # inverted roster: key: jid, value: set of entities who has this jid in roster (with presence of "from" or "both")
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
75 self.server = None
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
76
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
77 @property
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
78 def permissions(self):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
79 return self._permissions
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
80
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
81 def connectionInitialized(self):
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
82 for handler in self.parent.handlers:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
83 if IPubSubService.providedBy(handler):
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
84 self._pubsub_service = handler
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
85 break
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
86 self._backend = self.parent.parent.getServiceNamed('backend')
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
87 self.xmlstream.addObserver(PRIV_ENT_ADV_XPATH, self.onAdvertise)
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
88 self.xmlstream.addObserver('/presence', self.onPresence)
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
89
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
90 def onAdvertise(self, message):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
91 """Managage the <message/> advertising privileges
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
92
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
93 self._permissions will be updated according to advertised privileged
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
94 """
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
95 privilege_elt = message.elements(PRIV_ENT_NS, 'privilege').next()
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
96 for perm_elt in privilege_elt.elements(PRIV_ENT_NS):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
97 try:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
98 if perm_elt.name != 'perm':
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
99 raise InvalidStanza(u'unexpected element {}'.format(perm_elt.name))
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
100 perm_access = perm_elt['access']
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
101 perm_type = perm_elt['type']
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
102 try:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
103 if perm_type not in TO_CHECK[perm_access]:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
104 raise InvalidStanza(u'bad type [{}] for permission {}'.format(perm_type, perm_access))
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
105 except KeyError:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
106 raise InvalidStanza(u'bad permission [{}]'.format(perm_access))
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
107 except InvalidStanza as e:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
108 log.msg("Invalid stanza received ({}), setting permission to none".format(e))
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
109 for perm in self._permissions:
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
110 self._permissions[perm] = 'none'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
111 break
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
112
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
113 self._permissions[perm_access] = perm_type or 'none'
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
114
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
115 log.msg('Privileges updated: roster={roster}, message={message}, presence={presence}'.format(**self._permissions))
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
116
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
117 ## roster ##
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
118
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
119 def getRoster(self, to_jid):
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
120 """
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
121 Retrieve contact list.
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
122
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
123 @return: Roster as a mapping from L{JID} to L{RosterItem}.
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
124 @rtype: L{twisted.internet.defer.Deferred}
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
125 """
343
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
126 # TODO: cache results
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
127 if self._permissions[PERM_ROSTER] not in ('get', 'both'):
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
128 log.msg("WARNING: permission not allowed to get roster")
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
129 raise failure.Failure(NotAllowedError('roster get is not allowed'))
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
130
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
131 def processRoster(result):
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
132 roster = {}
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
133 for element in result.query.elements(ROSTER_NS, 'item'):
253
06494c9b25f2 update to fix broken RemoteRoster after Wokkel 0.7.1 changes
Goffi <goffi@goffi.org>
parents: 242
diff changeset
134 item = xmppim.RosterItem.fromElement(element)
06494c9b25f2 update to fix broken RemoteRoster after Wokkel 0.7.1 changes
Goffi <goffi@goffi.org>
parents: 242
diff changeset
135 roster[item.entity] = item
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
136
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
137 return roster
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
138
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
139 iq = IQ(self.xmlstream, 'get')
285
a87c155d0fd5 replaced former roster dirty hack by a XEP-0356 first draft implementation, only roster get is implemented so far
Goffi <goffi@goffi.org>
parents: 283
diff changeset
140 iq.addElement((ROSTER_NS, 'query'))
242
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
141 iq["to"] = to_jid.userhost()
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
142 d = iq.send()
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
143 d.addCallback(processRoster)
a6170637690d remote roster partial support
Goffi <goffi@goffi.org>
parents:
diff changeset
144 return d
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
145
348
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
146 def _isSubscribedFrom(self, roster, entity, roster_owner_jid):
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
147 try:
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
148 return roster[entity.userhostJID()].subscriptionFrom
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
149 except KeyError:
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
150 return False
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
151
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
152 def isSubscribedFrom(self, entity, roster_owner_jid):
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
153 """Check if entity has presence subscription from roster_owner_jid
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
154
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
155 @param entity(jid.JID): entity to check subscription to
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
156 @param roster_owner_jid(jid.JID): owner of the roster to check
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
157 @return D(bool): True if entity has a subscription from roster_owner_jid
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
158 """
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
159 d = self.getRoster(roster_owner_jid)
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
160 d.addCallback(self._isSubscribedFrom, entity, roster_owner_jid)
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
161 return d
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
162
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
163 ## message ##
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
164
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
165 def sendMessage(self, priv_message, to_jid=None):
348
d1f63ae1eaf4 privilege: added isSubscribedFrom method to check if an entity has presence subscription from an other entity.
Goffi <goffi@goffi.org>
parents: 343
diff changeset
166 """Send privileged message (in the name of the server)
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
167
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
168 @param priv_message(domish.Element): privileged message
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
169 @param to_jid(jid.JID, None): main message destinee
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
170 None to use our own server
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
171 """
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
172 if self._permissions[PERM_MESSAGE] not in ('outgoing',):
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
173 log.msg("WARNING: permission not allowed to send privileged messages")
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
174 raise failure.Failure(NotAllowedError('privileged messages are not allowed'))
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
175
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
176 main_message = domish.Element((None, "message"))
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
177 if to_jid is None:
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
178 to_jid = self.server_jid
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
179 main_message['to'] = to_jid.full()
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
180 privilege_elt = main_message.addElement((PRIV_ENT_NS, 'privilege'))
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
181 forwarded_elt = privilege_elt.addElement((FORWARDED_NS, 'forwarded'))
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
182 priv_message['xmlns'] = 'jabber:client'
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
183 forwarded_elt.addChild(priv_message)
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
184 self.send(main_message)
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
185
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
186 def notifyPublish(self, pep_jid, nodeIdentifier, notifications):
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
187 """Do notifications using privileges"""
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
188 for subscriber, subscriptions, items in notifications:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
189 message = self._pubsub_service._createNotification('items', pep_jid,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
190 nodeIdentifier, subscriber,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
191 subscriptions)
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
192 for item in items:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
193 item.uri = pubsub.NS_PUBSUB_EVENT
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
194 message.event.items.addChild(item)
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
195 self.sendMessage(message)
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
196
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
197
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
198 def notifyRetract(self, pep_jid, nodeIdentifier, notifications):
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
199 for subscriber, subscriptions, items in notifications:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
200 message = self._pubsub_service._createNotification('items', pep_jid,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
201 nodeIdentifier, subscriber,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
202 subscriptions)
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
203 for item in items:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
204 retract = domish.Element((None, "retract"))
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
205 retract['id'] = item['id']
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
206 message.event.items.addChild(retract)
321
c7fe09894952 privilege: better handling of main message 'to' attribute (i.e. privileged entity's server)
Goffi <goffi@goffi.org>
parents: 312
diff changeset
207 self.sendMessage(message)
293
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
208
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
209
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
210 # def notifyDelete(self, service, nodeIdentifier, subscribers,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
211 # redirectURI=None):
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
212 # # TODO
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
213 # for subscriber in subscribers:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
214 # message = self._createNotification('delete', service,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
215 # nodeIdentifier,
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
216 # subscriber)
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
217 # if redirectURI:
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
218 # redirect = message.event.delete.addElement('redirect')
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
219 # redirect['uri'] = redirectURI
b96a4ac25f8b privilege: added methods to send privileged messages and notifications
Goffi <goffi@goffi.org>
parents: 286
diff changeset
220 # self.send(message)
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
221
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
222
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
223 ## presence ##
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
224
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
225 @defer.inlineCallbacks
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
226 def onPresence(self, presence_elt):
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
227 if self.server is None:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
228 # FIXME: we use a hack supposing that our delegation come from hostname
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
229 # and we are a component named [name].hostname
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
230 # but we need to manage properly allowed servers
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
231 # TODO: do proper origin security check
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
232 _, self.server = presence_elt['to'].split('.', 1)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
233 from_jid = jid.JID(presence_elt['from'])
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
234 from_jid_bare = from_jid.userhostJID()
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
235 if from_jid.host == self.server and from_jid_bare not in self.roster_cache:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
236 roster = yield self.getRoster(from_jid_bare)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
237 timestamp = time.time()
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
238 self.roster_cache[from_jid_bare] = {'timestamp': timestamp,
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
239 'roster': roster,
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
240 }
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
241 for roster_jid, roster_item in roster.iteritems():
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
242 if roster_item.subscriptionFrom:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
243 self.presence_map.setdefault(roster_jid, set()).add(from_jid_bare)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
244
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
245 presence_type = presence_elt.getAttribute('type')
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
246 if presence_type != "unavailable":
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
247 # new resource available, we check entity capabilities
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
248 try:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
249 c_elt = next(presence_elt.elements('http://jabber.org/protocol/caps', 'c'))
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
250 hash_ = c_elt['hash']
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
251 ver = c_elt['ver']
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
252 except (StopIteration, KeyError):
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
253 # no capabilities, we don't go further
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
254 return
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
255
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
256 # FIXME: hash is not checked (cf. XEP-0115)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
257 disco_tuple = (hash_, ver)
343
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
258 jid_caps = self.caps_map.setdefault(from_jid_bare, {})
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
259 if from_jid.resource not in jid_caps:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
260 jid_caps[from_jid.resource] = disco_tuple
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
261
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
262 if disco_tuple not in self.hash_map:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
263 # first time we se this hash, what is behind it?
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
264 infos = yield self.requestInfo(from_jid)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
265 self.hash_map[disco_tuple] = {
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
266 'notify': {f[:-7] for f in infos.features if f.endswith('+notify')},
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
267 'infos': infos
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
268 }
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
269
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
270 # nodes are the nodes subscribed with +notify
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
271 nodes = tuple(self.hash_map[disco_tuple]['notify'])
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
272 if not nodes:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
273 return
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
274 # publishers are entities which have granted presence access to our user + user itself
342
28c9579901d3 privilege: fixed addition of owner to publishers in onPresence
Goffi <goffi@goffi.org>
parents: 338
diff changeset
275 publishers = tuple(self.presence_map.get(from_jid_bare, ())) + (from_jid_bare,)
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
276
343
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
277 # FIXME: add "presence" access_model (for node) for getLastItems
338
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
278 last_items = yield self._backend.storage.getLastItems(publishers, nodes, ('open',), ('open',), True)
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
279 # we send message with last item, as required by https://xmpp.org/extensions/xep-0163.html#notify-last
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
280 for pep_jid, node, item, item_access_model in last_items:
6d059f07c2d3 privilege: added presence and +notify initial support:
Goffi <goffi@goffi.org>
parents: 321
diff changeset
281 self.notifyPublish(pep_jid, node, [(from_jid, None, [item])])
343
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
282
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
283 ## misc ##
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
284
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
285 @defer.inlineCallbacks
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
286 def getAutoSubscribers(self, recipient, nodeIdentifier, explicit_subscribers):
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
287 """get automatic subscribers, i.e. subscribers with presence subscription and +notify for this node
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
288
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
289 @param recipient(jid.JID): jid of the PEP owner of this node
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
290 @param nodeIdentifier(unicode): node
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
291 @param explicit_subscribers(set(jid.JID}: jids of people which have an explicit subscription
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
292 @return (list[jid.JID]): full jid of automatically subscribed entities
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
293 """
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
294 auto_subscribers = []
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
295 roster = yield self.getRoster(recipient)
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
296 for roster_jid, roster_item in roster.iteritems():
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
297 if roster_jid in explicit_subscribers:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
298 continue
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
299 if roster_item.subscriptionFrom:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
300 try:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
301 online_resources = self.caps_map[roster_jid]
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
302 except KeyError:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
303 continue
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
304 for res, hash_ in online_resources.iteritems():
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
305 notify = self.hash_map[hash_]['notify']
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
306 if nodeIdentifier in notify:
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
307 full_jid = jid.JID(tuple=(roster_jid.user, roster_jid.host, res))
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
308 auto_subscribers.append(full_jid)
ff8aff4c9b79 backend, psql: implemented notifications for auto subscribers in PEP:
Goffi <goffi@goffi.org>
parents: 342
diff changeset
309 defer.returnValue(auto_subscribers)