Merge branch 'master' into develop

This commit is contained in:
Lance Stout 2012-10-15 22:27:30 -07:00
commit 77f2a339e1
7 changed files with 36 additions and 13 deletions

View File

@ -212,6 +212,10 @@ class BaseXMPP(XMLStream):
self.stream_version = xml.get('version', '') self.stream_version = xml.get('version', '')
self.peer_default_lang = xml.get('{%s}lang' % XML_NS, None) self.peer_default_lang = xml.get('{%s}lang' % XML_NS, None)
if not self.is_component and not self.stream_version:
log.warning('Legacy XMPP 0.9 protocol detected.')
self.event('legacy_protocol')
def process(self, *args, **kwargs): def process(self, *args, **kwargs):
"""Initialize plugins and begin processing the XML stream. """Initialize plugins and begin processing the XML stream.
@ -742,6 +746,8 @@ class BaseXMPP(XMLStream):
item = self.roster[pres['to']][pres['from']] item = self.roster[pres['to']][pres['from']]
if item['whitelisted']: if item['whitelisted']:
item.authorize() item.authorize()
if roster.auto_subscribe:
item.subscribe()
elif roster.auto_authorize: elif roster.auto_authorize:
item.authorize() item.authorize()
if roster.auto_subscribe: if roster.auto_subscribe:

View File

@ -273,6 +273,8 @@ class ClientXMPP(BaseXMPP):
# Don't continue if the feature requires # Don't continue if the feature requires
# restarting the XML stream. # restarting the XML stream.
return True return True
log.debug('Finished processing stream features.')
self.event('stream_negotiated')
def _handle_roster(self, iq): def _handle_roster(self, iq):
"""Update the roster after receiving a roster stanza. """Update the roster after receiving a roster stanza.

View File

@ -44,7 +44,7 @@ class FeatureMechanisms(BasePlugin):
} }
def plugin_init(self): def plugin_init(self):
if not self.use_mech and not self.xmpp.boundjid.user: if not self.use_mech and not self.xmpp.requested_jid.user:
self.use_mech = 'ANONYMOUS' self.use_mech = 'ANONYMOUS'
if self.sasl_callback is None: if self.sasl_callback is None:

View File

@ -541,6 +541,7 @@ register_stanza_plugin(VCardTemp, Logo, iterable=True)
register_stanza_plugin(VCardTemp, Mailer, iterable=True) register_stanza_plugin(VCardTemp, Mailer, iterable=True)
register_stanza_plugin(VCardTemp, Note, iterable=True) register_stanza_plugin(VCardTemp, Note, iterable=True)
register_stanza_plugin(VCardTemp, Nickname, iterable=True) register_stanza_plugin(VCardTemp, Nickname, iterable=True)
register_stanza_plugin(VCardTemp, Org, iterable=True)
register_stanza_plugin(VCardTemp, Photo, iterable=True) register_stanza_plugin(VCardTemp, Photo, iterable=True)
register_stanza_plugin(VCardTemp, ProdID, iterable=True) register_stanza_plugin(VCardTemp, ProdID, iterable=True)
register_stanza_plugin(VCardTemp, Rev, iterable=True) register_stanza_plugin(VCardTemp, Rev, iterable=True)

View File

