Mercurial > libervia-pubsub
diff sat_pubsub/privilege.py @ 460:607616f9ef5b
backend: new `server_jid` option:
Server domain must be known to validate requests, this can be done explicitely by using the
`server_jid` option. If this option is not set, the server domain is found:
- by using the `from` name of the initial delegation advertising message
- or it fallbacks to using the part after initial `.` (`pubsub.example.org` would give
`example.org`)
author | Goffi <goffi@goffi.org> |
---|---|
date | Fri, 15 Oct 2021 09:32:07 +0200 |
parents | 0b5233981671 |
children | a017af61a32b |
line wrap: on
line diff
--- a/sat_pubsub/privilege.py Fri Oct 15 09:32:04 2021 +0200 +++ b/sat_pubsub/privilege.py Fri Oct 15 09:32:07 2021 +0200 @@ -1,7 +1,6 @@ #!/usr/bin/env python3 -#-*- coding: utf-8 -*- # -# Copyright (c) 2015 Jérôme Poisson +# Copyright (c) 2015-2021 Jérôme Poisson # This program is free software: you can redistribute it and/or modify @@ -17,7 +16,8 @@ # You should have received a copy of the GNU Affero General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. -# --- +"This module implements XEP-0356 (Privileged Entity) to manage rosters, messages and " +"presences" # This module implements XEP-0356 (Privileged Entity) to manage rosters, messages and presences @@ -58,21 +58,17 @@ def __init__(self, service_jid): super(PrivilegesHandler, self).__init__() + self.backend = None self._permissions = {PERM_ROSTER: 'none', PERM_MESSAGE: 'none', PERM_PRESENCE: 'none'} self._pubsub_service = None - self._backend = None - # FIXME: we use a hack supposing that our privilege come from hostname - # and we are a component named [name].hostname - # but we need to manage properly server - # TODO: do proper server handling - self.server_jid = jid.JID(service_jid.host.split('.', 1)[1]) self.caps_map = {} # key: bare jid, value: dict of resources with caps hash - self.hash_map = {} # key: (hash,version), value: dict with DiscoInfo instance (infos) and nodes to notify (notify) + # key: (hash,version), value: dict with DiscoInfo instance (infos) and nodes to + # notify (notify) + self.hash_map = {} self.roster_cache = {} # key: jid, value: dict with "timestamp" and "roster" self.presence_map = {} # inverted roster: key: jid, value: set of entities who has this jid in roster (with presence of "from" or "both") - self.server = None @property def permissions(self): @@ -83,9 +79,9 @@ if IPubSubService.providedBy(handler): self._pubsub_service = handler break - self._backend = self.parent.parent.getServiceNamed('backend') + self.backend = self.parent.parent.getServiceNamed('backend') self.xmlstream.addObserver(PRIV_ENT_ADV_XPATH, self.onAdvertise) - self.xmlstream.addObserver('/presence', self.onPresence) + self.xmlstream.addObserver('/presence', self._onPresence) def onAdvertise(self, message): """Managage the <message/> advertising privileges @@ -175,7 +171,7 @@ main_message = domish.Element((None, "message")) if to_jid is None: - to_jid = self.server_jid + to_jid = self.backend.server_jid main_message['to'] = to_jid.full() privilege_elt = main_message.addElement((PRIV_ENT_NS, 'privilege')) forwarded_elt = privilege_elt.addElement((FORWARDED_NS, 'forwarded')) @@ -238,18 +234,15 @@ ## presence ## - @defer.inlineCallbacks - def onPresence(self, presence_elt): - if self.server is None: - # FIXME: we use a hack supposing that our delegation come from hostname - # and we are a component named [name].hostname - # but we need to manage properly allowed servers - # TODO: do proper origin security check - _, self.server = presence_elt['to'].split('.', 1) + def _onPresence(self, presence_elt: domish.Element) -> None: + defer.ensureDeferred(self.onPresence(presence_elt)) + + async def onPresence(self, presence_elt: domish.Element) -> None: from_jid = jid.JID(presence_elt['from']) from_jid_bare = from_jid.userhostJID() - if from_jid.host == self.server and from_jid_bare not in self.roster_cache: - roster = yield self.getRoster(from_jid_bare) + if ((jid.JID(from_jid.host) == self.backend.server_jid + and from_jid_bare not in self.roster_cache)): + roster = await self.getRoster(from_jid_bare) timestamp = time.time() self.roster_cache[from_jid_bare] = {'timestamp': timestamp, 'roster': roster,