def __init__(self, room_jid, nick, password, rejoin, config=None): self._room_jid = JID(room_jid) self._nick = nick self._password = password self._rejoin = rejoin self._config = config self._state = MUCJoinedState.NOT_JOINED
def _on_message(_con, _stanza, properties): data = [ BookmarkData( jid=JID.from_string('*****@*****.**'), name='The Play\'s the Thing', autojoin=True, password='******', nick='JC'), BookmarkData( jid=JID.from_string('*****@*****.**'), name='Second room', autojoin=False, password=None, nick=None) ] pubsub_event = PubSubEventData(node='storage:bookmarks', id='current', item=None, data=data, deleted=False, retracted=False, purged=False) # We cant compare Node objects pubsub_event_ = properties.pubsub_event._replace(item=None) self.assertEqual(pubsub_event, pubsub_event_)
def __init__(self, room_jid, nick, password, config=None): self._room_jid = JID(room_jid) self._config = config self.nick = nick self.password = password self.state = MUCJoinedState.NOT_JOINED # Message id of the captcha challenge self.captcha_id = None
def test_ip_literals(self): tests = [ ('juliet@[2002:4559:1FE2::4559:1FE2]/res'), ('[email protected]/res'), ] for jid in tests: JID.from_string(jid)
def test_jid_equality(self): tests = [ '*****@*****.**', '[email protected]/foo', 'example.com', ] for jid in tests: self.assertTrue(JID.from_string(jid) == JID.from_string(jid))
def set_os_info(self, result, jid): if self.xml.get_object('information_notebook').get_n_pages() < 5: return error = is_error_result(result) i = 0 client = '' os_info = '' while i in self.os_info: if self.os_info[i]['resource'] == JID(jid).getResource(): if not error: self.os_info[i]['client'] = '%s %s' % (result.name, result.version) else: self.os_info[i]['client'] = Q_('?Client:Unknown') if not error and result.os is not None: self.os_info[i]['os'] = result.os else: self.os_info[i]['os'] = Q_('?OS:Unknown') if i > 0: client += '\n' os_info += '\n' client += self.os_info[i]['client'] os_info += self.os_info[i]['os'] i += 1 self.xml.get_object('client_name_version_label').set_text(client) self.xml.get_object('os_label').set_text(os_info) self.os_info_arrived = True
def test_error_parsing(self): stanza = ''' <iq from='upload.montague.tld' id='step_03' to='[email protected]/garden' type='error'> <error type='modify'> <not-acceptable xmlns='urn:ietf:params:xml:ns:xmpp-stanzas' /> <text xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>File too large. The maximum file size is 20000 bytes</text> <text xml:lang='de' xmlns='urn:ietf:params:xml:ns:xmpp-stanzas'>File zu groß. Erlaubt sind 20000 bytes</text> <file-too-large xmlns='urn:xmpp:http:upload:0'> <max-file-size>20000</max-file-size> </file-too-large> </error> </iq>''' error = error_factory(Iq(node=stanza)) self.assertEqual(error.condition, 'not-acceptable') self.assertEqual(error.app_condition, 'file-too-large') self.assertEqual( error.get_text(), 'File too large. The maximum file size is 20000 bytes') self.assertEqual(error.get_text('de'), 'File zu groß. Erlaubt sind 20000 bytes') self.assertEqual(error.type, 'modify') self.assertEqual(error.id, 'step_03') self.assertEqual(error.jid, JID.from_string('upload.montague.tld'))
def _validate_jid(self, text): if not text: self._set_warning_icon(False) self._ui.create_button.set_sensitive(False) return try: jid = JID(text) if jid.getResource(): raise InvalidJid except InvalidJid: self._set_warning(_('Invalid Address')) else: self._set_warning_icon(False) self._ui.create_button.set_sensitive(True)
def parse_storage_node(storage, log): bookmarks = [] confs = storage.getTags('conference') for conf in confs: try: jid = JID.from_string(conf.getAttr('jid')) except Exception: log.warning('invalid jid: %s', conf) continue if jid.localpart is None or jid.resource is not None: log.warning('invalid jid: %s', conf) continue autojoin = parse_autojoin(conf.getAttr('autojoin')) nick = parse_nickname(conf.getTagData('nick')) name = conf.getAttr('name') or None password = conf.getTagData('password') or None bookmark = BookmarkData(jid=jid, name=name, autojoin=autojoin, password=password, nick=nick) bookmarks.append(bookmark) return bookmarks
def get_affiliation(self, jid, affiliation): _task = yield response = yield make_affiliation_request(jid, affiliation) if response.isError(): raise StanzaError(response) room_jid = response.getFrom() query = response.getTag('query', namespace=Namespace.MUC_ADMIN) items = query.getTags('item') users_dict = {} for item in items: try: jid = JID.from_string(item.getAttr('jid')) except Exception as error: self._log.warning('Invalid JID: %s, %s', item.getAttr('jid'), error) continue users_dict[jid] = {} if item.has_attr('nick'): users_dict[jid]['nick'] = item.getAttr('nick') if item.has_attr('role'): users_dict[jid]['role'] = item.getAttr('role') reason = item.getTagData('reason') if reason: users_dict[jid]['reason'] = reason self._log.info('Affiliations received from %s: %s', room_jid, users_dict) yield AffiliationResult(jid=room_jid, users=users_dict)
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 _parse_push(node): items = node.getTags('item') if not items: return BlockingPush(block=set(), unblock=set(), unblock_all=True) jids = set() for item in items: jid = item.getAttr('jid') if not jid: continue try: jid = JID.from_string(jid) except Exception: continue jids.add(jid) block, unblock = set(), set() if node.getName() == 'block': block = jids else: unblock = jids return BlockingPush(block=block, unblock=unblock, unblock_all=False)
def test_invalid_jids(self): tests = [ ('"juliet"@example.com', LocalpartNotAllowedChar), ('foo [email protected]', LocalpartNotAllowedChar), ('henry\[email protected]', LocalpartNotAllowedChar), ('@example.com', LocalpartByteLimit), ('[email protected]/', ResourcepartByteLimit), ('[email protected]/\U00000001', ResourcepartNotAllowedChar), ('\[email protected]', LocalpartNotAllowedChar), ('user@[email protected]', DomainpartNotAllowedChar), ('juliet@', DomainpartByteLimit), ('/foobar', DomainpartByteLimit), ] for jid, exception in tests: with self.assertRaises(exception): JID.from_string(jid)
def setUp(self): # Setup mock client self.client = Mock() self.client.is_websocket = False self.dispatcher = StanzaDispatcher(self.client) self.client.get_bound_jid.return_value = JID.from_string( '*****@*****.**') self.dispatcher.reset_parser() self.dispatcher.process_data(STREAM_START)
def test_valid_jids(self): tests = [ '*****@*****.**', '[email protected]/foo', '[email protected]/foo bar', '[email protected]/foo@bar', 'foo\\[email protected]', '*****@*****.**', 'fu\[email protected]', '\[email protected]', '\[email protected]/foo', '\[email protected]/foo', '\[email protected]/foo', '[email protected]/\U0000265A', 'example.com', 'example.com/foobar', 'a.example.com/[email protected]', ] for jid in tests: JID.from_string(jid)
def from_node(cls, node): attrs = node.getAttrs(copy=True) jid = attrs.get('jid') if jid is None: raise Exception('jid attribute missing') jid = JID.from_string(jid) attrs['jid'] = jid groups = {group.getData() for group in node.getTags('group')} attrs['groups'] = groups return cls(**attrs)
def _add_bookmark(self, account, nickname, password): con = app.connections[account] add_bookmark = self.bookmark_switch.get_active() if not add_bookmark: return autojoin = self.autojoin_switch.get_active() # Add as bookmark, with autojoin and not minimized name = app.get_nick_from_jid(self.room_jid) con.get_module('Bookmarks').add_bookmark(name, JID(self.room_jid), autojoin, password, nickname)
class MUCData: def __init__(self, room_jid, nick, password, rejoin, config=None): self._room_jid = JID(room_jid) self._nick = nick self._password = password self._rejoin = rejoin self._config = config self._state = MUCJoinedState.NOT_JOINED @property def jid(self): return self._room_jid @property def occupant_jid(self): jid = self._room_jid.copy() jid.setResource(self._nick) return jid @property def nick(self): return self._nick @nick.setter def nick(self, value): self._nick = value @property def password(self): return self._password @property def state(self): return self._state @state.setter def state(self, value): self._state = value @property def rejoin(self): return self._rejoin @rejoin.setter def rejoin(self, value): self._rejoin = value @property def config(self): return self._config
def _get_preference_jids(node): jids = [] for item in node.getTags('jid'): jid = item.getData() if not jid: continue try: jid = JID.from_string(jid) except Exception: continue jids.append(jid) return jids
def _process_mediated_invite(_client, stanza, properties): muc_user = stanza.getTag('x', namespace=Namespace.MUC_USER) if muc_user is None: return if properties.type != MessageType.NORMAL: return properties.from_muc = True properties.muc_jid = properties.jid.new_as_bare() data = {} invite = muc_user.getTag('invite') if invite is not None: data['muc'] = properties.jid.new_as_bare() data['from_'] = JID.from_string(invite.getAttr('from')) data['reason'] = invite.getTagData('reason') data['password'] = muc_user.getTagData('password') data['type'] = InviteType.MEDIATED data['continued'] = False data['thread'] = None continue_ = invite.getTag('continue') if continue_ is not None: data['continued'] = True data['thread'] = continue_.getAttr('thread') properties.muc_invite = InviteData(**data) return decline = muc_user.getTag('decline') if decline is not None: data['muc'] = properties.jid.new_as_bare() data['from_'] = JID.from_string(decline.getAttr('from')) data['reason'] = decline.getTagData('reason') properties.muc_decline = DeclineData(**data) return
def _test_credentials(self, ignore_all_errors=False): self._show_progress_page(_('Connecting...'), _('Connecting to server...')) address, password = self.get_page('login').get_credentials() jid = JID.from_string(address) advanced = self.get_page('login').is_advanced() self._client = self._get_base_client(jid.domain, jid.localpart, Mode.LOGIN_TEST, advanced, ignore_all_errors) self._client.set_password(password) self._client.subscribe('login-successful', self._on_login_successful) self._client.connect()
def _on_apply_clicked(self, _button): bookmarks = [] for row in self._ui.bookmarks_store: if not row[Column.ADDRESS]: continue bookmark = BookmarkData(jid=JID(row[Column.ADDRESS]), name=row[Column.NAME], autojoin=row[Column.AUTOJOIN], password=row[Column.PASSWORD], nick=row[Column.NICK]) bookmarks.append(bookmark) con = app.connections[self.account] con.get_module('Bookmarks').store_difference(bookmarks) self.destroy()
def validate_jid(jid, type_=None): try: jid = JID.from_string(str(jid)) except InvalidJid as error: raise ValueError(error) if type_ is None: return jid if type_ == 'bare' and jid.is_bare: return jid if type_ == 'full' and jid.is_full: return jid if type_ == 'domain' and jid.is_domain: return jid raise ValueError('Not a %s JID' % type_)
def _start_new_chat(self, row): if row.new: try: JID(row.jid) except InvalidJid as error: self._show_error_page(error) return if row.groupchat: if not app.account_is_connected(row.account): self._show_error_page( _('You can not join a group chat ' 'unless you are connected.')) return self._disco_muc(row.account, row.jid) else: app.interface.new_chat_from_jid(row.account, row.jid) self.ready_to_destroy = True
def _process_muc_message(self, properties): room_jid = properties.jid.getBare() resource = properties.jid.getResource() if properties.muc_ofrom is not None: # History Message from MUC return properties.muc_ofrom.getBare() contact = app.contacts.get_gc_contact(self._account, room_jid, resource) if contact is not None: return JID(contact.jid).getBare() self._log.info('Groupchat: Last resort trying to find SID in DB') from_jid = self.backend.storage.getJidFromDevice(properties.omemo.sid) if not from_jid: self._log.error("Can't decrypt GroupChat Message from %s", resource) return return from_jid
def parse_muc_user(muc_user, is_presence=True): item = muc_user.getTag('item') if item is None: return None item_dict = item.getAttrs() role = item_dict.get('role') if role is not None: try: role = Role(role) except ValueError: raise StanzaMalformed('invalid role %s' % role) elif is_presence: # role attr MUST be included in all presence broadcasts raise StanzaMalformed('role attr missing') affiliation = item_dict.get('affiliation') if affiliation is not None: try: affiliation = Affiliation(affiliation) except ValueError: raise StanzaMalformed('invalid affiliation %s' % affiliation) elif is_presence: # affiliation attr MUST be included in all presence broadcasts raise StanzaMalformed('affiliation attr missing') jid = item_dict.get('jid') if jid is not None: try: jid = JID.from_string(jid) except InvalidJid as error: raise StanzaMalformed('invalid jid %s, %s' % (jid, error)) return MucUserData(affiliation=affiliation, jid=jid, nick=item.getAttr('nick'), role=role, actor=item.getTagAttr('actor', 'nick'), reason=item.getTagData('reason'))
def _process_groupchat_message(self, _client, stanza, properties): properties.from_muc = True properties.muc_jid = properties.jid.new_as_bare() properties.muc_nickname = properties.jid.resource muc_user = stanza.getTag('x', namespace=Namespace.MUC_USER) if muc_user is not None: try: properties.muc_user = parse_muc_user(muc_user, is_presence=False) except StanzaMalformed as error: self._log.warning(error) self._log.warning(stanza) raise NodeProcessed addresses = stanza.getTag('addresses', namespace=Namespace.ADDRESS) if addresses is not None: address = addresses.getTag('address', attrs={'type': 'ofrom'}) if address is not None: properties.muc_ofrom = JID.from_string(address.getAttr('jid'))
def _process_direct_invite(_client, stanza, properties): direct = stanza.getTag('x', namespace=Namespace.CONFERENCE) if direct is None: return if stanza.getTag('x', namespace=Namespace.MUC_USER) is not None: # not a direct invite # See https://xmpp.org/extensions/xep-0045.html#example-57 # read implementation notes return data = {} data['muc'] = JID.from_string(direct.getAttr('jid')) data['from_'] = properties.jid data['reason'] = direct.getAttr('reason') data['password'] = direct.getAttr('password') data['continued'] = direct.getAttr('continue') == 'true' data['thread'] = direct.getAttr('thread') data['type'] = InviteType.DIRECT properties.muc_invite = InviteData(**data)
def parse_signcrypt(stanza): ''' <signcrypt xmlns='urn:xmpp:openpgp:0'> <to jid='*****@*****.**'/> <time stamp='2014-07-10T17:06:00+02:00'/> <rpad> f0rm1l4n4-mT8y33j!Y%fRSrcd^ZE4Q7VDt1L%WEgR!kv </rpad> <payload> <body xmlns='jabber:client'> This is a secret message. </body> </payload> </signcrypt> ''' if (stanza.getName() != 'signcrypt' or stanza.getNamespace() != Namespace.OPENPGP): raise StanzaMalformed('Invalid signcrypt node') to_nodes = stanza.getTags('to') if not to_nodes: raise StanzaMalformed('missing to nodes') recipients = [] for to_node in to_nodes: jid = to_node.getAttr('jid') try: recipients.append(JID.from_string(jid)) except Exception as error: raise StanzaMalformed('Invalid jid: %s %s' % (jid, error)) timestamp = stanza.getTagAttr('time', 'stamp') if timestamp is None: raise StanzaMalformed('Invalid timestamp') payload = stanza.getTag('payload') if payload is None or payload.getChildren() is None: raise StanzaMalformed('Invalid payload node') return payload.getChildren(), recipients, timestamp
def set_os_info(self, task): error = False try: result = task.finish() except StanzaError: error = True jid = task.get_user_data() if self.xml.get_object('information_notebook').get_n_pages() < 5: return i = 0 client = '' os_info = '' while i in self.os_info: if self.os_info[i]['resource'] == JID.from_string(jid).resource: if not error: self.os_info[i]['client'] = '%s %s' % (result.name, result.version) else: self.os_info[i]['client'] = Q_('?Client:Unknown') if not error and result.os is not None: self.os_info[i]['os'] = result.os else: self.os_info[i]['os'] = Q_('?OS:Unknown') if i > 0: client += '\n' os_info += '\n' client += self.os_info[i]['client'] os_info += self.os_info[i]['os'] i += 1 self.xml.get_object('client_name_version_label').set_text(client) self.xml.get_object('os_label').set_text(os_info) self.os_info_arrived = True