@ -44,16 +44,27 @@ class XEP_0078(BasePlugin):
restart=False, restart=False,
order=self.order) order=self.order)
self.xmpp.add_event_handler('legacy_protocol',
self._handle_legacy_protocol)
register_stanza_plugin(Iq, stanza.IqAuth) register_stanza_plugin(Iq, stanza.IqAuth)
register_stanza_plugin(StreamFeatures, stanza.AuthFeature) register_stanza_plugin(StreamFeatures, stanza.AuthFeature)
def plugin_end(self): def plugin_end(self):
self.xmpp.del_event_handler('legacy_protocol',
self._handle_legacy_protocol)
self.xmpp.unregister_feature('auth', self.order) self.xmpp.unregister_feature('auth', self.order)
def _handle_auth(self, features): def _handle_auth(self, features):
# If we can or have already authenticated with SASL, do nothing. # If we can or have already authenticated with SASL, do nothing.
if 'mechanisms' in features['features']: if 'mechanisms' in features['features']:
return False return False
return self.authenticate()
def _handle_legacy_protocol(self, event):
self.authenticate()
def authenticate(self):
if self.xmpp.authenticated: if self.xmpp.authenticated:
return False return False
@ -62,13 +73,13 @@ class XEP_0078(BasePlugin):
# Step 1: Request the auth form # Step 1: Request the auth form
iq = self.xmpp.Iq() iq = self.xmpp.Iq()
iq['type'] = 'get' iq['type'] = 'get'
iq['to'] = self.xmpp.boundjid.host iq['to'] = self.xmpp.requested_jid.host
iq['auth']['username'] = self.xmpp.boundjid.user iq['auth']['username'] = self.xmpp.requested_jid.user
try: try:
resp = iq.send(now=True) resp = iq.send(now=True)
except IqError: except IqError as err:
log.info("Authentication failed: %s", resp['error']['condition']) log.info("Authentication failed: %s", err.iq['error']['condition'])
self.xmpp.event('failed_auth', direct=True) self.xmpp.event('failed_auth', direct=True)
self.xmpp.disconnect() self.xmpp.disconnect()
return True return True
@ -81,11 +92,11 @@ class XEP_0078(BasePlugin):
# Step 2: Fill out auth form for either password or digest auth # Step 2: Fill out auth form for either password or digest auth
iq = self.xmpp.Iq() iq = self.xmpp.Iq()
iq['type'] = 'set' iq['type'] = 'set'
iq['auth']['username'] = self.xmpp.boundjid.user iq['auth']['username'] = self.xmpp.requested_jid.user
# A resource is required, so create a random one if necessary # A resource is required, so create a random one if necessary
if self.xmpp.boundjid.resource: if self.xmpp.requested_jid.resource:
iq['auth']['resource'] = self.xmpp.boundjid.resource iq['auth']['resource'] = self.xmpp.requested_jid.resource
else: else:
iq['auth']['resource'] = '%s' % random.random() iq['auth']['resource'] = '%s' % random.random()
@ -109,12 +120,12 @@ class XEP_0078(BasePlugin):
result = iq.send(now=True) result = iq.send(now=True)
except IqError as err: except IqError as err:
log.info("Authentication failed") log.info("Authentication failed")
self.xmpp.disconnect()
self.xmpp.event("failed_auth", direct=True) self.xmpp.event("failed_auth", direct=True)
self.xmpp.disconnect()
except IqTimeout: except IqTimeout:
log.info("Authentication failed") log.info("Authentication failed")
self.xmpp.disconnect()
self.xmpp.event("failed_auth", direct=True) self.xmpp.event("failed_auth", direct=True)
self.xmpp.disconnect()
self.xmpp.features.add('auth') self.xmpp.features.add('auth')

View File

@ -69,6 +69,8 @@ class XEP_0084(BasePlugin):
metadata = MetaData() metadata = MetaData()
if items is None: if items is None:
items = [] items = []
if not isinstance(items, (list, set)):
items = [items]
for info in items: for info in items:
metadata.add_info(info['id'], info['type'], info['bytes'], metadata.add_info(info['id'], info['type'], info['bytes'],
height=info.get('height', ''), height=info.get('height', ''),

View File

@ -70,9 +70,10 @@ def tostring(xml=None, xmlns='', stream=None,
# Output the tag name and derived namespace of the element. # Output the tag name and derived namespace of the element.
namespace = '' namespace = ''
if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \ if tag_xmlns:
or not top_level and tag_xmlns != xmlns: if top_level and tag_xmlns not in [default_ns, xmlns, stream_ns] \
namespace = ' xmlns="%s"' % tag_xmlns or not top_level and tag_xmlns != xmlns:
namespace = ' xmlns="%s"' % tag_xmlns
if stream and tag_xmlns in stream.namespace_map: if stream and tag_xmlns in stream.namespace_map:
mapped_namespace = stream.namespace_map[tag_xmlns] mapped_namespace = stream.namespace_map[tag_xmlns]
if mapped_namespace: if mapped_namespace: