示例#1
0
    def request_catalog(self, jid):
        _task = yield

        response = yield _make_catalog_request(self._client.domain, jid)
        if response.isError():
            raise StanzaError(response)

        catalog_node = response.getTag('catalog',
                                       namespace=Namespace.SECLABEL_CATALOG)
        to = catalog_node.getAttr('to')
        items = catalog_node.getTags('item')

        labels = {}
        default = None
        for item in items:
            label = item.getAttr('selector')
            if label is None:
                continue

            security = item.getTag('securitylabel',
                                   namespace=Namespace.SECLABEL)
            if security is None:
                continue

            try:
                security_label = SecurityLabel.from_node(security)
            except ValueError:
                continue

            labels[label] = security_label

            if item.getAttr('default') == 'true':
                default = label

        yield Catalog(labels=labels, default=default)
示例#2
0
    def disco_items(self, jid, node=None):
        _task = yield

        response = yield get_disco_request(Namespace.DISCO_ITEMS, jid, node)
        if response.isError():
            raise StanzaError(response)
        yield parse_disco_items(response)
示例#3
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)
示例#4
0
    def request_command_list(self, jid=None):
        _task = yield

        if jid is None:
            jid = self._client.get_bound_jid().bare
        response = yield get_disco_request(Namespace.DISCO_ITEMS,
                                           jid,
                                           node=Namespace.COMMANDS)
        if response.isError():
            raise StanzaError(response)

        payload = response.getQueryPayload()
        if payload is None:
            raise MalformedStanzaError('query payload missing', response)

        command_list = []
        for item in payload:
            if item.getName() != 'item':
                continue
            try:
                command_list.append(AdHocCommand(**item.getAttrs()))
            except Exception as error:
                raise MalformedStanzaError(f'invalid item attributes: {error}',
                                           response)

        yield command_list
示例#5
0
    def request_preferences(self):
        _task = yield

        response = yield _make_pref_request()
        if response.isError():
            raise StanzaError(response)

        prefs = response.getTag('prefs', namespace=Namespace.MAM_2)
        if prefs is None:
            raise MalformedStanzaError('prefs node missing', response)

        default = prefs.getAttr('default')
        if default is None:
            raise MalformedStanzaError('default attr missing', response)

        always_node = prefs.getTag('always')
        if always_node is None:
            raise MalformedStanzaError('always node missing', response)

        always = _get_preference_jids(always_node)

        never_node = prefs.getTag('never')
        if never_node is None:
            raise MalformedStanzaError('never node missing', response)

        never = _get_preference_jids(never_node)
        yield MAMPreferencesData(default=default,
                                 always=always,
                                 never=never)
示例#6
0
    def make_query(self,
                   jid,
                   queryid=None,
                   start=None,
                   end=None,
                   with_=None,
                   after=None,
                   max_=70):

        _task = yield

        response = yield _make_request(jid, queryid,
                                       start, end, with_, after, max_)
        if response.isError():
            raise StanzaError(response)

        jid = response.getFrom()
        fin = response.getTag('fin', namespace=Namespace.MAM_2)
        if fin is None:
            raise MalformedStanzaError('fin node missing', response)

        rsm = parse_rsm(fin)
        if rsm is None:
            raise MalformedStanzaError('rsm set missing', response)

        complete = fin.getAttr('complete') == 'true'
        if not complete:
            if rsm.first is None or rsm.last is None:
                raise MalformedStanzaError('first or last element missing',
                                           response)

        yield MAMQueryData(jid=jid,
                           complete=complete,
                           rsm=rsm)
示例#7
0
    def request_entity_time(self, jid):
        _task = yield

        response = yield _make_request(jid)
        if response.isError():
            raise StanzaError(response)

        yield _parse_response(response)
示例#8
0
    def request_last_activity(self, jid):
        _task = yield

        response = yield _make_request(jid)
        if response.isError():
            raise StanzaError(response)

        yield _parse_response(response)
    def request_software_version(self, jid):
        _task = yield

        response = yield Iq(typ='get', to=jid, queryNS=Namespace.VERSION)
        if response.isError():
            raise StanzaError(response)

        yield _parse_info(response)
示例#10
0
    def set_search(self, jid, dataform, items_per_page=50, after=None):
        _task = yield

        response = yield _make_search_query(jid, dataform, items_per_page,
                                            after)
        if response.isError():
            raise StanzaError(response)

        result = response.getTag('result', namespace=Namespace.MUCLUMBUS)
        if result is None:
            raise MalformedStanzaError('result node missing', response)

        items = result.getTags('item')
        if not items:
            yield MuclumbusResult(first=None,
                                  last=None,
                                  max=None,
                                  end=True,
                                  items=[])

        set_ = result.getTag('set', namespace=Namespace.RSM)
        if set_ is None:
            raise MalformedStanzaError('set node missing', response)

        first = set_.getTagData('first')
        last = set_.getTagData('last')
        try:
            max_ = int(set_.getTagData('max'))
        except Exception:
            raise MalformedStanzaError('invalid max value', response)

        results = []
        for item in items:
            jid = item.getAttr('address')
            name = item.getTagData('name')
            nusers = item.getTagData('nusers')
            description = item.getTagData('description')
            language = item.getTagData('language')
            is_open = item.getTag('is-open') is not None

            try:
                anonymity_mode = AnonymityMode(
                    item.getTagData('anonymity-mode'))
            except ValueError:
                anonymity_mode = AnonymityMode.UNKNOWN
            results.append(
                MuclumbusItem(jid=jid,
                              name=name or '',
                              nusers=nusers or '',
                              description=description or '',
                              language=language or '',
                              is_open=is_open,
                              anonymity_mode=anonymity_mode))
        yield MuclumbusResult(first=first,
                              last=last,
                              max=max_,
                              end=len(items) < max_,
                              items=results)
示例#11
0
    def execute_command(self, command, action=None, dataform=None):
        _task = yield

        if action is None:
            action = AdHocAction.EXECUTE
        attrs = {
            'node': command.node,
            'xmlns': Namespace.COMMANDS,
            'action': action.value
        }
        if command.sessionid is not None:
            attrs['sessionid'] = command.sessionid

        response = yield _make_command(command, attrs, dataform)
        if response.isError():
            raise StanzaError(response)

        command = response.getTag('command', namespace=Namespace.COMMANDS)
        if command is None:
            raise MalformedStanzaError('command node missing', response)

        node = command.getAttr('node')
        if node is None:
            raise MalformedStanzaError('node attribute missing', response)

        sessionid = command.getAttr('sessionid')
        if sessionid is None:
            raise MalformedStanzaError('sessionid attribute missing', response)

        status = command.getAttr('status')
        if status is None:
            raise MalformedStanzaError('status attribute missing', response)

        if status not in ('executing', 'completed', 'canceled'):
            raise MalformedStanzaError('invalid status attribute %s' % status,
                                       response)

        status = AdHocStatus(status)

        try:
            notes = _parse_notes(command)
        except ValueError as error:
            raise MalformedStanzaError(error, response)

        try:
            actions, default = _parse_actions(command)
        except ValueError as error:
            raise MalformedStanzaError(error, response)

        yield AdHocCommand(jid=response.getFrom(),
                           name=None,
                           node=node,
                           sessionid=sessionid,
                           status=status,
                           data=command.getTag('x', namespace=Namespace.DATA),
                           actions=actions,
                           default=default,
                           notes=notes)
示例#12
0
    def request_delimiter(self):
        _task = yield

        response = yield _make_request()
        if response.isError():
            raise StanzaError(response)

        delimiter = response.getQuery().getTagData('roster') or None
        yield delimiter
示例#13
0
    def request_vcard(self, jid=None):
        _task = yield

        response = yield _make_vcard_request(jid)

        if response.isError():
            raise StanzaError(response)

        vcard_node = _get_vcard_node(response)
        yield VCard.from_node(vcard_node)
示例#14
0
    def change_password(self, password):
        _task = yield

        response = yield _make_password_change_request(self._client.domain,
                                                       self._client.username,
                                                       password)
        if not response.isError():
            yield process_response(response)

        else:
            query = response.getQuery()
            if query is None:
                raise StanzaError(response)

            form = get_form(query, 'jabber:iq:register:changepassword')
            if form is None or response.getType() != 'modify':
                raise StanzaError(response)

            raise ChangePasswordStanzaError(response, form)
示例#15
0
    def request_register_form(self, jid=None):
        _task = yield

        if jid is None:
            jid = self._client.domain

        response = yield Iq('get', Namespace.REGISTER, to=jid)
        if response.isError():
            raise StanzaError(response)

        yield _parse_register_data(response)
    def request_bookmarks(self):
        _task = yield

        response = yield get_private_request()
        if response.isError():
            raise StanzaError(response)

        bookmarks = parse_private_bookmarks(response, self._log)
        for bookmark in bookmarks:
            self._log.info(bookmark)

        yield bookmarks
示例#17
0
    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)
示例#18
0
    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))
示例#19
0
def _parse_register_data(response):
    query = response.getTag('query', namespace=Namespace.REGISTER)
    if query is None:
        raise StanzaError(response)

    instructions = query.getTagData('instructions') or None

    data = RegisterData(instructions=instructions,
                        form=_parse_form(response),
                        fields_form=_parse_fields_form(query),
                        oob_url=_parse_oob_url(query),
                        bob_data=parse_bob_data(query))

    if (data.form is None and data.fields_form is None
            and data.oob_url is None):
        raise MalformedStanzaError('invalid register response', response)

    return data
示例#20
0
    def request_blocking_list(self):
        _task = yield

        result = yield _make_blocking_list_request()
        if result.isError():
            raise StanzaError(result)

        blocklist = result.getTag('blocklist', namespace=Namespace.BLOCKING)
        if blocklist is None:
            raise MalformedStanzaError('blocklist node missing', result)

        blocked = set()
        for item in blocklist.getTags('item'):
            try:
                jid = JID.from_string(item.getAttr('jid'))
            except Exception:
                self._log.info('Invalid JID: %s', item.getAttr('jid'))
                continue

            blocked.add(jid)

        self._log.info('Received blocking list: %s', blocked)
        yield blocked
示例#21
0
    def request_roster(self, version=None):
        _task = yield

        ver_support = self._client.features.has_roster_version()
        if not ver_support:
            version = None

        if ver_support and version is None:
            version = ''

        self._log.info('Roster versioning supported: %s', ver_support)

        response = yield _make_request(version, ver_support)
        if response.isError():
            raise StanzaError(response)

        query = response.getTag('query', namespace=Namespace.ROSTER)
        if query is None:
            if not ver_support:
                raise MalformedStanzaError('query node missing', response)
            yield RosterData(None, version)

        pushed_items, version = self._parse_push(response, ver_support)
        yield RosterData(pushed_items, version)
示例#22
0
def process_response(response):
    if response.isError():
        raise StanzaError(response)

    return CommonResult(jid=response.getFrom())