import logging logger = logging.getLogger("alias") 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 class AliasQuery(ElementBase): namespace = 'alias:query' name = 'query' plugin_attrib = 'alias' interfaces = set(('node', 'type', 'content', 'permission', 'key')) sub_interfaces = set(('content', 'permission', 'key', 'salt')) 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 if iq['alias']['type'] == 'keys': key, salt = ObjectReader(caller).get_private_key(); iq.reply() iq['alias']['type'] = 'keys' iq['alias']['key'] = key iq['alias']['salt'] = salt iq.send() try: callee = base64.b64decode(iq['to'].user) except TypeError: logger.error("callee field not base64 encoded") node = iq['alias']['node'] node = ObjectReader(callee, node) if iq['alias']['type'] == 'items': try: childs = node.get_child_list(caller) except PermissionError: self.send_permission_error(iq, 'Permission') else: iq.reply() iq['alias']['type'] = 'items' iq['alias']['node'] = node.hash for name, perm, key in childs: iq['alias'].addItem(name, key, perm) iq.send() if iq['alias']['type'] == 'content': try: content, key = node.get_content(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()