def parse_disco_info(stanza, timestamp=None): idenities = [] features = [] dataforms = [] if timestamp is None: timestamp = time.time() query = stanza.getQuery() for node in query.getTags('identity'): attrs = node.getAttrs() try: idenities.append( DiscoIdentity(category=attrs['category'], type=attrs['type'], name=attrs.get('name'), lang=attrs.get('xml:lang'))) except Exception: raise MalformedStanzaError('invalid attributes', stanza) for node in query.getTags('feature'): try: features.append(node.getAttr('var')) except Exception: raise MalformedStanzaError('invalid attributes', stanza) for node in query.getTags('x', namespace=Namespace.DATA): dataforms.append(extend_form(node)) return DiscoInfo(stanza=stanza, identities=idenities, features=features, dataforms=dataforms, timestamp=timestamp)
def _nec_new_acc_connected(self, obj): """ Connection to server succeded, present the form to the user """ # We receive events from all accounts from GED if obj.conn.name != self.account: return if self.update_progressbar_timeout_id is not None: GLib.source_remove(self.update_progressbar_timeout_id) self.back_button.show() self.forward_button.show() self.is_form = obj.is_form empty_config = True if obj.is_form: dataform = dataforms.extend_form(node=obj.config) self.data_form_widget = dataforms_widget.DataFormWidget() self.data_form_widget.selectable = True self.data_form_widget.set_data_form(dataform) empty_config = False else: self.data_form_widget = FakeDataFormWidget(obj.config) for field in obj.config: if field in ('key', 'instructions', 'x', 'registered'): continue empty_config = False break self.data_form_widget.show_all() self.xml.get_object('form_vbox').pack_start( self.data_form_widget, True, True, 0) if empty_config: self.forward_button.set_sensitive(False) self.notebook.set_current_page(4) # show form page return self.ssl_fingerprint_sha1 = obj.ssl_fingerprint_sha1 self.ssl_fingerprint_sha256 = obj.ssl_fingerprint_sha256 self.ssl_cert = obj.ssl_cert if obj.ssl_msg: # An SSL warning occured, show it hostname = app.connections[self.account].new_account_info[ 'hostname'] self.xml.get_object('ssl_label').set_markup(_( '<b>Security Warning</b>' '\n\nThe authenticity of the %(hostname)s SSL certificate could' ' be invalid.\nSSL Error: %(error)s\n' 'Do you still want to connect to this server?') % { 'hostname': hostname, 'error': obj.ssl_msg}) if obj.errnum in (18, 27): text = _( 'Add this certificate to the list of trusted ' 'certificates.\nSHA-1 fingerprint of the certificate:\n' '%(sha1)s\nSHA-256 fingerprint of the certificate:\n' '%(sha256)s') % {'sha1': obj.ssl_fingerprint_sha1, 'sha256': obj.ssl_fingerprint_sha256} self.xml.get_object('ssl_checkbutton').set_label(text) else: self.xml.get_object('ssl_checkbutton').set_no_show_all(True) self.xml.get_object('ssl_checkbutton').hide() self.notebook.set_current_page(3) # show SSL page else: self.notebook.set_current_page(4) # show form page
def _process_voice_request(self, _client, stanza, properties): data_form = stanza.getTag('x', namespace=Namespace.DATA) if data_form is None: return data_form = extend_form(data_form) try: if data_form['FORM_TYPE'].value != Namespace.MUC_REQUEST: return except KeyError: return nick = data_form['muc#roomnick'].value try: jid = JID.from_string(data_form['muc#jid'].value) except Exception: self._log.warning('Invalid JID on voice request') self._log.warning(stanza) raise NodeProcessed properties.voice_request = VoiceRequest(jid=jid, nick=nick, form=data_form) properties.from_muc = True properties.muc_jid = properties.jid.new_as_bare()
def _build_dataform(self, form, is_form): if not is_form: return FakeDataFormWidget(form) dataform = dataforms.extend_form(node=form) form_widget = DataFormWidget(dataform) form_widget.connect('is-valid', self._on_is_valid) form_widget.validate() return form_widget
def process_result(self, form): if self._treeview is not None: self._scrolled.remove(self._treeview) self._treeview.destroy() self._treeview = None self._menu = None self._label.hide() self._scrolled.hide() if not form: self._label.show() return form = dataforms.extend_form(node=form) fieldtypes = [] fieldvars = [] for field in form.reported.iter_fields(): if field.type_ == 'boolean': fieldtypes.append(bool) elif field.type_ in ('jid-single', 'text-single'): fieldtypes.append(str) else: log.warning('Not supported field received: %s', field.type_) continue fieldvars.append(field.var) liststore = Gtk.ListStore(*fieldtypes) for item in form.iter_records(): iter_ = liststore.append() for field in item.iter_fields(): if field.var in fieldvars: liststore.set_value(iter_, fieldvars.index(field.var), field.value) self._treeview = Gtk.TreeView() self._treeview.set_hexpand(True) self._treeview.set_vexpand(True) self._treeview.get_style_context().add_class('search-treeview') self._treeview.connect('button-press-event', self._on_button_press) self._menu = SearchMenu(self._treeview) for field, counter in zip(form.reported.iter_fields(), itertools.count()): self._treeview.append_column( Gtk.TreeViewColumn(field.label, Gtk.CellRendererText(), text=counter)) self._treeview.set_model(liststore) self._treeview.show() self._scrolled.add(self._treeview) self._scrolled.show()
def __init__(self): Gtk.Window.__init__(self, title="Data Form Test") self.set_default_size(600, 600) options = { 'left-width': 100, 'form-width': 435, } self._widget = DataFormWidget(extend_form(node=nbxmpp.Node(node=FORM)), options) self.add(self._widget) self.show()
def _show_form(self, form): if self._dataform_widget is not None: self.remove(self._dataform_widget) self._dataform_widget.destroy() if form is None: return form = dataforms.extend_form(node=form) self._dataform_widget = DataFormWidget(form) self._dataform_widget.connect('is-valid', self._on_is_valid) self._dataform_widget.validate() self._dataform_widget.show_all() self.add(self._dataform_widget)
def _show_form(self, form): if self._dataform_widget is not None: self.remove(self._dataform_widget) self._dataform_widget.destroy() if form is None: return form = dataforms.extend_form(node=form) self._dataform_widget = DataFormWidget(form, options={'read-only': True}) self._dataform_widget.show_all() self.add(self._dataform_widget)
def _show_form(self, form): if self._dataform_widget is not None: self.remove(self._dataform_widget) self._dataform_widget.destroy() if form is None: return form = dataforms.extend_form(node=form) options = {'entry-activates-default': True} self._dataform_widget = DataFormWidget(form, options) self._dataform_widget.connect('is-valid', self._on_is_valid) self._dataform_widget.validate() self._dataform_widget.show_all() self.add(self._dataform_widget)
def _parse_form(form): dataform = extend_form(node=form) result = {} try: result['submit-text'] = dataform['submit-button-text'].value except KeyError: result['submit-text'] = _('Submit') try: result['open-text'] = dataform['open-button-text'].value except KeyError: result['open-text'] = _('Open') return result
def _parse_form(stanza): query = stanza.getTag('query', namespace=Namespace.REGISTER) form = query.getTag('x', namespace=Namespace.DATA) if form is None: return None form = extend_form(node=form) field = form.vars.get('FORM_TYPE') if field is None: return None # Invalid urn:xmpp:captcha used by ejabberd # See https://github.com/processone/ejabberd/issues/3045 if field.value in ('jabber:iq:register', 'urn:xmpp:captcha'): return form return None
def request_parameters(self, jid): task = yield response = yield _make_parameter_request(jid) if response.isError(): raise StanzaError(response) search = response.getTag('search', namespace=Namespace.MUCLUMBUS) if search is None: raise MalformedStanzaError('search node missing', response) dataform = search.getTag('x', namespace=Namespace.DATA) if dataform is None: raise MalformedStanzaError('dataform node missing', response) self._log.info('Muclumbus parameters received') yield finalize(task, extend_form(node=dataform))
def request_config(self, room_jid): task = yield response = yield make_config_request(room_jid) if response.isError(): raise StanzaError(response) jid = response.getFrom() payload = response.getQueryPayload() for form in payload: if form.getNamespace() == Namespace.DATA: dataform = extend_form(node=form) self._log.info('Config form received for %s', jid) yield MucConfigResult(jid=jid, form=dataform) yield MucConfigResult(jid=jid)
def __init__(self, data): transient = app.app.get_active_window() Gtk.ApplicationWindow.__init__(self, title="Data Form Test") self.set_transient_for(transient) self.set_default_size(600, 400) self._account = data['account'] self._jid = data['jid'] self._form_widget = DataFormWidget( extend_form(node=nbxmpp.Node(node=data['form']))) box = Gtk.Box(orientation='vertical', spacing=12) box.add(self._form_widget) button = Gtk.Button(label=data['submit-text']) button.connect('clicked', self._on_send_clicked) button.set_halign(Gtk.Align.END) box.add(button) self.add(box) self.show_all()
def _get_configure_form(response, node): pubsub = response.getTag('pubsub', namespace=Namespace.PUBSUB_OWNER) if pubsub is None: raise MalformedStanzaError('pubsub node missing', response) configure = pubsub.getTag('configure') if configure is None: raise MalformedStanzaError('configure node missing', response) if node != configure.getAttr('node'): raise MalformedStanzaError('invalid node attribute', response) forms = configure.getTags('x', namespace=Namespace.DATA) for form in forms: dataform = extend_form(node=form) form_type = dataform.vars.get('FORM_TYPE') if form_type is None or form_type.value != Namespace.PUBSUB_CONFIG: continue return dataform raise MalformedStanzaError('no valid form type found', response)
def __init__(self, title, transient_for, form, node, submit_callback): Gtk.Dialog.__init__(self, title=title, transient_for=transient_for, modal=False) self.set_default_size(600, 500) self._submit_callback = submit_callback self._form = DataFormWidget(extend_form(node=form)) self._node = node self.get_content_area().get_style_context().add_class('dialog-margin') self.get_content_area().add(self._form) self.add_button(_('Cancel'), Gtk.ResponseType.CANCEL) submit_button = self.add_button(_('Submit'), Gtk.ResponseType.OK) submit_button.get_style_context().add_class('suggested-action') self.set_default_response(Gtk.ResponseType.OK) self.connect('response', self._on_response) self.show_all()
def _received_pb_configuration(self, _con, stanza, node): if not nbxmpp.isResultNode(stanza): self._log.warning('Error: %s', stanza.getError()) return pubsub = stanza.getTag('pubsub', namespace=nbxmpp.NS_PUBSUB_OWNER) if pubsub is None: self._log.warning( 'Malformed PubSub configure ' 'stanza (no pubsub node): %s', stanza) return configure = pubsub.getTag('configure') if configure is None: self._log.warning( 'Malformed PubSub configure ' 'stanza (no configure node): %s', stanza) return if configure.getAttr('node') != node: self._log.warning( 'Malformed PubSub configure ' 'stanza (wrong node): %s', stanza) return form = configure.getTag('x', namespace=nbxmpp.NS_DATA) if form is None: self._log.warning( 'Malformed PubSub configure ' 'stanza (no form): %s', stanza) return app.nec.push_incoming_event( PubSubConfigReceivedEvent(None, conn=self._con, node=node, form=dataforms.extend_form(node=form)))
def generate(self): self.id_ = self.stanza.getID() self.fjid = self.conn.get_module('Bytestream')._ft_get_from( self.stanza) self.jid = app.get_jid_without_resource(self.fjid) if self.jingle_content: secu = self.jingle_content.getTag('security') self.FT_content.use_security = bool(secu) if secu: fingerprint = secu.getTag('fingerprint') if fingerprint: self.FT_content.x509_fingerprint = fingerprint.getData() if not self.FT_content.transport: self.FT_content.transport = JingleTransportSocks5() self.FT_content.transport.set_our_jid( self.FT_content.session.ourjid) self.FT_content.transport.set_connection( self.FT_content.session.connection) sid = self.stanza.getTag('jingle').getAttr('sid') self.file_props = FilesProp.getNewFileProp(self.conn.name, sid) self.file_props.transport_sid = self.FT_content.transport.sid self.FT_content.file_props = self.file_props self.FT_content.transport.set_file_props(self.file_props) self.file_props.streamhosts.extend( self.FT_content.transport.remote_candidates) for host in self.file_props.streamhosts: host['initiator'] = self.FT_content.session.initiator host['target'] = self.FT_content.session.responder self.file_props.session_type = 'jingle' self.file_props.stream_methods = nbxmpp.NS_BYTESTREAM desc = self.jingle_content.getTag('description') if self.jingle_content.getAttr('creator') == 'initiator': file_tag = desc.getTag('file') self.file_props.sender = self.fjid self.file_props.receiver = self.conn.get_module( 'Bytestream')._ft_get_our_jid() else: file_tag = desc.getTag('file') h = file_tag.getTag('hash') h = h.getData() if h else None n = file_tag.getTag('name') n = n.getData() if n else None pjid = app.get_jid_without_resource(self.fjid) file_info = self.conn.get_module('Jingle').get_file_info( pjid, hash_=h, name=n, account=self.conn.name) self.file_props.file_name = file_info['file-name'] self.file_props.sender = self.conn.get_module( 'Bytestream')._ft_get_our_jid() self.file_props.receiver = self.fjid self.file_props.type_ = 's' for child in file_tag.getChildren(): name = child.getName() val = child.getData() if val is None: continue if name == 'name': self.file_props.name = val if name == 'size': self.file_props.size = int(val) if name == 'hash': self.file_props.algo = child.getAttr('algo') self.file_props.hash_ = val if name == 'date': self.file_props.date = val else: si = self.stanza.getTag('si') self.file_props = FilesProp.getNewFileProp(self.conn.name, si.getAttr('id')) self.file_props.transport_sid = self.file_props.sid profile = si.getAttr('profile') if profile != nbxmpp.NS_FILE: self.conn.get_module('Bytestream').send_file_rejection( self.file_props, code='400', typ='profile') raise nbxmpp.NodeProcessed feature_tag = si.getTag('feature', namespace=nbxmpp.NS_FEATURE) if not feature_tag: return form_tag = feature_tag.getTag('x', namespace=nbxmpp.NS_DATA) if not form_tag: return self.dataform = dataforms.extend_form(node=form_tag) for f in self.dataform.iter_fields(): if f.var == 'stream-method' and f.type_ == 'list-single': values = [o[1] for o in f.options] self.file_props.stream_methods = ' '.join(values) if nbxmpp.NS_BYTESTREAM in values or \ nbxmpp.NS_IBB in values: break else: self.conn.get_module('Bytestream').send_file_rejection( self.file_props, code='400', typ='stream') raise nbxmpp.NodeProcessed file_tag = si.getTag('file') for name, val in file_tag.getAttrs().items(): if val is None: continue if name == 'name': self.file_props.name = val if name == 'size': self.file_props.size = int(val) mime_type = si.getAttr('mime-type') if mime_type is not None: self.file_props.mime_type = mime_type self.file_props.sender = self.fjid self.file_props.receiver = self.conn.get_module( 'Bytestream')._ft_get_our_jid() self.file_props.request_id = self.id_ file_desc_tag = file_tag.getTag('desc') if file_desc_tag is not None: self.file_props.desc = file_desc_tag.getData() self.file_props.transfered_size = [] return True