Skip to content

Commit 1610019

Browse files
committed
Merge branch 'patch' of https://github.com/chenhouwu/django-conversejs into chenhouwu-patch
Conflicts: conversejs/utils.py
2 parents 0e94cc0 + f3fc19e commit 1610019

4 files changed

Lines changed: 82 additions & 65 deletions

File tree

conversejs/boshclient.py

Lines changed: 54 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,16 @@
1414
from urlparse import urlparse
1515
from xml.etree import ElementTree as ET
1616

17-
from puresasl.client import SASLClient
17+
from puresasl.client import SASLClient
18+
from .conf import get_conversejs_settings
19+
20+
21+
try: # Python 2.7+
22+
from logging import NullHandler
23+
except ImportError:
24+
class NullHandler(logging.Handler):
25+
def emit(self, record):
26+
pass
1827

1928

2029
HTTPBIND_NS = 'http://jabber.org/protocol/httpbind'
@@ -44,23 +53,27 @@ def __init__(self, jid, password, bosh_service):
4453

4554
self._connection = None
4655
self._sid = None
47-
56+
4857
self.jid, self.to = jid.split('@')
4958
self.password = password
50-
self.bosh_service = urlparse(bosh_service)
51-
59+
self.bosh_service = urlparse(bosh_service)
60+
5261
self.rid = randint(0, 10000000)
5362
self.log.debug('Init RID: %s' % self.rid)
54-
63+
5564
self.headers = {
5665
"Content-Type": "text/plain; charset=UTF-8",
5766
"Accept": "text/xml",
5867
"Accept-Encoding": "gzip, deflate"
5968
}
60-
69+
6170
self.server_auth = []
62-
63-
@property
71+
72+
converse_settings = get_conversejs_settings()
73+
xml_encoding_line = converse_settings['CONVERSEJS_XML_ENCODING_LINE']
74+
self.xml_encoding_line = True if xml_encoding_line.lower() == 'true' else False
75+
76+
@property
6477
def connection(self):
6578
"""Returns an stablished connection"""
6679

@@ -74,9 +87,9 @@ def connection(self):
7487
elif self.bosh_service.scheme == 'https':
7588
Connection = httplib.HTTPSConnection
7689
else:
77-
# TODO: raise proper exception
90+
# TODO: raise proper exception
7891
raise Exception('Invalid URL scheme %s' % self.bosh_service.scheme)
79-
92+
8093
self._connection = Connection(self.bosh_service.netloc)
8194
self.log.debug('Connection initialized')
8295
# TODO add exceptions handler there (URL not found etc)
@@ -86,7 +99,7 @@ def connection(self):
8699
def close_connection(self):
87100
if not self._connection:
88101
self.log.debug('Trying to close connection before initializing it.')
89-
return
102+
return
90103

91104
self.log.debug('Closing connection')
92105
self.connection.close()
@@ -99,7 +112,7 @@ def get_body(self, sid_request=False):
99112
body.set('xmlns', HTTPBIND_NS)
100113

101114
if sid_request:
102-
body.set('xmlns:xmpp', BOSH_NS)
115+
body.set('xmlns:xmpp', BOSH_NS)
103116
body.set('wait', unicode(BOSH_WAIT))
104117
body.set('hold', unicode(BOSH_HOLD))
105118
body.set('content', BOSH_CONTENT)
@@ -112,15 +125,17 @@ def get_body(self, sid_request=False):
112125
body.set('to', self.to)
113126

114127
if self._sid:
115-
body.set('sid', self.sid)
128+
body.set('sid', self.sid)
116129

117130
body.set('rid', str(self.rid))
118131

119132
return body
120133

121134
def send_request(self, xml_stanza):
122-
if isinstance(xml_stanza, ET.Element):
123-
xml_stanza = ET.tostring(xml_stanza, encoding='utf8', method='xml')
135+
ElementType = getattr(ET, '_Element', ET.Element)
136+
if isinstance(xml_stanza, ElementType):
137+
xml_stanza = ET.tostring(xml_stanza) if not self.xml_encoding_line\
138+
else ET.tostring(xml_stanza, encoding='utf8')
124139

125140
self.log.debug('XML_STANZA: %s', xml_stanza)
126141
self.log.debug('Sending the request')
@@ -147,7 +162,7 @@ def send_request(self, xml_stanza):
147162
def sid(self):
148163
if self._sid:
149164
return self._sid
150-
165+
151166
return self.request_sid()
152167

