def test_jid_true(self): jid = JID("user@host/res") self.assertTrue(jid.validate())
def test_bad_jids_false(self): for testjid in self.badjids: jid = JID(testjid, validate_on_init=False) self.assertFalse(jid.validate())
def test_bad_jid_inject(self): jid = JID('test') jid.domain = None with self.assertRaises(ValueError) as cm: jid.validate(True)
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
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
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 }