Put message handlers in a class
darcs-hash:20070522172311-86b55-7109d61ce39481f12e1a02fe337a4b2bc92d8fdf.gz
This commit is contained in:
@@ -205,35 +205,7 @@ class JCLComponent(Component, object):
|
|||||||
self.handle_message)
|
self.handle_message)
|
||||||
self.send_stanzas(self.account_manager.probe_all_accounts_presence())
|
self.send_stanzas(self.account_manager.probe_all_accounts_presence())
|
||||||
|
|
||||||
def password_msg_handler_filter(message):
|
self.msg_handlers += [PasswordMessageHandler()]
|
||||||
name = message.get_to().node
|
|
||||||
bare_from_jid = unicode(message.get_from().bare())
|
|
||||||
accounts = Account.select(\
|
|
||||||
AND(Account.q.name == name, \
|
|
||||||
Account.q.user_jid == bare_from_jid))
|
|
||||||
if accounts.count() != 1:
|
|
||||||
print >>sys.stderr, "Account " + name + " for user " + bare_from_jid + " must be uniq"
|
|
||||||
_account = accounts[0]
|
|
||||||
if hasattr(_account, 'password') \
|
|
||||||
and hasattr(_account, 'waiting_password_reply') \
|
|
||||||
and re.compile("\[PASSWORD\]").search(message.get_subject()) \
|
|
||||||
is not None:
|
|
||||||
return accounts
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
def password_msg_handler(message, accounts):
|
|
||||||
_account = accounts[0]
|
|
||||||
lang_class = self.lang.get_lang_class_from_node(message.get_node())
|
|
||||||
_account.password = message.get_body()
|
|
||||||
_account.waiting_password_reply = False
|
|
||||||
msg = Message(from_jid = _account.jid, \
|
|
||||||
to_jid = message.get_from(), \
|
|
||||||
stanza_type = "normal", \
|
|
||||||
subject = lang_class.password_saved_for_session, \
|
|
||||||
body = lang_class.password_saved_for_session)
|
|
||||||
self.stream.send(msg)
|
|
||||||
self.msg_handlers += [(password_msg_handler, password_msg_handler_filter)]
|
|
||||||
|
|
||||||
def signal_handler(self, signum, frame):
|
def signal_handler(self, signum, frame):
|
||||||
"""Stop method handler
|
"""Stop method handler
|
||||||
@@ -472,12 +444,14 @@ class JCLComponent(Component, object):
|
|||||||
Handle password response message
|
Handle password response message
|
||||||
"""
|
"""
|
||||||
self.__logger.debug("MESSAGE: " + message.get_body())
|
self.__logger.debug("MESSAGE: " + message.get_body())
|
||||||
|
result = []
|
||||||
self.db_connect()
|
self.db_connect()
|
||||||
for (msg_handler, filter_func) in self.msg_handlers:
|
for msg_handler in self.msg_handlers:
|
||||||
accounts = filter_func(message)
|
accounts = msg_handler.filter(message)
|
||||||
if accounts is not None:
|
if accounts is not None:
|
||||||
msg_handler(message, accounts)
|
result += msg_handler.handle(message, self.lang, accounts)
|
||||||
self.db_disconnect()
|
self.db_disconnect()
|
||||||
|
self.send_stanzas(result)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
###########################################################################
|
###########################################################################
|
||||||
@@ -1118,3 +1092,57 @@ class AccountManager(object):
|
|||||||
body = _account.default_lang_class.check_error_body \
|
body = _account.default_lang_class.check_error_body \
|
||||||
% (exception)))
|
% (exception)))
|
||||||
return result
|
return result
|
||||||
|
|
||||||
|
class MessageHandler(object):
|
||||||
|
"""Message handling class"""
|
||||||
|
|
||||||
|
def filter(self, message):
|
||||||
|
"""Filter account to be processed by the handler
|
||||||
|
return all accounts. DB connection might already be opened."""
|
||||||
|
accounts = Account.select()
|
||||||
|
return accounts
|
||||||
|
|
||||||
|
def handle(self, message, lang, accounts):
|
||||||
|
"""Apply actions to do on given accounts
|
||||||
|
Do nothing by default"""
|
||||||
|
return []
|
||||||
|
|
||||||
|
class PasswordMessageHandler(MessageHandler):
|
||||||
|
"""Handle password message"""
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
"""Ḧandler constructor"""
|
||||||
|
self.password_regexp = re.compile("\[PASSWORD\]")
|
||||||
|
|
||||||
|
def filter(self, message):
|
||||||
|
"""Return the uniq account associated with a name and user JID.
|
||||||
|
DB connection might already be opened."""
|
||||||
|
name = message.get_to().node
|
||||||
|
bare_from_jid = unicode(message.get_from().bare())
|
||||||
|
accounts = Account.select(\
|
||||||
|
AND(Account.q.name == name, \
|
||||||
|
Account.q.user_jid == bare_from_jid))
|
||||||
|
if accounts.count() != 1:
|
||||||
|
print >>sys.stderr, "Account " + name + " for user " + bare_from_jid + " must be uniq"
|
||||||
|
_account = accounts[0]
|
||||||
|
if hasattr(_account, 'password') \
|
||||||
|
and hasattr(_account, 'waiting_password_reply') \
|
||||||
|
and (getattr(_account, 'waiting_password_reply') == True) \
|
||||||
|
and self.password_regexp.search(message.get_subject()) \
|
||||||
|
is not None:
|
||||||
|
return accounts
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
def handle(self, message, lang, accounts):
|
||||||
|
"""Receive password for given account"""
|
||||||
|
_account = accounts[0]
|
||||||
|
lang_class = lang.get_lang_class_from_node(message.get_node())
|
||||||
|
_account.password = message.get_body()
|
||||||
|
_account.waiting_password_reply = False
|
||||||
|
return [Message(from_jid = _account.jid, \
|
||||||
|
to_jid = message.get_from(), \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = lang_class.password_saved_for_session, \
|
||||||
|
body = lang_class.password_saved_for_session)]
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ from pyxmpp.presence import Presence
|
|||||||
from pyxmpp.message import Message
|
from pyxmpp.message import Message
|
||||||
from pyxmpp.jabber.dataforms import Form, Field, Option
|
from pyxmpp.jabber.dataforms import Form, Field, Option
|
||||||
|
|
||||||
from jcl.jabber.component import JCLComponent
|
from jcl.jabber.component import JCLComponent, MessageHandler, PasswordMessageHandler
|
||||||
from jcl.model import account
|
from jcl.model import account
|
||||||
from jcl.model.account import Account
|
from jcl.model.account import Account
|
||||||
from jcl.lang import Lang
|
from jcl.lang import Lang
|
||||||
@@ -1983,8 +1983,155 @@ class JCLComponent_TestCase(unittest.TestCase):
|
|||||||
self.comp.send_stanzas(None)
|
self.comp.send_stanzas(None)
|
||||||
self.assertEquals(len(self.comp.stream.sent), 0)
|
self.assertEquals(len(self.comp.stream.sent), 0)
|
||||||
|
|
||||||
|
class MessageHandler_TestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.handler = MessageHandler()
|
||||||
|
if os.path.exists(DB_PATH):
|
||||||
|
os.unlink(DB_PATH)
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
Account.createTable(ifNotExists = True)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
Account.dropTable(ifExists = True)
|
||||||
|
del TheURIOpener.cachedURIs['sqlite://' + DB_URL]
|
||||||
|
account.hub.threadConnection.close()
|
||||||
|
del account.hub.threadConnection
|
||||||
|
if os.path.exists(DB_PATH):
|
||||||
|
os.unlink(DB_PATH)
|
||||||
|
|
||||||
|
def test_filter(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = Account(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account12 = Account(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
accounts = self.handler.filter(None)
|
||||||
|
self.assertEquals(accounts.count(), 2)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def test_handle(self):
|
||||||
|
self.assertEquals(self.handler.handle(None, None, None), [])
|
||||||
|
|
||||||
|
class PasswordMessageHandler_TestCase(unittest.TestCase):
|
||||||
|
def setUp(self):
|
||||||
|
self.handler = PasswordMessageHandler()
|
||||||
|
if os.path.exists(DB_PATH):
|
||||||
|
os.unlink(DB_PATH)
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
Account.createTable(ifNotExists = True)
|
||||||
|
ExampleAccount.createTable(ifNotExists = True)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
ExampleAccount.dropTable(ifExists = True)
|
||||||
|
Account.dropTable(ifExists = True)
|
||||||
|
del TheURIOpener.cachedURIs['sqlite://' + DB_URL]
|
||||||
|
account.hub.threadConnection.close()
|
||||||
|
del account.hub.threadConnection
|
||||||
|
if os.path.exists(DB_PATH):
|
||||||
|
os.unlink(DB_PATH)
|
||||||
|
|
||||||
|
def test_filter_waiting_password(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account11.waiting_password_reply = True
|
||||||
|
account12 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
message = Message(from_jid = "user1@test.com", \
|
||||||
|
to_jid = "account11@jcl.test.com", \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = "[PASSWORD]", \
|
||||||
|
body = "secret")
|
||||||
|
accounts = self.handler.filter(message)
|
||||||
|
self.assertEquals(accounts.count(), 1)
|
||||||
|
self.assertEquals(accounts[0].name, "account11")
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def test_filter_not_waiting_password(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account11.waiting_password_reply = False
|
||||||
|
account12 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
message = Message(from_jid = "user1@test.com", \
|
||||||
|
to_jid = "account11@jcl.test.com", \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = "[PASSWORD]", \
|
||||||
|
body = "secret")
|
||||||
|
accounts = self.handler.filter(message)
|
||||||
|
self.assertEquals(accounts, None)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def test_filter_not_good_message(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account11.waiting_password_reply = True
|
||||||
|
account12 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
message = Message(from_jid = "user1@test.com", \
|
||||||
|
to_jid = "account11@jcl.test.com", \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = "[NOT GOOD MESSAGE]", \
|
||||||
|
body = "secret")
|
||||||
|
accounts = self.handler.filter(message)
|
||||||
|
self.assertEquals(accounts, None)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def test_filter_not_password_account(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = Account(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account12 = Account(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
message = Message(from_jid = "user1@test.com", \
|
||||||
|
to_jid = "account11@jcl.test.com", \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = "[PASSWORD]", \
|
||||||
|
body = "secret")
|
||||||
|
accounts = self.handler.filter(message)
|
||||||
|
self.assertEquals(accounts, None)
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
|
def test_handle(self):
|
||||||
|
account.hub.threadConnection = connectionForURI('sqlite://' + DB_URL)
|
||||||
|
account11 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account11", \
|
||||||
|
jid = "account11@jcl.test.com")
|
||||||
|
account12 = ExampleAccount(user_jid = "user1@test.com", \
|
||||||
|
name = "account12", \
|
||||||
|
jid = "account12@jcl.test.com")
|
||||||
|
message = Message(from_jid = "user1@test.com", \
|
||||||
|
to_jid = "account11@jcl.test.com", \
|
||||||
|
stanza_type = "normal", \
|
||||||
|
subject = "[PASSWORD]", \
|
||||||
|
body = "secret")
|
||||||
|
messages = self.handler.handle(message, Lang(), [account11])
|
||||||
|
self.assertEquals(len(messages), 1)
|
||||||
|
self.assertEquals(account11.password, "secret")
|
||||||
|
del account.hub.threadConnection
|
||||||
|
|
||||||
def suite():
|
def suite():
|
||||||
return unittest.makeSuite(JCLComponent_TestCase, 'test')
|
suite = unittest.TestSuite()
|
||||||
|
suite.addTest(unittest.makeSuite(JCLComponent_TestCase, 'test'))
|
||||||
|
suite.addTest(unittest.makeSuite(MessageHandler_TestCase, 'test'))
|
||||||
|
suite.addTest(unittest.makeSuite(PasswordMessageHandler_TestCase, 'test'))
|
||||||
|
return suite
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main(defaultTest='suite')
|
unittest.main(defaultTest='suite')
|
||||||
|
|||||||
Reference in New Issue
Block a user