def create_room(room_name): """Create and configure a room. Documentation to create and configure a room: https://xmpp.org/extensions/xep-0045.html#createroom Parameters ---------- room_name: string The name of the room you want to create. """ client = _connect() client.send( xmpp.Presence( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}/admin", payload=[xmpp.Node(tag="x", attrs={"xmlns": xmpp.NS_MUC})], ) ) client.send( xmpp.Iq( to=f"{room_name}@{settings.XMPP_CONFERENCE_DOMAIN}", frm=settings.XMPP_PRIVATE_ADMIN_JID, typ="set", queryNS=xmpp.NS_MUC_OWNER, payload=[ xmpp.DataForm( typ="submit", data=[ xmpp.DataField( typ="hidden", name="FORM_TYPE", value=xmpp.NS_MUC_ROOMCONFIG ), # Make Room Persistent? xmpp.DataField( typ="boolean", name="muc#roomconfig_persistentroom", value=1 ), # Make room publicly searchable? xmpp.DataField( typ="boolean", name="muc#roomconfig_publicroom", value=0 ), # Nobody can send private message xmpp.DataField( typ="list-single", name="muc#roomconfig_allowpm", value="none", ), # Nobody can send private message xmpp.DataField( typ="boolean", name="muc#roomconfig_allowinvites", value=0 ), # Nobody can change the subject xmpp.DataField( typ="boolean", name="muc#roomconfig_changesubject", value=0 ), ], ) ], ) )
def send_pb_retract(self, jid, node, id_): '''Delete item from a node''' query = xmpp.Iq('set', to=jid) r = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) r = r.addChild('retract', {'node': node, 'notify': '1'}) r = r.addChild('item', {'id': id_}) self.connection.send(query)
def request_pb_configuration(self, jid, node): query = xmpp.Iq('get', to=jid) e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB_OWNER) e = e.addChild('configure', {'node': node}) id = self.connection.getAnID() query.setID(id) self.awaiting_answers[id] = (connection_handlers.PEP_CONFIG, ) self.connection.send(query)
def send_pb_subscription_query(self, jid, cb, *args, **kwargs): query = xmpp.Iq('get', to=jid) pb = query.addChild('pubsub', {'xmlns': xmpp.NS_PUBSUB}) pb.addChild('subscriptions') id = self.connection.send(query) self.__callbacks[id] = (cb, args, kwargs)
def ping(self): ping = xmpp.Iq(typ='get', to=self.jid.getDomain(), frm=self.jid) ping.addChild(name="ping", namespace="urn:xmpp:ping") self.send(ping, lambda cb, stanza: self.debug('response received to ping!'), description="expect pong") self.debug('ping sent: %s' % ping.__str__())
def command_superban(bot, room, nick, access_level, parameters, message): if parameters == '': return "Expected <target jid>" (target, reason) = separate_target_reason(bot, room, parameters) iq = xmpp.Iq('set', xmpp.NS_MUC_ADMIN, {}, room) item = iq.getTag('query').setTag('item') item.setAttr('affiliation', 'outcast') item.setAttr('jid', target) bot.client.send(iq)
def _process(self): self.result = False #Offer Stream Initiation self.myAgent.DEBUG("Offer StreamInitiation to" + str(self.to)) iq = xmpp.Iq(attrs={'id': self.id}) iq.setTo(self.to) iq.setType("set") si = xmpp.Node("si", { "profile": "http://jabber.org/protocol/si/profile/spade-p2p-messaging" }) si.setNamespace("http://jabber.org/protocol/si") if self.myAgent._P2P.isReady(): p2pnode = xmpp.Node("p2p") p2pnode.setNamespace( 'http://jabber.org/protocol/si/profile/spade-p2p-messaging') p2pnode.setData(self.myAgent.getP2PUrl()) si.addChild(node=p2pnode) iq.addChild(node=si) self.myAgent.send(iq) msg = self._receive(True) if msg: self.result = False if msg.getType() == "result": self.myAgent.DEBUG("StreamRequest Agreed", "ok") try: remote_address = str( msg.getTag("si").getTag("p2p").getTag( "value").getData()) d = {"url": remote_address, "p2p": True} if str(msg.getFrom().getStripped() ) in self.myAgent._P2P.getRoutes(): self.myAgent._P2P.p2p_routes[str( msg.getFrom().getStripped())].update(d) self.result = True else: self.myAgent._P2P.p2p_routes[str( msg.getFrom().getStripped())] = d except Exception as e: self.myAgent.DEBUG( "Malformed StreamRequest Answer: " + str(e), "err") self.myAgent.P2P.p2p_routes[str( msg.getFrom().getStripped())] = {} elif msg.getType() == "error": self.myAgent.DEBUG("StreamRequest REFUSED", "warn") self.myAgent._P2P.p2p_routes[str( msg.getFrom().getStripped())] = { 'p2p': False } else: #Not message, treat like a refuse self.myAgent.DEBUG("No msg received. StreamRequest REFUSED", "warn") self.myAgent._P2P.p2p_routes[str(iq.getTo().getStripped())] = { 'p2p': False }
def error_iq(who, err_attrs, description, body, msgid=None): iq = xmpp.Iq(typ='error', to=who) if msgid is not None: iq.setID(msgid) iq.addChild(node=simplexml.XML2Node(str(body))) error = iq.addChild('error', err_attrs) error.addChild(description, namespace='urn:ietf:params:xml:ns:xmpp-stanzas') return iq
def users_register(self, users): """ Reister new users @type users: list @param users: list of users to register """ def on_receive_registration(conn, iq): if iq.getType() == "result": for user in users: self.users.append({ "jid": user["jid"].getStripped(), "type": "human" }) self.entities_types_cache[user["jid"].getStripped()] = "human" self.entity.log.info( "XMPPSERVER: Successfully registered user(s).") self.entity.push_change("xmppserver:users", "registered") else: self.entity.push_change("xmppserver:users", "registerationerror", content_node=iq) self.entity.log.error( "XMPPSERVER: Unable to register user. %s" % str(iq)) server = self.entity.jid.getDomain() for user in users: iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain()) iq_command = iq.addChild( "command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#add-user"}) iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"}) iq_command_x.addChild("field", attrs={ "type": "hidden", "var": "FORM_TYPE" }).addChild("value").setData( "http://jabber.org/protocol/admin") iq_command_x.addChild("field", attrs={ "var": "accountjid" }).addChild("value").setData(user["jid"]) iq_command_x.addChild("field", attrs={ "var": "password" }).addChild("value").setData(user["password"]) iq_command_x.addChild("field", attrs={ "var": "password-verify" }).addChild("value").setData(user["password"]) if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse( iq, on_receive_registration) else: self.entity.xmppclient.SendAndCallForResponse( iq, on_receive_registration) self.entity.log.info("XMPPSERVER: Registering a new user %s@%s" % (user["jid"], server))
def send_pb_unsubscribe(self, jid, node, cb, *args, **kwargs): our_jid = gajim.get_jid_from_account(self.name) query = xmpp.Iq('set', to=jid) pb = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) pb.addChild('unsubscribe', {'node': node, 'jid': our_jid}) id = self.connection.send(query) self.__callbacks[id] = (cb, args, kwargs)
def send_pb_publish(self, jid, node, item, id_): '''Publish item to a node.''' query = xmpp.Iq('set', to=jid) e = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) e = e.addChild('publish', {'node': node}) e = e.addChild( 'item', {'id': id_}, [item]) # TODO: we should generate id... or we shouldn't? self.connection.send(query)
def unpublish(self): iq = xmpp.Iq(typ="set") iq.pubsub = iq.addChild("pubsub", namespace=xmpp.NS_PUBSUB) iq.pubsub.publish = iq.pubsub.addChild("publish", attrs={"node": NS_TUNE}) iq.pubsub.publish.item = iq.pubsub.publish.addChild( "item", attrs={"id": "current"}) tune = iq.pubsub.publish.item.addChild("tune") tune.setNamespace(NS_TUNE) self.con.send(iq)
def subscribe(self, jid, callback=None, unique=True, wait=False): """ Subscribe to the node. @type jid: xmpp.Protocol.JID @param jid: the JID of the subscriber @type callback: function @param callback: the callback that will be called when an item is published @type unique: Boolean @param unique: if True, it will subscribe only if no subscription is already done @type wait: Boolean @param wait: if True, action will be done in sync mode """ self.subscriber_callback = callback self.subscriber_jid = jid if unique: if len(self.subscriptions) == 0: self.retrieve_subscriptions(wait=True) if not len(self.subscriptions) == 0: self.xmppclient.RegisterHandler('message', self._on_pubsub_event, ns=xmpp.protocol.NS_PUBSUB + "#event", typ="headline") return iq = xmpp.Iq(typ="set", to=self.pubsubserver) pubsub = iq.addChild("pubsub", namespace=xmpp.protocol.NS_PUBSUB) pubsub.addChild("subscribe", attrs={ "node": self.nodename, "jid": jid.getStripped() }) def _did_subscribe(conn, resp, callback): ret = False if resp.getType() == "result": self.xmppclient.RegisterHandler('message', self._on_pubsub_event, ns=xmpp.protocol.NS_PUBSUB + "#event", typ="headline") ret = True return ret if wait: resp = self.xmppclient.SendAndWaitForResponse(iq) return _did_subscribe(None, resp, callback) else: self.xmppclient.SendAndCallForResponse(iq, func=_did_subscribe, args={"callback": callback}) return True self.xmppclient.send(iq)
def register(jid, email=None, password=None): """ Register a new jabber ID """ if email is None: email = str(jid) password = get_checked_password(jid, password) jid = toJID(jid) # connect to server cl = connect(jid) # ask the server to start the registration process # http://www.xmpp.org/extensions/xep-0077.html#usecases-register # <iq type='get' id='reg1'> <query xmlns='jabber:iq:register'/> </iq> iq = xmpp.Iq(typ='get') iq.addChild('query', namespace=xmpp.NS_REGISTER) ready = cl.SendAndWaitForResponse(iq) # just check for an error response if ready.getErrorCode() is not None: raise RuntimeError(ready.getError()) # send registration data (something like...) # <iq type='result' id='reg1'> # <query xmlns='jabber:iq:register'> # <registered/> # <username>juliet</username> # <password>R0m30</password> # <email>[email protected]</email> # </query> # </iq> iq = xmpp.Iq(typ='set') query = iq.addChild('query', namespace=xmpp.NS_REGISTER) query.addChild('username', payload=jid.getNode()) query.addChild('password', payload=password) query.addChild('email', payload=email) register = cl.SendAndWaitForResponse(iq) if register.getErrorCode() is not None: raise RuntimeError(register.getError()) return register
def commit_to_db(self, action, table, callback): """ Sends a command to active central agent for execution @type command: string @param command: the sql command to execute @type table: table @param command: the table of dicts of values associated with the command. """ central_agent_jid = self.central_agent_jid() if central_agent_jid: # send an iq to central agent dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) for entry in table: entryTag = xmpp.Node(tag="entry") for key, value in entry.iteritems(): entryTag.addChild("item", attrs={ "key": key, "value": value }) dbCommand.addChild(node=entryTag) def commit_to_db_callback(conn, resp): if callback: unpacked_entries = self.unpack_entries(resp) callback(unpacked_entries) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=central_agent_jid) iq.getTag("query").addChild(name="archipel", attrs={"action": action}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) self.entity.log.debug("CENTRALDB: commit to db request %s" % iq) xmpp.dispatcher.ID += 1 iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID)) self.entity.xmppclient.SendAndCallForResponse( iq, commit_to_db_callback) else: self.entity.log.warning( "CENTRALDB: cannot commit to db because we have not detected any central agent" )
def send_pb_create(self, jid, node, configure=False, configure_form=None): '''Creates new node.''' query = xmpp.Iq('set', to=jid) c = query.addChild('pubsub', namespace=xmpp.NS_PUBSUB) c = c.addChild('create', {'node': node}) if configure: conf = c.addChild('configure') if configure_form is not None: conf.addChild(node=configure_form) self.connection.send(query)
def create_invisible_list(self): iq = xmpp.Iq(typ="set") iq.query = iq.addChild("query", namespace=xmpp.NS_PRIVACY) iq.query.list = iq.query.addChild("list", attrs={"name": "invisible"}) iq.query.list.item = iq.query.list.addChild("item", attrs={ "action": "deny", "order": "1" }) iq.query.list.item.addChild("presence-out") self.con.send(iq)
def disco_info(args): if not args.who: return self.subparser.format_usage() who = toJID(args.who) q = xmpp.Iq(typ="get", queryNS='http://jabber.org/protocol/disco#items', to=who) if args.node: q.setTagAttr('query', 'node', args.node[0]) args.bot.cl.send(q) return "Sent items query"
def make_iq(tojid, typ, marshaled, msgid=None): """ Wrap XML-RPC marshaled data in an XMPP jabber:iq:rpc message """ tojid = toJID(tojid) iq = xmpp.Iq(typ=typ, to=tojid, xmlns=None) if msgid is not None: iq.setID(msgid) query = iq.addChild('query', namespace=xmpp.NS_RPC) query.addChild(node=simplexml.XML2Node(marshaled)) return iq
def check_invisible_list(self): request = xmpp.Iq(typ="get") request.addChild("query", namespace=xmpp.NS_PRIVACY) rep = self.con.SendAndWaitForResponse(request, timeout=25) children = rep.getQueryChildren() has_privacy = False if children is not None: for child in children: if child.getName() == "list" and child.getAttr( "name") == "invisible": has_privacy = True return has_privacy
def kick(userJID, room): """Kicks user from MUC""" #mJID=xmpp.Protocol.JID(moderJID) #uJID=xmpp.Protocol.JID(userJID) iq=xmpp.Iq('set') id='kick'+str(random.randrange(1,1000)) iq.setID(id) iq.setTo(userJID) dummy,uNick=userJID.split('/') iq.T.query.NT.
def command_ping(bot, room, nick, access_level, parameters, message): if parameters: target = parameters if not target in bot.roster[room]: return '%s is unreachable.'%(target) if target == bot.self_nick[room]: return u'Пинг до %s - 0.0000 s.'%(target) else: target = nick target = '%s/%s'%(room, target) iq = xmpp.Iq('get', None, {'id': 'ping1xtc'}, target) iq.setTag('ping', namespace='urn:xmpp:ping') bot.client.send(iq) wait_ping[target] = (time.time(), message.getType(), nick)
def muc_set_affiliation(self, room, jid, affiliation, reason=None): """Set affiliation to user from muc reason works only if defined in protocol Works only with sufficient rights.""" NS_MUCADMIN = 'http://jabber.org/protocol/muc#admin' item = xmpp.simplexml.Node('item') item.setAttr('jid', jid) item.setAttr('affiliation', affiliation) iq = xmpp.Iq(typ='set', queryNS=NS_MUCADMIN, xmlns=None, to=room, payload=set([item])) if reason is not None: item.setTagData('reason', reason) self.connect().send(iq)
def read_from_db(self, action, columns, where_statement, callback): """ Send a select statement to central db. @type command: string @param command: the sql command to execute @type columns: string @param columns: the list of database columns to return @type where_statement: string @param where_statement: for database reads, provides "where" constraint """ central_agent_jid = self.central_agent_jid() if central_agent_jid: # send an iq to central agent dbCommand = xmpp.Node(tag="event", attrs={"jid": self.entity.jid}) if where_statement: dbCommand.setAttr("where_statement", where_statement) if columns: dbCommand.setAttr("columns", columns) self.entity.log.debug("CENTRALDB: central agent jid %s" % central_agent_jid) iq = xmpp.Iq(typ="set", queryNS=ARCHIPEL_NS_CENTRALAGENT, to=central_agent_jid) iq.getTag("query").addChild(name="archipel", attrs={"action": action}) iq.getTag("query").getTag("archipel").addChild(node=dbCommand) xmpp.dispatcher.ID += 1 iq.setID("%s-%d" % (self.entity.jid.getNode(), xmpp.dispatcher.ID)) def _read_from_db_callback(conn, resp): self.entity.log.debug("CENTRALDB: reply to read statement %s" % resp) unpacked_entries = self.unpack_entries(resp) self.entity.log.debug("CENTRALDB: unpacked reply %s" % unpacked_entries) callback(unpacked_entries) self.entity.xmppclient.SendAndCallForResponse( iq, _read_from_db_callback) else: self.entity.log.warning( "CENTRALDB: cannot read from db because we have not detected any central agent" )
def configure(self, options, callback=None, wait=False): """ Configure the node. @type options: dict @param options: dictionary containing options: value for the pubsub configuration @type wait: Boolean @param wait: if True, recovering will be blockant (IE, execution interrupted until recovering) @rtype: Boolean @return: True in case of success """ if not self.recovered: raise Exception( "PUBSUB: can't configure. Node %s doesn't exists." % self.nodename) iq = xmpp.Iq(typ="set", to=self.pubsubserver) pubsub = iq.addChild("pubsub", namespace=xmpp.protocol.NS_PUBSUB + "#owner") configure = pubsub.addChild("configure", attrs={"node": self.nodename}) x = configure.addChild("x", namespace=xmpp.protocol.NS_DATA, attrs={"type": "submit"}) x.addChild("field", attrs={ "var": "FORM_TYPE", "type": "hidden" }).addChild("value").setData( "http://jabber.org/protocol/pubsub#node_config") for key, value in options.items(): field = x.addChild("field", attrs={"var": key}) if type(value) == types.ListType: for v in value: field.addChild("value").setData(v) else: field.addChild("value").setData(str(value)) def _did_configure(conn, resp, callback): ret = False if resp.getType() == "result": ret = True if callback: callback(resp) return ret if wait: resp = self.xmppclient.SendAndWaitForResponse(iq) return _did_configure(None, resp, callback) else: self.xmppclient.SendAndCallForResponse(iq, func=_did_configure, args={"callback": callback}) return True
def IQSender(chat, attr, data, afrls, role, text=str(), handler=()): stanza = xmpp.Iq(to=chat, typ="set") query = xmpp.Node("query") query.setNamespace(xmpp.NS_MUC_ADMIN) arole = query.addChild("item", {attr: data, afrls: role}) if text: arole.setTagData("reason", text) stanza.addChild(node=query) if not handler: jClient.send(stanza) else: handler, args = handler jClient.SendAndCallForResponse(stanza, handler, args) INFO["outiq"] += 1
def users_unregister(self, users): """ Unregister users @type users: list @param users: list of users to unregister """ def on_receive_unregistration(conn, iq): if iq.getType() == "result": for jid in users: self.users.remove({ "jid": jid.getStripped(), "type": "human" }) self.entity.log.info( "XMPPSERVER: Successfully unregistered user(s).") self.entity.push_change("xmppserver:users", "unregistered") else: self.entity.push_change("xmppserver:users", "unregisterationerror", content_node=iq) self.entity.log.error( "XMPPSERVER: unable to unregister user. %s" % str(iq)) iq = xmpp.Iq(typ="set", to=self.entity.jid.getDomain()) iq_command = iq.addChild( "command", namespace="http://jabber.org/protocol/commands", attrs={"node": "http://jabber.org/protocol/admin#delete-user"}) iq_command_x = iq_command.addChild("x", namespace="jabber:x:data", attrs={"type": "submit"}) iq_command_x.addChild( "field", attrs={ "type": "hidden", "var": "FORM_TYPE" }).addChild("value").setData("http://jabber.org/protocol/admin") accountjids_node = iq_command_x.addChild("field", attrs={"var": "accountjids"}) for jid in users: accountjids_node.addChild("value").setData(jid.getStripped()) if jid.getStripped() in self.entities_types_cache: del self.entities_types_cache[jid.getStripped()] if self.entity.__class__.__name__ == "TNArchipelVirtualMachine": self.entity.hypervisor.xmppclient.SendAndCallForResponse( iq, on_receive_unregistration) else: self.entity.xmppclient.SendAndCallForResponse( iq, on_receive_unregistration) self.entity.log.info("XMPPSERVER: Unregistring some users %s" % str(users))
def kick(self, room, nick, reason=None): """Kicks user from muc Works only with sufficient rights.""" NS_MUCADMIN = 'http://jabber.org/protocol/muc#admin' item = xmpp.simplexml.Node('item') item.setAttr('nick', nick) item.setAttr('role', 'none') iq = xmpp.Iq(typ='set', queryNS=NS_MUCADMIN, xmlns=None, to=room, payload=set([item])) if reason is not None: item.setTagData('reason', reason) self.connect().send(iq)
def disco_info(args): if not args.who: return self.subparser.format_usage() who = toJID(args.who) q = xmpp.Iq(typ="get", queryNS='http://jabber.org/protocol/disco#info', to=who) if args.node: q.setTagAttr('query', 'node', args.node[0]) tree = fromstring(str(q)) print("--disco-info--") dump(tree) args.bot.cl.send(q) return "Sent info query"
def got_iq(self, sess, iq): jid = iq.getFrom() nick = jid.getResource() room = jid.getStripped() if not room in self.configuration['mucs']: self.log_debug('Unexpected iq from %s: %s'%(jid, iq)) return if iq.getQueryNS() == xmpp.NS_VERSION: reply_iq = xmpp.Iq('result', None, {'id': iq.getID()}, '%s/%s'%(room, nick)) reply_query = reply_iq.setTag('query', namespace=xmpp.NS_VERSION) reply_query.setTagData('name', 'Magnet') reply_query.setTagData('version', self.version) reply_query.setTagData('os', self.platform) self.client.send(reply_iq) raise xmpp.NodeProcessed self.event_room_iq(self, (iq, room, nick))