示例#1
0
 def test_jid_true(self):
     jid = JID("user@host/res")
     self.assertTrue(jid.validate())
示例#2
0
 def test_bad_jids_false(self):
     for testjid in self.badjids:
         jid = JID(testjid, validate_on_init=False)
         self.assertFalse(jid.validate())
示例#3
0
 def test_bad_jid_inject(self):
     jid = JID('test')
     jid.domain = None
     with self.assertRaises(ValueError) as cm:
         jid.validate(True)
示例#4
0
class Contact(Base):
    """Jabber Contact, aka roster item. It has some really strict attribute
       setting mechanism as it leads to all kinds of fantastic crashes with
       clients which should be avoided in any case.
    """

    __tablename__ = 'contacts'

    id = Column(Integer, primary_key=True)
    approved = Column(Boolean)
    ask = Column(Enum('subscribe'))
    jid = Column(JIDString, nullable=False)
    name = Column(String(255))
    subscription = Column(Enum("none", "from", "to", "remove", "both"))
    groups = relationship(Group, secondary=contacts_groups)
    roster = relationship(Roster, backref=backref('contacts'))
    roster_id = Column(Integer, ForeignKey('rosters.id'), nullable=False)

    def __init__(self, jid, **kwds):
        super(Contact, self).__init__()

        # required
        if isinstance(jid, basestring):
            self.jid = JID(jid)
        elif isinstance(jid, JID):
            self.jid = jid
            self.jid.validate(raise_error=True)
        else:
            raise AttributeError(
                "Needs valid jid either as string or JID instance")

        # optional
        self.approved = False
        self.ask = None
        self.name = None
        self.subscription = "none"
        self.groups = []

        for k, v in kwds.iteritems():
            setattr(self, k, v)

    def to_element(self):
        """Formats contact as `class`:ET.Element object"""

        element = ET.Element("item")
        if self.approved is not None:
            element.set("approved", 'true' if self.approved else 'false')
        if self.ask is not None:
            element.set("ask", self.ask)
        element.set("jid", str(self.jid))
        if self.name is not None:
            element.set("name", self.name)
        if self.subscription is not None:
            element.set("subscription", self.subscription)
        for group in self.groups:
            group_element = ET.SubElement(element, "group")
            group_element.text = group
        return element

    @staticmethod
    def from_element(element):
        """Creates contact instance from `class`:ET.Element"""

        if element.tag != "item":
            raise ValueError("Invalid element with tag %s" % element.tag)

        cont = Contact(element.get('jid'))
        cont.ask = element.get('ask')
        cont.subscription = element.get('subscription')
        approved = element.get('approved')
        if approved == 'true':
            cont.approved = True
        elif approved == 'false':
            cont.approved = False
        else:
            cont.approved = approved
        for group in list(element):
            if group.tag == "group":
                cont.groups.append(group.text)
        return cont
示例#5
0
class Contact(Base):
    """Jabber Contact, aka roster item. It has some really strict attribute
       setting mechanism as it leads to all kinds of fantastic crashes with
       clients which should be avoided in any case.
    """

    __tablename__ = 'contacts'

    id = Column(Integer, primary_key=True)
    approved = Column(Boolean)
    ask = Column(Enum('subscribe'))
    jid = Column(JIDString, nullable=False)
    name = Column(String(255))
    subscription = Column(Enum("none", "from", "to", "remove", "both"))
    groups = relationship(Group, secondary=contacts_groups)
    roster = relationship(Roster, backref=backref('contacts'))
    roster_id = Column(Integer, ForeignKey('rosters.id'), nullable=False)

    def __init__(self, jid, **kwds):
        super(Contact, self).__init__()

        # required
        if isinstance(jid, basestring):
            self.jid = JID(jid)
        elif isinstance(jid, JID):
            self.jid = jid
            self.jid.validate(raise_error=True)
        else:
            raise AttributeError("Needs valid jid either as string or JID instance")

        # optional
        self.approved = False
        self.ask = None
        self.name = None
        self.subscription = "none"
        self.groups = []

        for k, v in kwds.iteritems():
            setattr(self, k, v)

    def to_element(self):
        """Formats contact as `class`:ET.Element object"""

        element = ET.Element("item")
        if self.approved is not None:
            element.set("approved", 'true' if self.approved else 'false')
        if self.ask is not None:
            element.set("ask", self.ask)
        element.set("jid", str(self.jid))
        if self.name is not None:
            element.set("name", self.name)
        if self.subscription is not None:
            element.set("subscription", self.subscription)
        for group in self.groups:
            group_element = ET.SubElement(element, "group")
            group_element.text = group
        return element

    @staticmethod
    def from_element(element):
        """Creates contact instance from `class`:ET.Element"""

        if element.tag != "item":
            raise ValueError("Invalid element with tag %s" % element.tag)

        cont = Contact(element.get('jid'))
        cont.ask = element.get('ask')
        cont.subscription = element.get('subscription')
        approved = element.get('approved')
        if approved == 'true':
            cont.approved = True
        elif approved == 'false':
            cont.approved = False
        else:
            cont.approved = approved
        for group in list(element):
            if group.tag == "group":
                cont.groups.append(group.text)
        return cont
