import logging logger = logging.getLogger(__name__) import base64 import hashlib from xml.etree import cElementTree as ET from sleekxmpp.xmlstream.stanzabase import ElementBase, register_stanza_plugin from sleekxmpp.plugins import base from sleekxmpp.xmlstream.handler.callback import Callback from sleekxmpp.xmlstream.matcher.xpath import MatchXPath from sleekxmpp.stanza.iq import Iq from object import ObjectReader, ObjectError from permission import PermissionError from config import config class AliasQuery(ElementBase): namespace = 'alias:iq:object' name = 'query' plugin_attrib = 'alias' interfaces = set(('node', 'type', 'content', 'permission', 'key')) sub_interfaces = set(('content', 'permission', 'key')) def addItem(self, node, key, permission = None): item = AliasItem(None, self) item['node'] = node item['key'] = key if permission is not None: item['permission'] = str(permission) class AliasItem(ElementBase): namespace = 'alias:query' name = 'item' plugin_attrib = 'item' interfaces = set(('node', 'permission', 'key')) class AliasPlugin(base.base_plugin): def plugin_init(self): self.description = 'Plugin to handle alias queries' register_stanza_plugin(Iq, AliasQuery) query_parser = MatchXPath('{{{}}}iq/{{{}}}query'.format(self.xmpp.default_ns, AliasQuery.namespace)) self.xmpp.register_handler(Callback('Alias queries', query_parser, self.handle_alias_query)) def post_init(self): base.base_plugin.post_init(self) self.xmpp.plugin['xep_0030'].add_feature("alias:query") def send_permission_error(self, iq, message): node = iq['alias']['node'] iq.reply() iq['alias']['type'] = 'error' iq['alias']['node'] = node iq['alias']['permission'] = message iq.send() def handle_alias_query(self, iq): caller = iq['from'].bare try: callee = base64.b64decode(iq['to'].user) except TypeError: logger.error("callee field not base64 encoded") node = iq['alias']['node'] node = ObjectReader(node, callee) if iq['alias']['type'] == 'get': try: content, key = node.get_content(caller) except PermissionError: self.send_permission_error(iq, 'Permission') else: iq.reply() iq['alias']['type'] = 'get' iq['alias']['node'] = node.hash iq['alias']['content'] = content iq['alias']['key'] = key iq.send() if iq['alias']['type'] == 'list': try: list = node.get_children_list(caller) except PermissionError: self.send_permission_error(iq, 'Permission') else: iq.reply() iq['alias']['type'] = 'content' iq['alias']['node'] = node.hash iq['alias']['content'] = content iq['alias']['key'] = key iq.send()