def test_39464(q, bus, conn, stream): """ Regression test for an issue where a form with no type='' attribute on the <x/> node would crash Gabble. """ client = 'fake:qutim' hash = 'blahblah' contact = '[email protected]/foo' caps = { 'node': client, 'ver': hash, 'hash': 'sha-1', } presence = make_presence(contact, status='hello', caps=caps) stream.send(presence) # Gabble looks up our capabilities event = q.expect('stream-iq', to=contact, query_ns=ns.DISCO_INFO) # Send a reply with a form without a type='' result = make_result_iq(stream, event.stanza, add_query_node=False) result.addChild( elem(ns.DISCO_INFO, 'query', node='%s#%s' % (client, hash))( # NB. no type='' attribute elem(ns.X_DATA, 'x') ) ) stream.send(result) # We don't really care what Gabble does, as long as it doesn't crash. sync_stream(q, stream)
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) # Force Gabble to process the vCard before calling any methods. sync_stream(q, stream) handle = conn.Properties.Get(cs.CONN, "SelfHandle") call_async(q, conn.Avatars, 'SetAvatar', 'william shatner', 'image/x-actor-name') event = q.expect('stream-iq', iq_type='get', to=None, query_ns='vcard-temp', query_name='vCard') reply = make_result_iq(stream, event.stanza) reply['type'] = 'error' reply.addChild( elem('error')(elem(ns.STANZA, 'forbidden')(), elem(ns.STANZA, 'text')(u'zomg whoops'))) stream.send(reply) event = q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
def test(q, bus, conn, stream): # The user happily joins a MUC _, chan, _, _ = join_muc(q, bus, conn, stream, MUC) muc_self_handle = chan.Group.GetSelfHandle() muc_self_jid, = conn.InspectHandles(cs.HT_CONTACT, [muc_self_handle]) # But then Bob kicks us. bob_jid = "%s/bob" % MUC bob_handle, = conn.RequestHandles(cs.HT_CONTACT, [bob_jid]) stream.send( elem("presence", from_=muc_self_jid, type="unavailable")( elem(ns.MUC_USER, "x")( elem("item", affiliation="none", role="none")(elem("actor", jid=bob_jid), elem("reason")(u"bye")), elem("status", code="307"), ) ) ) mcd_event = q.expect("dbus-signal", signal="MembersChangedDetailed") added, removed, local_pending, remote_pending, details = mcd_event.args assertEquals([], added) assertEquals([muc_self_handle], removed) assertEquals([], local_pending) assertEquals([], remote_pending) assertContains("actor", details) assertEquals(bob_handle, details["actor"]) assertEquals(cs.GC_REASON_KICKED, details["change-reason"]) assertEquals("bye", details["message"]) q.expect("dbus-signal", signal="ChannelClosed")
def test_privacy_list_push_conflict(q, bus, conn, stream): test_invisible_on_connect(q, bus, conn, stream) set_id = stream.send_privacy_list_push_iq("invisible") _, req_list = q.expect_many( EventPattern('stream-iq', iq_type='result', predicate=lambda event: \ event.stanza['id'] == set_id), EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type="get")) stream.send_privacy_list(req_list.stanza, [elem('item', type='jid', value='*****@*****.**', action='allow', order='1')(elem('presence-out')), elem('item', action='deny', order='2')(elem('presence-out'))]) create_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') created = xpath.queryForNodes('//list', create_list.stanza)[0] assertEquals(created["name"], 'invisible-gabble') acknowledge_iq(stream, create_list.stanza) set_active = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', set_active.query)[0] assertEquals('invisible-gabble', active['name']) acknowledge_iq(stream, set_active.stanza)
def test_invisible_on_connect(q, bus, conn, stream): props = conn.Properties.GetAll(cs.CONN_IFACE_SIMPLE_PRESENCE) assertNotEquals({}, props['Statuses']) presence_event_pattern = EventPattern('stream-presence') q.forbid_events([presence_event_pattern]) conn.SimplePresence.SetPresence("hidden", "") conn.Connect() stream.handle_get_all_privacy_lists(q, bus, conn, ['invisible']) get_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='get') list_node = xpath.queryForNodes('//list', get_list.query)[0] assertEquals('invisible', list_node['name']) stream.send_privacy_list(get_list.stanza, [elem('item', action='deny', order='1')(elem('presence-out'))]) set_active = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', set_active.query)[0] assertEquals('invisible', active['name']) acknowledge_iq(stream, set_active.stanza) q.unforbid_events([presence_event_pattern]) q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
def test_message(q, bus, conn, stream): jid = '*****@*****.**' tube_chan, tube_path, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid) bob_jid = '%s/bob' % jid bob_handle = conn.get_contact_handle_sync(bob_jid) # now let's send a message stream.send( elem('message', from_=bob_jid, type='groupchat')( elem('body')(u'oh hey i didnt see you there'), )) # the text channel appears! e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assertEquals(1, len(channels)) path, props = channels[0] assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE]) # make sure we didn't request it assertEquals(False, props[cs.REQUESTED]) assertEquals(bob_handle, props[cs.INITIATOR_HANDLE]) # and the message is then signalled e = q.expect('dbus-signal', signal='MessageReceived', path=path) parts = e.args[0] header = parts[0] assertEquals(bob_handle, header['message-sender']) assertEquals(bob_jid, header['message-sender-id']) body = parts[1] assertEquals('oh hey i didnt see you there', body['content'])
def gadget_publish(q, stream, conn, publish): gadget_iface = dbus.Interface(conn, 'org.laptop.Telepathy.Gadget') call_async(q, gadget_iface, 'Publish', publish) if publish: q.expect_many( EventPattern('stream-presence', presence_type='subscribe'), EventPattern('dbus-return', method='Publish')) # accept the request presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribed') stream.send(presence) # send a subscribe request presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribe') stream.send(presence) q.expect('stream-presence', presence_type='subscribed'), else: q.expect_many( EventPattern('stream-presence', presence_type='unsubscribe'), EventPattern('stream-presence', presence_type='unsubscribed'), EventPattern('dbus-return', method='Publish')) # Gadget tries to subscribe but is refused now presence = elem('presence', to='test@localhost', from_='gadget.localhost', type='subscribe') stream.send(presence)
def test_invisible_on_connect(q, bus, conn, stream): props = conn.Properties.GetAll(cs.CONN_IFACE_SIMPLE_PRESENCE) assertNotEquals({}, props['Statuses']) presence_event_pattern = EventPattern('stream-presence') q.forbid_events([presence_event_pattern]) conn.SimplePresence.SetPresence("hidden", "") conn.Connect() stream.handle_get_all_privacy_lists(q, bus, conn, ['invisible']) get_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='get') list_node = xpath.queryForNodes('//list', get_list.query)[0] assertEquals('invisible', list_node['name']) stream.send_privacy_list( get_list.stanza, [elem('item', action='deny', order='1')(elem('presence-out'))]) set_active = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', set_active.query)[0] assertEquals('invisible', active['name']) acknowledge_iq(stream, set_active.stanza) q.unforbid_events([presence_event_pattern]) q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
def test(q, bus, conn, stream): conn.Connect() _, event = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard')) acknowledge_iq(stream, event.stanza) # Force Gabble to process the vCard before calling any methods. sync_stream(q, stream) handle = conn.GetSelfHandle() call_async(q, conn.Avatars, 'SetAvatar', 'william shatner', 'image/x-actor-name') event = q.expect('stream-iq', iq_type='get', to=None, query_ns='vcard-temp', query_name='vCard') reply = make_result_iq(stream, event.stanza) reply['type'] = 'error' reply.addChild(elem('error')( elem(ns.STANZA, 'forbidden')(), elem(ns.STANZA, 'text')(u'zomg whoops'))) stream.send(reply) event = q.expect('dbus-error', method='SetAvatar', name=cs.NOT_AVAILABLE)
def test_privacy_list_push_conflict(q, bus, conn, stream): test_invisible_on_connect(q, bus, conn, stream) set_id = stream.send_privacy_list_push_iq("invisible") _, req_list = q.expect_many( EventPattern('stream-iq', iq_type='result', iq_id=set_id), EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type="get")) stream.send_privacy_list(req_list.stanza, [ elem('item', type='jid', value='*****@*****.**', action='allow', order='1')(elem('presence-out')), elem('item', action='deny', order='2')(elem('presence-out')) ]) create_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') created = xpath.queryForNodes('//list', create_list.stanza)[0] assertEquals(created["name"], 'invisible-gabble') acknowledge_iq(stream, create_list.stanza) set_active = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', set_active.query)[0] assertEquals('invisible-gabble', active['name']) acknowledge_iq(stream, set_active.stanza)
def announce_socks5_proxy(q, stream, disco_stanza): reply = make_result_iq(stream, disco_stanza) query = xpath.queryForNodes('/iq/query', reply)[0] item = query.addElement((None, 'item')) item['jid'] = 'proxy.localhost' stream.send(reply) # wait for proxy disco#info query event = q.expect('stream-iq', to='proxy.localhost', query_ns=ns.DISCO_INFO, iq_type='get') reply = elem_iq(stream, 'result', from_='proxy.localhost', id=event.stanza['id'])( elem(ns.DISCO_INFO, 'query')( elem('identity', category='proxy', type='bytestreams', name='SOCKS5 Bytestreams')(), elem('feature', var=ns.BYTESTREAMS)())) stream.send(reply) # Gabble asks for SOCKS5 info event = q.expect('stream-iq', to='proxy.localhost', query_ns=ns.BYTESTREAMS, iq_type='get') port = listen_socks5(q) reply = elem_iq(stream, 'result', id=event.stanza['id'], from_='proxy.localhost')( elem(ns.BYTESTREAMS, 'query')( elem('streamhost', jid='proxy.localhost', host='127.0.0.1', port=str(port))())) stream.send(reply)
def send_own_message(to, text): iq = elem_iq(stream, 'set', from_='chat.facebook.com')( elem(NS_FACEBOOK_MESSAGES, 'own-message', to=to, self='false')( elem('body')(text) ) ) stream.send(iq) q.expect('stream-iq', iq_type='result', iq_id=iq['id'])
def send_privacy_list(self, req_iq, list_items): req_list = xpath.queryForNodes('//list', req_iq)[0] iq = elem_iq(self, "result", id=req_iq["id"])( elem(ns.PRIVACY, 'query')( elem('list', name=req_list["name"])(*list_items) ) ) self.send(iq)
def send_privacy_list_push_iq(self, list_name): iq = elem_iq(self, 'set')( elem(ns.PRIVACY, 'query')( elem('list', name=list_name) ) ) self.send(iq) return iq["id"]
def test(q, bus, conn, stream): jids = ['*****@*****.**', '*****@*****.**', ] gregory, hawk = jids gregory_handle, hawk_handle = conn.get_contact_handles_sync(jids) event = q.expect('stream-iq', query_ns=ns.ROSTER) event.stanza['type'] = 'result' for jid in jids: item = event.query.addElement('item') item['jid'] = jid item['subscription'] = 'both' stream.send(event.stanza) q.expect('dbus-signal', signal='PresencesChanged', args=[{gregory_handle: (cs.PRESENCE_OFFLINE, 'offline', ''), hawk_handle: (cs.PRESENCE_OFFLINE, 'offline', ''), } ]) # Our server can't resolve unreachable.example.com so it sends us an error # presence for Gregory. (This is what Prosody actually does.) presence = make_presence(gregory, type='error') error_text = u'Connection failed: DNS resolution failed' presence.addChild( elem('error', type='cancel')( elem(ns.STANZA, 'remote-server-not-found'), elem(ns.STANZA, 'text')( error_text ) )) stream.send(presence) e = q.expect('dbus-signal', signal='PresencesChanged') presences, = e.args type_, status, message = presences[gregory_handle] assertEquals(cs.PRESENCE_ERROR, type_) assertEquals('error', status) assertEquals(error_text, message) # How about maybe the hawk's server is busted? presence = make_presence(hawk, type='error') presence.addChild( elem('error', type='cancel')( elem(ns.STANZA, 'internal-server-error'), )) stream.send(presence) e = q.expect('dbus-signal', signal='PresencesChanged') presences, = e.args type_, status, message = presences[hawk_handle] assertEquals(cs.PRESENCE_ERROR, type_) assertEquals('error', status) # FIXME: It might be less user-hostile to give some kind of readable # description of the error in future. assertEquals('internal-server-error', message)
def send_own_message(to, text): iq = elem_iq(stream, 'set', from_='chat.facebook.com')(elem(NS_FACEBOOK_MESSAGES, 'own-message', to=to, self='false')( elem('body')(text))) stream.send(iq) q.expect('stream-iq', iq_type='result', iq_id=iq['id'])
def test(q, bus, conn, stream): conn.Connect() _, event = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard')) acknowledge_iq(stream, event.stanza) handle = conn.RequestHandles(cs.HT_CONTACT, ['*****@*****.**'])[0] call_async(q, conn.Aliasing, 'RequestAliases', [handle]) event = q.expect('stream-iq', to='*****@*****.**', iq_type='get', query_ns=ns.PUBSUB, query_name='pubsub') items = event.query.firstChildElement() assertEquals('items', items.name) assertEquals(ns.NICK, items['node']) result = make_result_iq(stream, event.stanza) pubsub = result.firstChildElement() items = pubsub.addElement('items') items['node'] = ns.NICK item = items.addElement('item') item.addElement('nick', ns.NICK, content='Bobby') stream.send(result) q.expect('dbus-signal', signal='AliasesChanged', args=[[(handle, u'Bobby')]]) q.expect('dbus-return', method='RequestAliases', value=(['Bobby'],)) # A second request should be satisfied from the cache. assertEquals(['Bobby'], conn.Aliasing.RequestAliases([handle])) # Bobby grows up, decides he hates his nickname. # This is a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=21817>, where this would # crash Gabble. message = elem('message', from_='*****@*****.**')( elem((ns.PUBSUB + "#event"), 'event')( elem('items', node=ns.NICK)( elem('item')( elem(ns.NICK, 'nick') ) ) ) ) stream.send(message.toXml()) event = q.expect('dbus-signal', signal='AliasesChanged') aliases = event.args[0] assertLength(1, aliases) h, a = aliases[0] assertEquals(handle, h) # The contact explicitly cleared their PEP nick; Gabble should fall back to # their JID. assertEquals(a, '*****@*****.**')
def _make_pubsub_event_msg(from_, node): # manually create the item node as we need a ref on it item = domish.Element((None, 'item')) message = elem('message', from_=from_, to='test@localhost')( elem(ns.PUBSUB_EVENT, 'event')( elem('items', node=node)(item))) return message, item
def test(q, bus, conn, stream): jids = [ '*****@*****.**', '*****@*****.**', ] gregory, hawk = jids gregory_handle, hawk_handle = conn.get_contact_handles_sync(jids) event = q.expect('stream-iq', query_ns=ns.ROSTER) event.stanza['type'] = 'result' for jid in jids: item = event.query.addElement('item') item['jid'] = jid item['subscription'] = 'both' stream.send(event.stanza) q.expect('dbus-signal', signal='PresencesChanged', args=[{ gregory_handle: (cs.PRESENCE_OFFLINE, 'offline', ''), hawk_handle: (cs.PRESENCE_OFFLINE, 'offline', ''), }]) # Our server can't resolve unreachable.example.com so it sends us an error # presence for Gregory. (This is what Prosody actually does.) presence = make_presence(gregory, type='error') error_text = u'Connection failed: DNS resolution failed' presence.addChild( elem('error', type='cancel')(elem(ns.STANZA, 'remote-server-not-found'), elem(ns.STANZA, 'text')(error_text))) stream.send(presence) e = q.expect('dbus-signal', signal='PresencesChanged') presences, = e.args type_, status, message = presences[gregory_handle] assertEquals(cs.PRESENCE_ERROR, type_) assertEquals('error', status) assertEquals(error_text, message) # How about maybe the hawk's server is busted? presence = make_presence(hawk, type='error') presence.addChild( elem('error', type='cancel')(elem(ns.STANZA, 'internal-server-error'), )) stream.send(presence) e = q.expect('dbus-signal', signal='PresencesChanged') presences, = e.args type_, status, message = presences[hawk_handle] assertEquals(cs.PRESENCE_ERROR, type_) assertEquals('error', status) # FIXME: It might be less user-hostile to give some kind of readable # description of the error in future. assertEquals('internal-server-error', message)
def send_gadget_current_activity_changed_msg(stream, buddy, view_id, id, room): message = elem('message', from_='gadget.localhost', to='test@localhost', type='notice')( elem(ns.OLPC_BUDDY, 'change', jid=buddy, id=view_id)( elem(ns.OLPC_CURRENT_ACTIVITY, 'activity', id=id, room=room)()), elem(ns.AMP, 'amp')( elem('rule', condition='deliver-at', value='stored', action='error'))) stream.send(message)
def make_pubsub_event(from_, node, *contents): return elem('message', from_=from_)( elem((ns.PUBSUB_EVENT), 'event')( elem('items', node=node)( elem('item')( *contents ) ) ) )
def _make_pubsub_event_msg(from_, node): # manually create the item node as we need a ref on it item = domish.Element((None, 'item')) message = elem('message', from_=from_, to='test@localhost')(elem(ns.PUBSUB_EVENT, 'event')(elem('items', node=node)(item))) return message, item
def bob_in_tube(): presence = elem('presence', from_='[email protected]/bob', to='*****@*****.**')( elem('x', xmlns=ns.MUC_USER), elem('tubes', xmlns=ns.TUBES)( elem('tube', type='dbus', initiator='[email protected]/test', service='com.example.TestCase', id=str(dbus_tube_id))(elem('parameters')( elem('parameter', name='ay', type='bytes')(u'aGVsbG8='), elem('parameter', name='s', type='str')(u'hello'), elem('parameter', name='i', type='int')(u'-123'), elem('parameter', name='u', type='uint')(u'123'))))) # have to add stream-id and dbus-name attributes manually as we can't use # keyword with '-'... tube_node = xpath.queryForNodes('/presence/tubes/tube', presence)[0] tube_node['stream-id'] = dbus_stream_id tube_node['dbus-name'] = bob_bus_name stream.send(presence)
def test_requested_message(q, bus, conn, stream): jid = '*****@*****.**' self_handle = conn.Properties.Get(cs.CONN, 'SelfHandle') text_chan, text_path, _ = text_channel(q, bus, conn, stream, 'CreateChannel', jid) tube_chan, tube_path, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid, presence=False) bob_jid = '%s/bob' % jid bob_handle = conn.get_contact_handle_sync(bob_jid) # make sure it says we requested it props = text_chan.Properties.GetAll(cs.CHANNEL) assertEquals(True, props['Requested']) assertEquals(self_handle, props['InitiatorHandle']) text_chan.Close() expect_close(q, text_path) assert_on_bus(q, tube_chan) assert_not_on_bus(q, text_chan) # now let's send a message stream.send( elem('message', from_=bob_jid, type='groupchat')(elem('body')(u'hello again'), )) e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assertEquals(1, len(channels)) path, props = channels[0] assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE]) # now make sure we didn't request it assertEquals(False, props[cs.REQUESTED]) assertEquals(bob_handle, props[cs.INITIATOR_HANDLE]) e = q.expect('dbus-signal', signal='MessageReceived', path=path) parts = e.args[0] header = parts[0] assertEquals(bob_handle, header['message-sender']) assertEquals(bob_jid, header['message-sender-id']) body = parts[1] assertEquals('hello again', body['content']) assert_on_bus(q, tube_chan) assert_on_bus(q, text_chan)
def bob_in_tube(): presence = elem("presence", from_="[email protected]/bob", to="*****@*****.**")( elem("x", xmlns=ns.MUC_USER), elem("tubes", xmlns=ns.TUBES)( elem( "tube", type="dbus", initiator="[email protected]/test", service="com.example.TestCase", id=str(dbus_tube_id), )( elem("parameters")( elem("parameter", name="ay", type="bytes")(u"aGVsbG8="), elem("parameter", name="s", type="str")(u"hello"), elem("parameter", name="i", type="int")(u"-123"), elem("parameter", name="u", type="uint")(u"123"), ) ) ), ) # have to add stream-id and dbus-name attributes manually as we can't use # keyword with '-'... tube_node = xpath.queryForNodes("/presence/tubes/tube", presence)[0] tube_node["stream-id"] = dbus_stream_id tube_node["dbus-name"] = bob_bus_name stream.send(presence)
def _cb_bare_jid_disco_iq(self, iq): """ \o\ /o/ <o/ \o> /o> ... "Crap! It's the cops! Turn the music off!" """ send_error_reply(self, iq, error_stanza=elem('error')( elem(ns.STANZA, 'feature-not-implemented'), elem(ns.STANZA, 'text')( u'No, officer! This is certainly not an illegal party.') ))
def test(q, bus, conn, stream): room = '*****@*****.**' our_jid = room + '/test' bob_jid = room + '/bob' marco_jid = room + '/marco' room_handle, chan, test_handle, bob_handle = \ join_muc_and_check(q, bus, conn, stream, room) # Here are a few scrollback messages. One from us; one from bob; and one # from marco, who's no longer in the room. stream.send( elem('message', from_=our_jid, type='groupchat')( elem('body')( u'i really hate the muc xep' ), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:34:56') ) ) stream.send( elem('message', from_=bob_jid, type='groupchat')( elem('body')( u'yeah, it totally sucks' ), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:45:56') ) ) stream.send( elem('message', from_=marco_jid, type='groupchat')( elem('body')( u'we should start a riot' ), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:56:56') ) ) m1 = q.expect('dbus-signal', signal='MessageReceived') m2 = q.expect('dbus-signal', signal='MessageReceived') m3 = q.expect('dbus-signal', signal='MessageReceived') def badger(event): assertEquals(chan.object_path, event.path) message, = event.args header = message[0] assertContains('scrollback', header) assert header['scrollback'] assertContains('message-sender', header) return header['message-sender'] me = badger(m1) bob = badger(m2) marco = badger(m3) assertEquals([our_jid, bob_jid, marco_jid], conn.InspectHandles(cs.HT_CONTACT, [ me, bob, marco ]))
def test(q, bus, conn, stream): event = q.expect('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard') acknowledge_iq(stream, event.stanza) handle = conn.get_contact_handle_sync('*****@*****.**') call_async(q, conn.Aliasing, 'RequestAliases', [handle]) event = q.expect('stream-iq', to='*****@*****.**', iq_type='get', query_ns=ns.PUBSUB, query_name='pubsub') items = event.query.firstChildElement() assertEquals('items', items.name) assertEquals(ns.NICK, items['node']) result = make_result_iq(stream, event.stanza) pubsub = result.firstChildElement() items = pubsub.addElement('items') items['node'] = ns.NICK item = items.addElement('item') item.addElement('nick', ns.NICK, content='Bobby') stream.send(result) q.expect('dbus-signal', signal='AliasesChanged', args=[[(handle, u'Bobby')]]) q.expect('dbus-return', method='RequestAliases', value=(['Bobby'],)) # A second request should be satisfied from the cache. assertEquals(['Bobby'], conn.Aliasing.RequestAliases([handle])) # Bobby grows up, decides he hates his nickname. # This is a regression test for # <https://bugs.freedesktop.org/show_bug.cgi?id=21817>, where this would # crash Gabble. message = elem('message', from_='*****@*****.**')( elem((ns.PUBSUB_EVENT), 'event')( elem('items', node=ns.NICK)( elem('item')( elem(ns.NICK, 'nick') ) ) ) ) stream.send(message.toXml()) event = q.expect('dbus-signal', signal='AliasesChanged') aliases = event.args[0] assertLength(1, aliases) h, a = aliases[0] assertEquals(handle, h) # The contact explicitly cleared their PEP nick; Gabble should fall back to # their JID. assertEquals(a, '*****@*****.**')
def test(q, bus, conn, stream): try_to_join_muc(q, bus, conn, stream, MUC) stream.send( elem('presence', from_=MUC, type='error')(elem(ns.MUC, 'x'), elem('error', code='403', type='auth')(elem( ns.STANZA, 'forbidden'), elem(ns.STANZA, 'text')( u'Access denied by service policy', )))) q.expect('dbus-error', method='CreateChannel', name=cs.BANNED)
def test_requested_message(q, bus, conn, stream): jid = '*****@*****.**' self_handle = conn.Properties.Get(cs.CONN, 'SelfHandle') text_chan, text_path, _ = text_channel(q, bus, conn, stream,'CreateChannel', jid) tube_chan, tube_path, _ = stream_tube(q, bus, conn, stream, 'CreateChannel', jid, presence=False) bob_jid = '%s/bob' % jid bob_handle = conn.get_contact_handle_sync(bob_jid) # make sure it says we requested it props = text_chan.Properties.GetAll(cs.CHANNEL) assertEquals(True, props['Requested']) assertEquals(self_handle, props['InitiatorHandle']) text_chan.Close() expect_close(q, text_path) assert_on_bus(q, tube_chan) assert_not_on_bus(q, text_chan) # now let's send a message stream.send( elem('message', from_=bob_jid, type='groupchat')( elem('body')( u'hello again' ), ) ) e = q.expect('dbus-signal', signal='NewChannels') channels = e.args[0] assertEquals(1, len(channels)) path, props = channels[0] assertEquals(cs.CHANNEL_TYPE_TEXT, props[cs.CHANNEL_TYPE]) # now make sure we didn't request it assertEquals(False, props[cs.REQUESTED]) assertEquals(bob_handle, props[cs.INITIATOR_HANDLE]) e = q.expect('dbus-signal', signal='MessageReceived', path=path) parts = e.args[0] header = parts[0] assertEquals(bob_handle, header['message-sender']) assertEquals(bob_jid, header['message-sender-id']) body = parts[1] assertEquals('hello again', body['content']) assert_on_bus(q, tube_chan) assert_on_bus(q, text_chan)
def send_socks5_reply(stream, iq, jid=None, host=None, port=None): if jid is None: jid = iq['to'] if port is None: port = proxy_port[jid] if host is None: host = '127.0.0.1' reply = elem_iq(stream, 'result', id=iq['id'], from_=iq['to'])( elem(ns.BYTESTREAMS, 'query')( elem('streamhost', jid=jid, host=host, port=port)())) stream.send(reply)
def accept_stream_tube(q, bus, conn, stream): connect_and_announce_alice(q, bus, conn, stream) # Accept a stream tube, we'll need SOCKS5 proxies each time we'll connect # on the tube socket # Alice offers us a stream tube message = elem('message', to='test@localhost/Resource', from_='alice@localhost/Test')(elem(ns.TUBES, 'tube', type='stream', service='http', id='10')) stream.send(message) # we are interested in the 'NewChannels' announcing the tube channel def new_chan_predicate(e): path, props = e.args[0][0] return props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE # Proxy queries are send when receiving an incoming stream tube new_chan, e1, e2 = q.expect_many( EventPattern('dbus-signal', signal='NewChannels', predicate=new_chan_predicate), proxy_query_events[0], proxy_query_events[1]) send_socks5_reply(stream, e1.stanza) send_socks5_reply(stream, e2.stanza) path, props = new_chan.args[0][0] assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE tube_chan = bus.get_object(conn.bus_name, path) tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE) # connect to the socket so a SOCKS5 bytestream will be created address = tube_iface.Accept(cs.SOCKET_ADDRESS_TYPE_IPV4, cs.SOCKET_ACCESS_CONTROL_LOCALHOST, 0, byte_arrays=True) s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect(address) proxies = wait_si_and_return_proxies(q, stream) check_proxies([('fallback2-proxy.localhost', '127.0.0.1', '6789'), ('fallback1-proxy.localhost', '127.0.0.1', '12345')], proxies)
def test_invisible_on_connect_fail_invalid_list(q, bus, conn, stream, really_invalid=False): props = conn.Properties.GetAll(cs.CONN_IFACE_SIMPLE_PRESENCE) assertNotEquals({}, props['Statuses']) presence_event_pattern = EventPattern('stream-presence') q.forbid_events([presence_event_pattern]) conn.SimplePresence.SetPresence("hidden", "") conn.Connect() stream.handle_get_all_privacy_lists(q, bus, conn, ['invisible']) get_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='get') list_node = xpath.queryForNodes('//list', get_list.query)[0] assertEquals('invisible', list_node['name']) if really_invalid: # At one point Gabble would crash if the reply was of type 'result' but # wasn't well-formed. acknowledge_iq(stream, get_list.stanza) else: stream.send_privacy_list(get_list.stanza, [elem('item', type='jid', value='*****@*****.**', action='allow', order='1')(elem('presence-out')), elem('item', action='deny', order='2')(elem('presence-out'))]) create_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') created = xpath.queryForNodes('//list', create_list.stanza)[0] assertEquals(created["name"], 'invisible-gabble') acknowledge_iq (stream, create_list.stanza) q.unforbid_events([presence_event_pattern]) activate_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', activate_list.stanza)[0] assertEquals(active["name"], 'invisible-gabble') acknowledge_iq (stream, activate_list.stanza) q.expect_many( EventPattern('dbus-signal', signal='PresencesChanged', interface=cs.CONN_IFACE_SIMPLE_PRESENCE, args=[{1: (5, 'hidden', '')}]), EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])) # 'hidden' should not be an available status. assertContains("hidden", conn.Properties.Get(cs.CONN_IFACE_SIMPLE_PRESENCE, "Statuses"))
def test(q, bus, conn, stream): (muc_handle, chan, user, bob) = join_muc_and_check(q, bus, conn, stream, MUC) stream.send( elem('message', from_=BOB, to='test@localhost/Resource', type='groupchat', jid='*****@*****.**')( elem(ns.CHAT_STATES, 'composing'), elem('google:nosave', 'x', value='disabled'), elem('http://jabber.org/protocol/archive', 'record', otr='false'), )) e = q.expect('dbus-signal', signal='ChatStateChanged') contact, state = e.args assertEquals(bob, contact) assertEquals(cs.CHAT_STATE_COMPOSING, state) stream.send( elem('message', from_=BOB, to='test@localhost/Resource', type='groupchat', jid='*****@*****.**')( elem(ns.CHAT_STATES, 'paused'), elem('google:nosave', 'x', value='disabled'), elem('http://jabber.org/protocol/archive', 'record', otr='false'), )) e = q.expect('dbus-signal', signal='ChatStateChanged') contact, state = e.args assertEquals(bob, contact) assertEquals(cs.CHAT_STATE_PAUSED, state)
def test(q, bus, conn, stream): room = '*****@*****.**' our_jid = room + '/test' bob_jid = room + '/bob' marco_jid = room + '/marco' chan, test_handle, bob_handle = \ join_muc_and_check(q, bus, conn, stream, room) # Here are a few scrollback messages. One from us; one from bob; and one # from marco, who's no longer in the room. stream.send( elem('message', from_=our_jid, type='groupchat')(elem('body')(u'i really hate the muc xep'), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:34:56'))) stream.send( elem('message', from_=bob_jid, type='groupchat')(elem('body')(u'yeah, it totally sucks'), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:45:56'))) stream.send( elem('message', from_=marco_jid, type='groupchat')(elem('body')(u'we should start a riot'), elem(ns.X_DELAY, 'x', from_=room, stamp='20090910T12:56:56'))) m1 = q.expect('dbus-signal', signal='MessageReceived') m2 = q.expect('dbus-signal', signal='MessageReceived') m3 = q.expect('dbus-signal', signal='MessageReceived') def badger(event): assertEquals(chan.object_path, event.path) message, = event.args header = message[0] assertContains('scrollback', header) assert header['scrollback'] assertContains('message-sender', header) return header['message-sender'] me = badger(m1) bob = badger(m2) marco = badger(m3) assertEquals([our_jid, bob_jid, marco_jid], conn.inspect_contacts_sync([me, bob, marco]))
def test(q, bus, conn, stream): try_to_join_muc(q, bus, conn, stream, MUC) stream.send( elem('presence', from_=MUC, type='error')( elem(ns.MUC, 'x'), elem('error', code='403', type='auth')( elem(ns.STANZA, 'forbidden'), elem(ns.STANZA, 'text')( u'Access denied by service policy', ) ) )) q.expect('dbus-error', method='CreateChannel', name=cs.BANNED)
def disco_caps(q, stream, presence): c_nodes = xpath.queryForNodes('/presence/c', presence.stanza) assert c_nodes is not None assertLength(1, c_nodes) hash = c_nodes[0].attributes['hash'] ver = c_nodes[0].attributes['ver'] node = c_nodes[0].attributes['node'] assertEquals('sha-1', hash) # ask caps request = \ elem_iq(stream, 'get', from_='[email protected]/resource')( elem(ns.DISCO_INFO, 'query', node=(node + '#' + ver)) ) stream.send(request) # receive caps event = q.expect('stream-iq', query_ns=ns.DISCO_INFO, iq_id=request['id']) # Check that Gabble's announcing the identity we think it should be. (identities, features, dataforms) = extract_disco_parts(event.stanza) # Check if the hash matches the announced capabilities assertEquals(compute_caps_hash(identities, features, dataforms), ver) return (event, features, dataforms)
def send_socks5_reply(stream, iq, jid=None, host=None, port=None): if jid is None: jid = iq['to'] if port is None: port = proxy_port[jid] if host is None: host = '127.0.0.1' reply = elem_iq(stream, 'result', id=iq['id'], from_=iq['to'])(elem(ns.BYTESTREAMS, 'query')(elem('streamhost', jid=jid, host=host, port=port)())) stream.send(reply)
def send_unrecognised_get(q, stream): stream.send( elem_iq(stream, 'get')( elem('urn:unimaginative', 'dont-handle-me-bro') )) return q.expect('stream-iq', iq_type='error')
def _cb_presence_iq(self, stanza): nodes = xpath.queryForNodes("/presence/c", stanza) c = nodes[0] if 'share-v1' in c.getAttribute('ext'): assert FileTransferTest.caps_identities is not None and \ FileTransferTest.caps_features is not None and \ FileTransferTest.caps_dataforms is not None new_hash = compute_caps_hash(FileTransferTest.caps_identities, FileTransferTest.caps_features + \ [ns.GOOGLE_FEAT_SHARE], FileTransferTest.caps_dataforms) # Replace ver hash from one with file-transfer ns to one without FileTransferTest.caps_ft = c.attributes['ver'] c.attributes['ver'] = new_hash else: node = c.attributes['node'] ver = c.attributes['ver'] # ask for raw caps request = elem_iq(self.stream, 'get', from_='[email protected]/resource')(elem( ns.DISCO_INFO, 'query', node=(node + '#' + ver))) self.stream.send(request)
def test(q, bus, conn, stream): jid = '*****@*****.**' iq = elem_iq(stream, 'get', from_=jid)(elem(ns.DISCO_INFO, 'query')) stream.send(iq) event = q.expect('stream-iq', iq_type='result', to='*****@*****.**') assertEquals(iq['id'], event.stanza['id'])
def _send(self, from_, to, data): id = random.randint(0, sys.maxint) iq = elem_iq(self.stream, 'set', from_=from_, to=to, id=str(id))( elem('data', xmlns=ns.IBB, sid=self.stream_id, seq=str(self.seq))( (unicode(base64.b64encode(data))))) self.stream.send(iq)
def announce_gadget(q, stream, disco_stanza): # announce Gadget service reply = make_result_iq(stream, disco_stanza) query = xpath.queryForNodes('/iq/query', reply)[0] item = query.addElement((None, 'item')) item['jid'] = 'gadget.localhost' stream.send(reply) # wait for Gadget disco#info query event = q.expect('stream-iq', to='gadget.localhost', query_ns=ns.DISCO_INFO) reply = elem_iq(stream, 'result', id=event.stanza['id'], from_='gadget.localhost')( elem(ns.DISCO_INFO, 'query')( elem('identity', category='collaboration', type='gadget', name='OLPC Gadget')(), elem('feature', var=ns.OLPC_BUDDY)(), elem('feature', var=ns.OLPC_ACTIVITY)())) stream.send(reply)
def server_discovered(q, bus, conn, stream, server=None): iq_event, disco_event = q.expect_many( EventPattern('stream-iq', to=None, query_ns='vcard-temp', query_name='vCard'), EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS)) acknowledge_iq(stream, iq_event.stanza) # no search server has been discovered yet. The CreateChannel operation # will be completed once the disco process is finished. call_create(q, conn, server=server) # reply to IQ query reply = make_result_iq(stream, disco_event.stanza) query = xpath.queryForNodes('/iq/query', reply)[0] item = query.addElement((None, 'item')) item['jid'] = JUD_SERVER stream.send(reply) # wait for the disco#info query event = q.expect('stream-iq', to=JUD_SERVER, query_ns=ns.DISCO_INFO) reply = elem_iq(stream, 'result', id=event.stanza['id'], from_=JUD_SERVER)( elem(ns.DISCO_INFO, 'query')(elem('identity', category='directory', type='user', name='vCard User Search')(), elem('feature', var=ns.SEARCH)())) stream.send(reply) # JUD_SERVER is used as default, and shows up as the Server property on the # resulting channel. ret, _ = answer_field_query(q, stream, JUD_SERVER) _, properties = ret.value assertEquals(JUD_SERVER, properties[cs.CONTACT_SEARCH_SERVER]) # Now that the search server has been discovered, it is used right away. call_create(q, conn, server=server) ret, _ = answer_field_query(q, stream, JUD_SERVER) _, properties = ret.value assertEquals(JUD_SERVER, properties[cs.CONTACT_SEARCH_SERVER])
def test_with_password(q, bus, conn, stream): room = '*****@*****.**' call_async( q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_ID: room }) expected_muc_jid = '%s/%s' % (room, 'test') q.expect('stream-presence', to=expected_muc_jid) # tell gabble the room needs a password stream.send( elem('jabber:client', 'presence', from_=expected_muc_jid, type='error')( elem(ns.MUC, 'x'), elem('error', type='auth')(elem(ns.STANZA, 'not-authorized'), ), )) cc, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='PasswordFlagsChanged', args=[cs.PASSWORD_FLAG_PROVIDE, 0])) chan = wrap_channel(bus.get_object(conn.bus_name, cc.value[0]), 'Text') forbidden = [EventPattern('stream-presence', to=expected_muc_jid)] q.forbid_events(forbidden) # we call Close... call_async(q, chan, 'Close') # ...but this time no unavailable presence because we were in the # auth state, so the channel closes immediately. q.expect_many(EventPattern('dbus-return', method='Close'), EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed')) q.unforbid_events(forbidden)
def test_with_password(q, bus, conn, stream): room = '*****@*****.**' handle = request_muc_handle(q, conn, stream, room) call_async(q, conn.Requests, 'CreateChannel', { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.TARGET_HANDLE: handle}) expected_muc_jid = '%s/%s' % (room, 'test') q.expect('stream-presence', to=expected_muc_jid) # tell gabble the room needs a password stream.send( elem('jabber:client', 'presence', from_=expected_muc_jid, type='error')( elem(ns.MUC, 'x'), elem('error', type='auth')( elem(ns.STANZA, 'not-authorized'), ), )) cc, _ = q.expect_many( EventPattern('dbus-return', method='CreateChannel'), EventPattern('dbus-signal', signal='PasswordFlagsChanged', args=[cs.PASSWORD_FLAG_PROVIDE, 0])) chan = wrap_channel(bus.get_object(conn.bus_name, cc.value[0]), 'Text') forbidden = [EventPattern('stream-presence', to=expected_muc_jid)] q.forbid_events(forbidden) # we call Close... call_async(q, chan, 'Close') # ...but this time no unavailable presence because we were in the # auth state, so the channel closes immediately. q.expect_many(EventPattern('dbus-return', method='Close'), EventPattern('dbus-signal', signal='Closed'), EventPattern('dbus-signal', signal='ChannelClosed')) q.unforbid_events(forbidden)
def test_privacy_list_push_valid(q, bus, conn, stream): test_invisible_on_connect(q, bus, conn, stream) set_id = stream.send_privacy_list_push_iq("invisible") _, req_list = q.expect_many( EventPattern('stream-iq', iq_type='result', iq_id=set_id), EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type="get")) stream.send_privacy_list(req_list.stanza, [elem('item', action='deny', order='1')(elem(u'presence-out')), elem('item', type='jid', value='*****@*****.**', action='deny', order='2')(elem(u'message'))]) # We redundantly re-activate the 'invisible' list. These lines also # check to see that we didn't switch over to 'invisible-gabble' activate_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', activate_list.stanza)[0] assertEquals(active["name"], 'invisible') acknowledge_iq (stream, activate_list.stanza)
def _send(self, from_, to, data): id = random.randint(0, sys.maxsize) iq = elem_iq(self.stream, 'set', from_=from_, to=to, id=str(id))(elem('data', xmlns=ns.IBB, sid=self.stream_id, seq=str(self.seq))( (base64.b64encode(data).decode()))) self.stream.send(iq)
def test(q, bus, conn, stream): # The user happily joins a MUC chan, _, _ = join_muc(q, bus, conn, stream, MUC) muc_self_handle = chan.Properties.Get(cs.CHANNEL_IFACE_GROUP, "SelfHandle") muc_self_jid = conn.inspect_contact_sync(muc_self_handle) # But then Bob kicks us. bob_jid = '%s/bob' % MUC bob_handle = conn.get_contact_handle_sync(bob_jid) stream.send( elem('presence', from_=muc_self_jid, type='unavailable')(elem(ns.MUC_USER, 'x')( elem('item', affiliation='none', role='none')(elem('actor', jid=bob_jid), elem('reason')(u'bye')), elem('status', code='307'), ))) mcd_event = q.expect('dbus-signal', signal='MembersChangedDetailed') added, removed, local_pending, remote_pending, details = mcd_event.args assertEquals([], added) assertEquals([muc_self_handle], removed) assertEquals([], local_pending) assertEquals([], remote_pending) assertContains('actor', details) assertEquals(bob_handle, details['actor']) assertEquals(cs.GC_REASON_KICKED, details['change-reason']) assertEquals('bye', details['message']) q.expect('dbus-signal', signal='ChannelClosed')
def _send_status_list(self, iq_id=None): if iq_id is None: iq_id = str(int(time())) iq_type = "set" else: iq_type = "result" status, show, invisible = self.shared_status elems = [] elems.append(elem('status')(status)) elems.append(elem('show')(show)) for show, statuses in self.shared_status_lists.items(): lst = [] for _status in statuses: lst.append(elem('status')(_status)) elems.append(elem('status-list', show=show)(*lst)) elems.append(elem('invisible', value=invisible)()) attribs = { 'status-max': self.max_status_message_length, 'status-list-max': '3', 'status-list-contents-max': self.max_statuses, 'status-min-ver': self.min_version } iq = elem_iq(self, iq_type, id=iq_id)(elem(ns.GOOGLE_SHARED_STATUS, 'query', **attribs)(*elems)) self.send(iq)
def announce_socks5_proxy(q, stream, disco_stanza): reply = make_result_iq(stream, disco_stanza) query = xpath.queryForNodes('/iq/query', reply)[0] item = query.addElement((None, 'item')) item['jid'] = 'proxy.localhost' stream.send(reply) # wait for proxy disco#info query event = q.expect('stream-iq', to='proxy.localhost', query_ns=ns.DISCO_INFO, iq_type='get') reply = elem_iq(stream, 'result', from_='proxy.localhost', id=event.stanza['id'])(elem(ns.DISCO_INFO, 'query')( elem('identity', category='proxy', type='bytestreams', name='SOCKS5 Bytestreams')(), elem('feature', var=ns.BYTESTREAMS)())) stream.send(reply) # Gabble asks for SOCKS5 info event = q.expect('stream-iq', to='proxy.localhost', query_ns=ns.BYTESTREAMS, iq_type='get') port = listen_socks5(q) reply = elem_iq(stream, 'result', id=event.stanza['id'], from_='proxy.localhost')(elem(ns.BYTESTREAMS, 'query')( elem('streamhost', jid='proxy.localhost', host='127.0.0.1', port=str(port))())) stream.send(reply)
def test(q, bus, conn, stream): e = q.expect('stream-iq', iq_type='get', query_ns=ns.ROSTER) e.stanza['type'] = 'result' e.query.addChild( elem('item', jid='*****@*****.**', subscription='both')) stream.send(e.stanza) # Romeo's on the roster. stream.send( elem_iq(stream, 'get', from_='*****@*****.**')( elem(ns.LAST, 'query') ) ) e = q.expect('stream-iq', iq_type='result', query_ns=ns.LAST, query_name='query') # No real assertions about the number of seconds; this is just a smoke # test. seconds = int(e.query['seconds']) assert seconds >= 0 # Juliet is not. stream.send( elem_iq(stream, 'get', from_='*****@*****.**')( elem(ns.LAST, 'query') ) ) e = q.expect('stream-iq', iq_type='error', query_ns=ns.LAST, query_name='query') # Yuck. assertEquals('forbidden', e.stanza.children[1].children[0].name) # If the server asks, Gabble had better not crash. stream.send( elem_iq(stream, 'get')( elem(ns.LAST, 'query') ) ) e = q.expect('stream-iq', iq_type='result', query_ns=ns.LAST, query_name='query')
def disco_bundle(q, bus, conn, stream, node, features): request = \ elem_iq(stream, 'get', from_='[email protected]/resource')( elem(ns.DISCO_INFO, 'query', node=node) ) stream.send(request) disco_response = q.expect('stream-iq', query_ns=ns.DISCO_INFO, iq_id=request['id']) nodes = xpath.queryForNodes('/iq/query/feature', disco_response.stanza) vars = [n["var"] for n in nodes] assertEquals(set(features), set(vars))
def privacy_list_iq_cb(self, iq): if iq.getAttribute("type") == 'set': active = xpath.queryForNodes("//active", iq) if active and ('name' not in active[0].attributes or active[0]['name'] == 'invisible'): acknowledge_iq(self, iq) else: # Don't allow other lists to be activated; and don't allow # modifications. send_error_reply(self, iq) else: requested_lists = xpath.queryForNodes('//list', iq) if not requested_lists: self.send_privacy_list_list(iq['id'], ['invisible']) elif requested_lists[0]['name'] == 'invisible': self.send_privacy_list(iq, [ elem('item', action='deny', order='1')( elem('presence-out')) ]) else: send_error_reply(self, iq, elem(ns.STANZA, 'item-not-found'))
def close(self): if self.initiated: from_ = self.initiator to = self.target else: from_ = self.target to = self.initiator iq = elem_iq(self.stream, 'set', from_=from_, to=to, id=str(id))(elem('close', xmlns=ns.IBB, sid=self.stream_id)()) self.stream.send(iq)
def test_privacy_list_push_valid(q, bus, conn, stream): test_invisible_on_connect(q, bus, conn, stream) set_id = stream.send_privacy_list_push_iq("invisible") _, req_list = q.expect_many( EventPattern('stream-iq', iq_type='result', iq_id=set_id), EventPattern('stream-iq', query_ns=ns.PRIVACY, iq_type="get")) stream.send_privacy_list(req_list.stanza, [ elem('item', action='deny', order='1')(elem(u'presence-out')), elem('item', type='jid', value='*****@*****.**', action='deny', order='2')(elem(u'message')) ]) # We redundantly re-activate the 'invisible' list. These lines also # check to see that we didn't switch over to 'invisible-gabble' activate_list = q.expect('stream-iq', query_ns=ns.PRIVACY, iq_type='set') active = xpath.queryForNodes('//active', activate_list.stanza)[0] assertEquals(active["name"], 'invisible') acknowledge_iq(stream, activate_list.stanza)
def test(q, bus, conn, stream): request = elem_iq(stream, 'get')(elem(ns.VERSION, 'query')) stream.send(request) reply = q.expect('stream-iq', iq_id=request['id'], query_ns=ns.VERSION, query_name='query') # Both <name/> and <version/> are REQUIRED. What they actually contain is # someone else's problem™. names = xpath.queryForNodes('/query/name', reply.query) assertLength(1, names) versions = xpath.queryForNodes('/query/version', reply.query) assertLength(1, versions) # <os/> is OPTIONAL. “Revealing the application's underlying operating # system may open the user or system to attacks directed against that # operating system; therefore, an application MUST provide a way for a # human user or administrator to disable sharing of information about the # operating system.” The “way” that we provide is never to send it. oss = xpath.queryForNodes('/query/os', reply.query) assert oss is None