示例#6
0
class Iq(object):
    """This Class handles <iq> XMPP frames"""

    def __init__(self):
        super(Iq, self).__init__()
        self.from_jid = None

    def create_response(self, content, iq_id=None):
        """Set up an iq response"""
        # prepare result header
        iq = ET.Element("iq")
        iq.set("id", iq_id or self.tree.get("id"))
        iq.set("type", "result")
        iq.set("from", self.from_jid.domain)
        iq.set("to", self.tree.get("from"))
        iq.append(content)
        return iq

    def handle(self, tree):
        """<iq> handler, returns one or more <iq> tags with results and new ones if required"""

        self.from_jid = JID(tree.get("from"))
        self.tree = tree

        responses = []
        # dispatch to the handler for the given request query
        for req in list(tree):
            if tree.get("type") == "get":
                try:
                    data = self.get_handler[req.tag](self, req)
                    if data != None:
                        responses.append(self.create_response(data))
                except KeyError as e:
                    for elem in self.failure(req):
                        iq.append(elem)
                    iq.set("type", "error")
        # return the result
        return responses

    def bind(self, request):
        """Handles bind requests"""
        bind = ET.Element("bind")
        bind.set("xmlns", "urn:ietf:params:xml:ns:xmpp-bind")
        jid = ET.SubElement(bind, "jid")
        # add resource to JID if provided
        if request.find("resource") != None:
            self.from_jid.resource = request.find("resource").text
            if not self.from_jid.validate():
                self.from_jid.resource = None

        jid.text = unicode(self.from_jid)
        return bind

    def session(self, request):
        """ No-op as suggested in RFC6121 Appendix E.
            Session establishment had been defined in RFC3921 Section 3
            and marked depricated in RFC6121.
        """
        return None

    def query(self, request):
        """Implements the query command"""
        handler = Query()
        return handler.handle(request, self.tree.get("from"))

    def ping(self, request):
        """A No-op for XEP-0199"""

    def vcard(self, request):
        """Returns the users vCard as specified by XEP-0054"""

        # TODO: Stub - Implement real vCard storage
        return ET.Element("vCard")

    def failure(self, requested_service):
        error = ET.Element("error")
        error.set("type", "cancel")
        service = ET.SubElement(error, "service-unavailable")
        service.set("xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas")
        return [requested_service, error]

    get_handler = {
      'bind': bind,
      'session': session,
      'query': query,
      'ping': ping,
      'vCard': vcard
    }
示例#7
0
class Iq(object):
    """This Class handles <iq> XMPP frames"""
    def __init__(self):
        super(Iq, self).__init__()
        self.from_jid = None

    def create_response(self, content, iq_id=None):
        """Set up an iq response"""
        # prepare result header
        iq = ET.Element("iq")
        iq.set("id", iq_id or self.tree.get("id"))
        iq.set("type", "result")
        iq.set("from", self.from_jid.domain)
        iq.set("to", self.tree.get("from"))
        iq.append(content)
        return iq

    def handle(self, tree):
        """<iq> handler, returns one or more <iq> tags with results and new ones if required"""

        self.from_jid = JID(tree.get("from"))
        self.tree = tree

        responses = []
        # dispatch to the handler for the given request query
        for req in list(tree):
            if tree.get("type") == "get":
                try:
                    data = self.get_handler[req.tag](self, req)
                    if data != None:
                        responses.append(self.create_response(data))
                except KeyError as e:
                    for elem in self.failure(req):
                        iq.append(elem)
                    iq.set("type", "error")
        # return the result
        return responses

    def bind(self, request):
        """Handles bind requests"""
        bind = ET.Element("bind")
        bind.set("xmlns", "urn:ietf:params:xml:ns:xmpp-bind")
        jid = ET.SubElement(bind, "jid")
        # add resource to JID if provided
        if request.find("resource") != None:
            self.from_jid.resource = request.find("resource").text
            if not self.from_jid.validate():
                self.from_jid.resource = None

        jid.text = unicode(self.from_jid)
        return bind

    def session(self, request):
        """ No-op as suggested in RFC6121 Appendix E.
            Session establishment had been defined in RFC3921 Section 3
            and marked depricated in RFC6121.
        """
        return None

    def query(self, request):
        """Implements the query command"""
        handler = Query()
        return handler.handle(request, self.tree.get("from"))

    def ping(self, request):
        """A No-op for XEP-0199"""

    def vcard(self, request):
        """Returns the users vCard as specified by XEP-0054"""

        # TODO: Stub - Implement real vCard storage
        return ET.Element("vCard")

    def failure(self, requested_service):
        error = ET.Element("error")
        error.set("type", "cancel")
        service = ET.SubElement(error, "service-unavailable")
        service.set("xmlns", "urn:ietf:params:xml:ns:xmpp-stanzas")
        return [requested_service, error]

    get_handler = {
        'bind': bind,
        'session': session,
        'query': query,
        'ping': ping,
        'vCard': vcard
    }