153168
def request_sid(self):
@@ -160,44 +175,44 @@ def request_sid(self):
160175
return self._sid
161176

162177
self.log.debug('Prepare to request BOSH session')
163-
178+
164179
data = self.send_request(self.get_body(sid_request=True))
165180
if not data:
166181
return None
167-
182+
168183

169184
# This is XML. response_body contains the <body/> element of the
170185
# response.
171186
response_body = ET.fromstring(data)
172-
187+
173188
# Get the remote Session ID
174189
self._sid = response_body.get('sid')
175190
self.log.debug('sid = %s' % self._sid)
176-
191+
177192
# Get the longest time (s) that the XMPP server will wait before
178193
# responding to any request.
179194
self.server_wait = response_body.get('wait')
180195
self.log.debug('wait = %s' % self.server_wait)
181-
196+
182197
# Get the authid
183198
self.authid = response_body.get('authid')
184-
199+
185200
# Get the allowed authentication methods using xpath
186-
search_for = '{{{}}}features/{{{}}}mechanisms/{{{}}}mechanism'.format(
201+
search_for = '{{{0}}}features/{{{1}}}mechanisms/{{{2}}}mechanism'.format(
187202
JABBER_STREAMS_NS, XMPP_SASL_NS, XMPP_SASL_NS)
188203
self.log.debug('Looking for "%s" into response body', search_for)
189204
mechanisms = response_body.iterfind(search_for)
190205
self.server_auth = []
191206

192207
for mechanism in mechanisms:
193-
self.server_auth.append(mechanism.text)
208+
self.server_auth.append(mechanism.text)
194209
self.log.debug('New AUTH method: %s' % mechanism.text)
195210

196211
if not self.server_auth:
197212
self.log.debug(('The server didn\'t send the allowed '
198213
'authentication methods'))
199214
self._sid = None
200-
215+
201216
return self._sid
202217

203218
def get_challenge(self, mechanism):
@@ -207,10 +222,10 @@ def get_challenge(self, mechanism):
207222
auth.set('mechanism', mechanism)
208223

209224
resp_root = ET.fromstring(self.send_request(body))
210-
challenge_node = resp_root.find('{{{}}}challenge'.format(XMPP_SASL_NS))
225+
challenge_node = resp_root.find('{{{0}}}challenge'.format(XMPP_SASL_NS))
211226

212227
if challenge_node is not None:
213-
return challenge_node.text
228+
return challenge_node.text
214229

215230
return None
216231

@@ -222,16 +237,16 @@ def send_challenge_response(self, response_plain):
222237

223238
# Create a response tag and add the response content on it
224239
# using base64 encoding
225-
response_node = ET.SubElement(body, 'response')
240+
response_node = ET.SubElement(body, 'response')
226241
response_node.set('xmlns', XMPP_SASL_NS)
227242
response_node.text = base64.b64encode(response_plain)
228243

229244
# Send the challenge response to server
230245
resp_root = ET.fromstring(self.send_request(body))
231246

232247
# Look for the success tag. If it's not present authentication
233-
# has failed
234-
success = resp_root.find('{{{}}}success'.format(XMPP_SASL_NS))
248+
# has failed
249+
success = resp_root.find('{{{0}}}success'.format(XMPP_SASL_NS))
235250
if success is not None:
236251
return True
237252
return False
@@ -243,7 +258,7 @@ def authenticate_xmpp(self):
243258

244259
self.log.debug('Prepare the XMPP authentication')
245260

246-
# Instantiate a sasl object
261+
# Instantiate a sasl object
247262
sasl = SASLClient(host=self.to,
248263
service='xmpp',
249264
username=self.jid,
@@ -254,7 +269,7 @@ def authenticate_xmpp(self):
254269

255270
# Request challenge
256271
challenge = self.get_challenge(sasl.mechanism)
257-
272+
258273
# Process challenge and generate response
259274
response = sasl.process(base64.b64decode(challenge))
260275

@@ -266,7 +281,7 @@ def authenticate_xmpp(self):
266281
self.request_restart()
267282

268283
self.bind_resource()
269-
284+
270285
return True
271286

272287
def bind_resource(self):
@@ -275,10 +290,10 @@ def bind_resource(self):
275290
iq = ET.SubElement(body, 'iq')
276291
iq.set('id', 'bind_1')
277292
iq.set('type', 'set')
278-
iq.set('xmlns', JABBER_CLIENT_NS)
293+
iq.set('xmlns', JABBER_CLIENT_NS)
279294

280295
bind = ET.SubElement(iq, 'bind')
281-
bind.set('xmlns', XMPP_BIND_NS)
296+
bind.set('xmlns', XMPP_BIND_NS)
282297

283298
self.send_request(body)
284299

@@ -289,18 +304,18 @@ def request_restart(self):
289304
self.send_request(body)
290305

291306
def get_credentials(self):
292-
success = self.authenticate_xmpp()
307+
success = self.authenticate_xmpp()
293308
if not success:
294309
return None, None, None
295310

296-
return u'{}@{}'.format(self.jid, self.to), self.sid, self.rid
297-
311+
return u'{0}@{1}'.format(self.jid, self.to), self.sid, self.rid
312+
298313

299314
if __name__ == '__main__':
300315
import sys
301316

302317
if len(sys.argv) != 4:
303-
print 'usage: {} SERVICE_URL USERNAME PASSWORD'.format(sys.argv[0])
318+
print 'usage: {0} SERVICE_URL USERNAME PASSWORD'.format(sys.argv[0])
304319
sys.exit(1)
305320

306321
c = BOSHClient(sys.argv[2], sys.argv[3], sys.argv[1])

conversejs/conf.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
from django.conf import settings
2+
3+
4+
def get_conversejs_settings():
5+
converse_settings = {
6+
'CONVERSEJS_AUTO_LIST_ROOMS': False,
7+
'CONVERSEJS_AUTO_SUBSCRIBE': False,
8+
'CONVERSEJS_BOSH_SERVICE_URL': 'https://bind.opkode.im',
9+
'CONVERSEJS_HIDE_MUC_SERVER': False,
10+
'CONVERSEJS_PREBIND': True,
11+
'CONVERSEJS_SHOW_CONTROLBOX_BY_DEFAULT': False,
12+
'CONVERSEJS_XHR_USER_SEARCH': False,
13+
'CONVERSEJS_XML_ENCODING_LINE': True,
14+
'CONVERSEJS_DEBUG': settings.DEBUG,
15+
}
16+
17+
for key, value in converse_settings.items():
18+
conf = getattr(settings, key, value)
19+
20+
if isinstance(conf, bool):
21+
conf = unicode(conf).lower()
22+
23+
converse_settings[key] = conf
24+
25+
return converse_settings

conversejs/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ class XMPPAccount(models.Model):
1515
password = models.CharField(max_length=1024)
1616

1717
def __unicode__(self):
18-
return u'{}/{}'.format(self.user, self.jid)
18+
return u'{0}/{1}'.format(self.user, self.jid)

conversejs/utils.py

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,12 @@
11

22
import uuid
33

4-
from django.conf import settings
4+
from .conf import get_conversejs_settings
55
from .models import XMPPAccount
66
from .boshclient import BOSHClient
77
from .register import register_account
88

99

10-
def get_conversejs_settings():
11-
converse_settings = {
12-
'CONVERSEJS_AUTO_LIST_ROOMS': False,
13-
'CONVERSEJS_AUTO_SUBSCRIBE': False,
14-
'CONVERSEJS_BOSH_SERVICE_URL': 'https://bind.opkode.im',
15-
'CONVERSEJS_HIDE_MUC_SERVER': False,
16-
'CONVERSEJS_PREBIND': True,
17-
'CONVERSEJS_SHOW_CONTROLBOX_BY_DEFAULT': False,
18-
'CONVERSEJS_XHR_USER_SEARCH': False,
19-
'CONVERSEJS_DEBUG': settings.DEBUG,
20-
}
21-
22-
for key, value in converse_settings.items():
23-
conf = getattr(settings, key, value)
24-
25-
if isinstance(conf, bool):
26-
conf = unicode(conf).lower()
27-
28-
converse_settings[key] = conf
29-
30-
return converse_settings
31-
32-
3310
def get_conversejs_context(context, xmpp_login=False):
3411
context.update(get_conversejs_settings())
3512

@@ -59,7 +36,7 @@ def get_conversejs_context(context, xmpp_login=False):
5936
user=request.user)
6037

6138
bosh = BOSHClient(xmpp_account.jid, xmpp_account.password,
62-
settings.CONVERSEJS_BOSH_SERVICE_URL)
39+
context['CONVERSEJS_BOSH_SERVICE_URL'])
6340
jid, sid, rid = bosh.get_credentials()
6441
context.update({'jid': jid, 'sid': sid, 'rid': rid})
6542

0 commit comments

Comments
 (0)