def testConvertArray(self): params = [[1,2,3], ('a', 'b', 'c')] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <array> <data> <value><i4>1</i4></value> <value><i4>2</i4></value> <value><i4>3</i4></value> </data> </array> </value> </param> <param> <value> <array> <data> <value><string>a</string></value> <value><string>b</string></value> <value><string>c</string></value> </data> </array> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Array to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(list(map(list, params)), xml2py(expected_xml), "XML to array conversion")
def testConvertBase64(self): params = [rpcbase64(base64.b64encode(b"Hello, world!"))] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <base64>SGVsbG8sIHdvcmxkIQ==</base64> </value> </param> </params> """) alternate_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <Base64>SGVsbG8sIHdvcmxkIQ==</Base64> </value> </param> </params> """) self.assertTrue( self.compare(expected_xml, params_xml), "Base64 to XML conversion\nExpected: %s\nGot: %s" % (tostring(expected_xml), tostring(params_xml))) self.assertEqual(list(map(lambda x: x.decode(), params)), list(map(lambda x: x.decode(), xml2py(expected_xml))), "XML to base64 conversion") self.assertEqual( list(map(lambda x: x.decode(), params)), list(map(lambda x: x.decode(), xml2py(alternate_xml))), "Alternate XML to base64 conversion")
def testConvertStruct(self): params = [{"foo": "bar", "baz": False}] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <struct> <member> <name>foo</name> <value><string>bar</string></value> </member> <member> <name>baz</name> <value><boolean>0</boolean></value> </member> </struct> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Struct to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to struct conversion")
def testConvertArray(self): params = [[1, 2, 3], ('a', 'b', 'c')] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <array> <data> <value><i4>1</i4></value> <value><i4>2</i4></value> <value><i4>3</i4></value> </data> </array> </value> </param> <param> <value> <array> <data> <value><string>a</string></value> <value><string>b</string></value> <value><string>c</string></value> </data> </array> </value> </param> </params> """) self.assertTrue( self.compare(expected_xml, params_xml), "Array to XML conversion\nExpected: %s\nGot: %s" % (tostring(expected_xml), tostring(params_xml))) self.assertEqual(list(map(list, params)), xml2py(expected_xml), "XML to array conversion")
def testConvertStruct(self): params = [{"foo": "bar", "baz": False}] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <struct> <member> <name>foo</name> <value><string>bar</string></value> </member> <member> <name>baz</name> <value><boolean>0</boolean></value> </member> </struct> </value> </param> </params> """) self.assertTrue( self.compare(expected_xml, params_xml), "Struct to XML conversion\nExpected: %s\nGot: %s" % (tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to struct conversion")
def call(self, target_jid, method, *args) -> Future: """Call a method on a remote host. Args: target_jid: Target JID to call method on. method: Name of method to call. *args: Parameters for method. Returns: Future for response. """ # create the method call iq = self._client.plugin['xep_0009'].make_iq_method_call( target_jid, method, py2xml(*args)) # create a future for this pid = iq['id'] future = Future() self._futures[pid] = future # send request try: iq.send(block=False) except sleekxmpp.exceptions.IqError: # we handle exceptions elsewhere pass # don't wait for response, just return future return future
async def call(self, target_jid: str, method: str, signature: inspect.Signature, *args: Any) -> Any: """Call a method on a remote host. Args: target_jid: Target JID to call method on. method: Name of method to call. signature: Method signature. *args: Parameters for method. Returns: Future for response. """ # create the method call iq = self._client.plugin["xep_0009"].make_iq_method_call( target_jid, method, py2xml(*args)) # create a future for this pid = iq["id"] future = Future(signature=signature) self._futures[pid] = future # send request try: iq.send(block=False) except sleekxmpp.exceptions.IqError: raise InvocationException() except sleekxmpp.exceptions.IqTimeout: raise TimeoutException() # don't wait for response, just return future return await future
def testConvertBase64(self): params = [rpcbase64(base64.b64encode(b"Hello, world!"))] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <base64>SGVsbG8sIHdvcmxkIQ==</base64> </value> </param> </params> """) alternate_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <Base64>SGVsbG8sIHdvcmxkIQ==</Base64> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Base64 to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(list(map(lambda x: x.decode(), params)), list(map(lambda x: x.decode(), xml2py(expected_xml))), "XML to base64 conversion") self.assertEqual(list(map(lambda x: x.decode(), params)), list(map(lambda x: x.decode(), xml2py(alternate_xml))), "Alternate XML to base64 conversion")
def _on_jabber_rpc_method_call(self, iq): """React on remote method call. Args: iq: Received XMPP message. """ # get method and parameters iq.enable('rpc_query') params = xml2py(iq['rpc_query']['method_call']['params']) pmethod = iq['rpc_query']['method_call']['method_name'] try: # get method with self._lock: try: method, signature = self._methods[pmethod] except KeyError: log.error("No handler available for %s!", pmethod) self._client.plugin['xep_0009'].item_not_found(iq).send() return # bind parameters ba = signature.bind(*params) ba.apply_defaults() # do we have a timeout? if hasattr(method, 'timeout'): timeout = method.timeout(self._handler, **ba.arguments) if timeout: # yes, send it! response = self._client.plugin['xep_0009_timeout'].\ make_iq_method_timeout(iq['id'], iq['from'], int(timeout)) response.send() # call method return_value = self._handler.execute(pmethod, *params, sender=iq['from'].user) return_value = () if return_value is None else (return_value, ) # send response self._client.plugin['xep_0009'].make_iq_method_response( iq['id'], iq['from'], py2xml(*return_value)).send() except InvocationException as ie: # could not invoke method fault = dict() fault['code'] = 500 fault['string'] = ie.get_message() self._client.plugin['xep_0009'].send_fault(iq, fault2xml(fault)) except Exception as e: # something else went wrong # log.exception('Error during call to %s: %s', pmethod, str(e)) fault = dict() fault['code'] = 500 fault['string'] = str(e) self._client.plugin['xep_0009'].send_fault(iq, fault2xml(fault))
def testMethodResponse(self): iq = self.Iq() iq['rpc_query']['method_response']['params'] = py2xml(*()) self.check(iq, """ <iq> <query xmlns="jabber:iq:rpc"> <methodResponse> <params /> </methodResponse> </query> </iq> """, use_values=False)
def _call_remote(self, pto, pmethod, callback, *arguments): iq = self._client.plugin['xep_0009'].make_iq_method_call(pto, pmethod, py2xml(*arguments)) pid = iq['id'] if callback is None: future = Future() self._register_callback(pid, future) iq.send() return future.get_value(30) else: log.debug("[RemoteSession] _call_remote %s", callback) self._register_callback(pid, callback) iq.send()
def _call_remote(self, pto, pmethod, callback, *arguments): iq = self._client.plugin['xep_0009'].make_iq_method_call( pto, pmethod, py2xml(*arguments)) pid = iq['id'] if callback is None: future = Future() self._register_callback(pid, future) iq.send() return future.get_value(30) else: log.debug("[RemoteSession] _call_remote %s", callback) self._register_callback(pid, callback) iq.send()
def testMethodCall(self): iq = self.Iq() iq['rpc_query']['method_call']['method_name'] = 'system.exit' iq['rpc_query']['method_call']['params'] = py2xml(*()) self.check(iq, """ <iq> <query xmlns="jabber:iq:rpc"> <methodCall> <methodName>system.exit</methodName> <params /> </methodCall> </query> </iq> """, use_values=False)
async def _call_remote(self, iq: Any, method_name: str, method: Callable, arguments: dict) -> None: """React on remote method call. Args: iq: Received XMPP message. """ try: # do we have a timeout? if hasattr(method, "timeout"): timeout = await getattr(method, "timeout")(self._handler, **arguments) if timeout: # yes, send it! response = self._client.plugin[ "xep_0009_timeout"].make_iq_method_timeout( iq["id"], iq["from"], int(timeout)) response.send() # call method return_value = await self._handler.execute(method_name, **arguments, sender=iq["from"].user) return_value = () if return_value is None else (return_value, ) # send response self._client.plugin["xep_0009"].make_iq_method_response( iq["id"], iq["from"], py2xml(*return_value)).send() except InvocationException as ie: # could not invoke method fault = {"code": 500, "string": ie.get_message()} self._client.plugin["xep_0009"].send_fault(iq, fault2xml(fault)) except Exception as e: # something else went wrong log.warning("Error during call to %s: %s", method_name, str(e), exc_info=True) # send response fault = dict() fault["code"] = 500 fault["string"] = str(e) self._client.plugin["xep_0009"].send_fault(iq, fault2xml(fault))
def testConvertUnicodeString(self): params = ["おはよう"] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <string>おはよう</string> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "String to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to string conversion")
def testConvertNil(self): params = [None] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <nil /> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Nil to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to nil conversion")
def testConvertNil(self): params = [None] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <nil /> </value> </param> </params> """) self.assertTrue( self.compare(expected_xml, params_xml), "Nil to XML conversion\nExpected: %s\nGot: %s" % (tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to nil conversion")
def testConvertString(self): params = ["'This' & \"That\""] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <string>'This' & "That"</string> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "String to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to string conversion")
def testConvertDouble(self): params = [3.14159265] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <double>3.14159265</double> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Double to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to double conversion")
def testConvertDateTime(self): params = [rpctime("20111220T01:50:00")] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <dateTime.iso8601>20111220T01:50:00</dateTime.iso8601> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "DateTime to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(list(map(lambda x: x.iso8601(), params)), list(map(lambda x: x.iso8601(), xml2py(expected_xml))), None)
def _on_jabber_rpc_method_call(self, iq): iq.enable('rpc_query') params = iq['rpc_query']['method_call']['params'] args = xml2py(params) pmethod = iq['rpc_query']['method_call']['method_name'] try: with self._lock: entry = self._entries[pmethod] rules = self._acls[entry.get_endpoint_FQN()] if ACL.check(rules, iq['from'], pmethod): return_value = entry.call_method(args) else: raise AuthorizationException( "Unauthorized access to %s from %s!" % (pmethod, iq['from'])) if return_value is None: return_value = () response = self._client.plugin['xep_0009'].make_iq_method_response( iq['id'], iq['from'], py2xml(*return_value)) response.send() except InvocationException as ie: fault = dict() fault['code'] = 500 fault['string'] = ie.get_message() self._client.plugin['xep_0009']._send_fault(iq, fault2xml(fault)) except AuthorizationException as ae: log.error(ae.get_message()) error = self._client.plugin['xep_0009']._forbidden(iq) error.send() except Exception as e: if isinstance(e, KeyError): log.error("No handler available for %s!", pmethod) error = self._client.plugin['xep_0009']._item_not_found(iq) else: traceback.print_exc(file=sys.stderr) log.error("An unexpected problem occurred invoking method %s!", pmethod) error = self._client.plugin['xep_0009']._undefined_condition( iq) #! print "[REMOTE.PY] _handle_remote_procedure_call AN ERROR SHOULD BE SENT NOW %s " % e error.send()
def testConvertInteger(self): params = [32767, -32768] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <i4>32767</i4> </value> </param> <param> <value> <i4>-32768</i4> </value> </param> </params> """) alternate_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <int>32767</int> </value> </param> <param> <value> <int>-32768</int> </value> </param> </params> """) self.assertTrue( self.compare(expected_xml, params_xml), "Integer to XML conversion\nExpected: %s\nGot: %s" % (tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to boolean conversion") self.assertEqual(params, xml2py(alternate_xml), "Alternate XML to boolean conversion")
def testConvertBoolean(self): params = [True, False] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <boolean>1</boolean> </value> </param> <param> <value> <boolean>0</boolean> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Boolean to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to boolean conversion")
def testConvertInteger(self): params = [32767, -32768] params_xml = py2xml(*params) expected_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <i4>32767</i4> </value> </param> <param> <value> <i4>-32768</i4> </value> </param> </params> """) alternate_xml = self.parse_xml(""" <params xmlns="jabber:iq:rpc"> <param> <value> <int>32767</int> </value> </param> <param> <value> <int>-32768</int> </value> </param> </params> """) self.assertTrue(self.compare(expected_xml, params_xml), "Integer to XML conversion\nExpected: %s\nGot: %s" % ( tostring(expected_xml), tostring(params_xml))) self.assertEqual(params, xml2py(expected_xml), "XML to boolean conversion") self.assertEqual(params, xml2py(alternate_xml), "Alternate XML to boolean conversion")
def _on_jabber_rpc_method_call(self, iq): iq.enable('rpc_query') params = iq['rpc_query']['method_call']['params'] args = xml2py(params) pmethod = iq['rpc_query']['method_call']['method_name'] try: with self._lock: entry = self._entries[pmethod] rules = self._acls[entry.get_endpoint_FQN()] if ACL.check(rules, iq['from'], pmethod): return_value = entry.call_method(args) else: raise AuthorizationException("Unauthorized access to %s from %s!" % (pmethod, iq['from'])) if return_value is None: return_value = () response = self._client.plugin['xep_0009'].make_iq_method_response(iq['id'], iq['from'], py2xml(*return_value)) response.send() except InvocationException as ie: fault = dict() fault['code'] = 500 fault['string'] = ie.get_message() self._client.plugin['xep_0009']._send_fault(iq, fault2xml(fault)) except AuthorizationException as ae: log.error(ae.get_message()) error = self._client.plugin['xep_0009']._forbidden(iq) error.send() except Exception as e: if isinstance(e, KeyError): log.error("No handler available for %s!", pmethod) error = self._client.plugin['xep_0009']._item_not_found(iq) else: traceback.print_exc(file=sys.stderr) log.error("An unexpected problem occurred invoking method %s!", pmethod) error = self._client.plugin['xep_0009']._undefined_condition(iq) #! print "[REMOTE.PY] _handle_remote_procedure_call AN ERROR SHOULD BE SENT NOW %s " % e error.send()