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.send_stanzas(self.account_manager.probe_all_accounts_presence())
|
||||
|
||||
def password_msg_handler_filter(message):
|
||||
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)]
|
||||
self.msg_handlers += [PasswordMessageHandler()]
|
||||
|
||||
def signal_handler(self, signum, frame):
|
||||
"""Stop method handler
|
||||
@@ -472,12 +444,14 @@ class JCLComponent(Component, object):
|
||||
Handle password response message
|
||||
"""
|
||||
self.__logger.debug("MESSAGE: " + message.get_body())
|
||||
result = []
|
||||
self.db_connect()
|
||||
for (msg_handler, filter_func) in self.msg_handlers:
|
||||
accounts = filter_func(message)
|
||||
for msg_handler in self.msg_handlers:
|
||||
accounts = msg_handler.filter(message)
|
||||
if accounts is not None:
|
||||
msg_handler(message, accounts)
|
||||
result += msg_handler.handle(message, self.lang, accounts)
|
||||
self.db_disconnect()
|
||||
self.send_stanzas(result)
|
||||
return 1
|
||||
|
||||
###########################################################################
|
||||
@@ -1118,3 +1092,57 @@ class AccountManager(object):
|
||||
body = _account.default_lang_class.check_error_body \
|
||||
% (exception)))
|
||||
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.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.account import Account
|
||||
from jcl.lang import Lang
|
||||
@@ -1983,8 +1983,155 @@ class JCLComponent_TestCase(unittest.TestCase):
|
||||
self.comp.send_stanzas(None)
|
||||
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():
|
||||
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__':
|
||||
unittest.main(defaultTest='suite')
|
||||
|
||||
Reference in New Issue
Block a user