Exemple #1
0
 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
Exemple #2
0
        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_)
Exemple #3
0
 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
Exemple #4
0
    def test_ip_literals(self):
        tests = [
            ('juliet@[2002:4559:1FE2::4559:1FE2]/res'),
            ('[email protected]/res'),
        ]

        for jid in tests:
            JID.from_string(jid)
Exemple #5
0
    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))
Exemple #6
0
    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'))
Exemple #8
0
    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)
Exemple #9
0
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
Exemple #10
0
    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)
Exemple #11
0
    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()
Exemple #12
0
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)
Exemple #13
0
    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)
Exemple #14
0
    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)
Exemple #15
0
    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)
Exemple #16
0
    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)
Exemple #17
0
    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)
Exemple #18
0
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
Exemple #19
0
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
Exemple #20
0
    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
Exemple #21
0
    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()
Exemple #22
0
    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()
Exemple #23
0
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_)
Exemple #24
0
    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
Exemple #25
0
    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
Exemple #26
0
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'))
Exemple #27
0
    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'))
Exemple #28
0
    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)
Exemple #29
0
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
Exemple #30
0
    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