replace send_stanzas by returned value in handler. Pyxmpp will take care to send these stanzas

This commit is contained in:
David Rousselie
2010-10-21 09:05:15 +02:00
parent d16396c4e4
commit 5f5a0cb7fa
10 changed files with 248 additions and 238 deletions

View File

@@ -40,6 +40,7 @@ from jcl.model.account import Account, User
COMMAND_NS = "http://jabber.org/protocol/commands" COMMAND_NS = "http://jabber.org/protocol/commands"
ACTION_COMPLETE = "complete" ACTION_COMPLETE = "complete"
ACTION_EXECUTE = "execute"
ACTION_NEXT = "next" ACTION_NEXT = "next"
ACTION_PREVIOUS = "prev" ACTION_PREVIOUS = "prev"
ACTION_CANCEL = "cancel" ACTION_CANCEL = "cancel"
@@ -157,6 +158,9 @@ class CommandManager(object):
return [info_query.make_error_response(\ return [info_query.make_error_response(\
"feature-not-implemented")] "feature-not-implemented")]
def apply_complete_command(self, info_query, short_command_name):
return self.apply_execute_command(info_query, short_command_name)
def apply_execute_command(self, info_query, short_command_name): def apply_execute_command(self, info_query, short_command_name):
return self.execute_multi_step_command(\ return self.execute_multi_step_command(\
info_query, info_query,

View File

@@ -898,8 +898,8 @@ class JCLComponent(Component, object):
Handle IQ-get "jabber:iq:last" requests. Handle IQ-get "jabber:iq:last" requests.
""" """
self.__logger.debug("IQ:Last request") self.__logger.debug("IQ:Last request")
self.apply_registered_behavior(self.iqlast_handlers, info_query) return self.apply_registered_behavior(self.iqlast_handlers, info_query,
return 1 send_result=False)
def handle_get_gateway(self, info_query): def handle_get_gateway(self, info_query):
"""Handle IQ-get "jabber:iq:gateway" requests. """Handle IQ-get "jabber:iq:gateway" requests.
@@ -911,8 +911,7 @@ class JCLComponent(Component, object):
query = info_query.new_query("jabber:iq:gateway") query = info_query.new_query("jabber:iq:gateway")
query.newTextChild(query.ns(), "desc", lang_class.get_gateway_desc) query.newTextChild(query.ns(), "desc", lang_class.get_gateway_desc)
query.newTextChild(query.ns(), "prompt", lang_class.get_gateway_prompt) query.newTextChild(query.ns(), "prompt", lang_class.get_gateway_prompt)
self.send_stanzas([info_query]) return [info_query]
return 1
def handle_set_gateway(self, info_query): def handle_set_gateway(self, info_query):
""" """
@@ -929,8 +928,7 @@ class JCLComponent(Component, object):
query.newTextChild(query.ns(), "jid", jid) query.newTextChild(query.ns(), "jid", jid)
# XEP-0100 - section 6: should be <jid> but PSI only work with <prompt> # XEP-0100 - section 6: should be <jid> but PSI only work with <prompt>
query.newTextChild(query.ns(), "prompt", jid) query.newTextChild(query.ns(), "prompt", jid)
self.send_stanzas([info_query]) return [info_query]
return 1
def disco_get_info(self, node, info_query): def disco_get_info(self, node, info_query):
""" """
@@ -974,15 +972,14 @@ class JCLComponent(Component, object):
query = info_query.new_query("jabber:iq:version") query = info_query.new_query("jabber:iq:version")
query.newTextChild(query.ns(), "name", self.name) query.newTextChild(query.ns(), "name", self.name)
query.newTextChild(query.ns(), "version", self.version) query.newTextChild(query.ns(), "version", self.version)
self.send_stanzas([info_query]) return [info_query]
return 1
def handle_get_register(self, info_query): def handle_get_register(self, info_query):
"""Send back register form to user """Send back register form to user
see node structure in disco_get_items() see node structure in disco_get_items()
""" """
self.__logger.debug("GET_REGISTER") self.__logger.debug("GET_REGISTER")
self.apply_behavior(\ return self.apply_behavior(\
info_query, info_query,
lambda name, from_jid, account_type, lang_class: \ lambda name, from_jid, account_type, lang_class: \
self.account_manager.account_get_register(info_query, self.account_manager.account_get_register(info_query,
@@ -997,25 +994,21 @@ class JCLComponent(Component, object):
lambda name, from_jid, account_type, lang_class: \ lambda name, from_jid, account_type, lang_class: \
self.account_manager.root_get_register(info_query, self.account_manager.root_get_register(info_query,
lang_class), lang_class),
send_result=True) send_result=False)
def handle_set_register(self, info_query): def handle_set_register(self, info_query):
"""Handle user registration response """Handle user registration response
""" """
self.__logger.debug("SET_REGISTER") self.__logger.debug("SET_REGISTER")
lang_class = \
self.lang.get_lang_class_from_node(info_query.get_node())
from_jid = info_query.get_from() from_jid = info_query.get_from()
remove = info_query.xpath_eval("r:query/r:remove", remove = info_query.xpath_eval("r:query/r:remove",
{"r" : "jabber:iq:register"}) {"r": "jabber:iq:register"})
if remove: if remove:
result = self.account_manager.remove_all_accounts(from_jid) return self.account_manager.remove_all_accounts(from_jid)
self.send_stanzas(result)
return 1
x_node = info_query.xpath_eval("jir:query/jxd:x", x_node = info_query.xpath_eval("jir:query/jxd:x",
{"jir" : "jabber:iq:register", {"jir": "jabber:iq:register",
"jxd" : "jabber:x:data"})[0] "jxd": "jabber:x:data"})[0]
x_data = Form(x_node) x_data = Form(x_node)
return self.apply_registered_behavior(\ return self.apply_registered_behavior(\
self.set_register_handlers, self.set_register_handlers,
@@ -1023,65 +1016,61 @@ class JCLComponent(Component, object):
apply_filter_func=lambda filter_func, stanza, lang_class: \ apply_filter_func=lambda filter_func, stanza, lang_class: \
filter_func(stanza, lang_class, x_data), filter_func(stanza, lang_class, x_data),
apply_handle_func=lambda handle_func, stanza, lang_class, data, result: \ apply_handle_func=lambda handle_func, stanza, lang_class, data, result: \
handle_func(stanza, lang_class, data, x_data)) handle_func(stanza, lang_class, data, x_data),
send_result=False)
def handle_presence_available(self, stanza): def handle_presence_available(self, stanza):
"""Handle presence availability """Handle presence availability
if presence sent to the component ('if not name'), presence is sent to if presence sent to the component ('if not name'), presence is sent to
all accounts for current user. Otherwise, send presence from current account. all accounts for current user. Otherwise, send presence from current
account.
""" """
result = self.apply_registered_behavior(self.presence_available_handlers, self.__logger.debug("PRESENCE_AVAILABLE")
stanza) return self.apply_registered_behavior(self.presence_available_handlers,
return result stanza, send_result=False)
def handle_presence_unavailable(self, stanza): def handle_presence_unavailable(self, stanza):
"""Handle presence unavailability """Handle presence unavailability
""" """
self.__logger.debug("PRESENCE_UNAVAILABLE") self.__logger.debug("PRESENCE_UNAVAILABLE")
result = self.apply_registered_behavior(self.presence_unavailable_handlers, return self.apply_registered_behavior(self.presence_unavailable_handlers,
stanza) stanza, send_result=False)
return result
def handle_presence_subscribe(self, stanza): def handle_presence_subscribe(self, stanza):
"""Handle subscribe presence from user """Handle subscribe presence from user
""" """
self.__logger.debug("PRESENCE_SUBSCRIBE") self.__logger.debug("PRESENCE_SUBSCRIBE")
result = self.apply_registered_behavior(self.presence_subscribe_handlers, return self.apply_registered_behavior(self.presence_subscribe_handlers,
stanza) stanza, send_result=False)
return result
def handle_presence_subscribed(self, stanza): def handle_presence_subscribed(self, stanza):
"""Handle subscribed presence from user """Handle subscribed presence from user
""" """
self.__logger.debug("PRESENCE_SUBSCRIBED") self.__logger.debug("PRESENCE_SUBSCRIBED")
return 1 return []
def handle_presence_unsubscribe(self, stanza): def handle_presence_unsubscribe(self, stanza):
"""Handle unsubscribe presence from user """Handle unsubscribe presence from user
""" """
self.__logger.debug("PRESENCE_UNSUBSCRIBE") self.__logger.debug("PRESENCE_UNSUBSCRIBE")
result = self.apply_registered_behavior(self.presence_unsubscribe_handlers, return self.apply_registered_behavior(self.presence_unsubscribe_handlers,
stanza) stanza, send_result=False)
return result
def handle_presence_unsubscribed(self, stanza): def handle_presence_unsubscribed(self, stanza):
"""Handle unsubscribed presence from user """Handle unsubscribed presence from user
""" """
self.__logger.debug("PRESENCE_UNSUBSCRIBED") self.__logger.debug("PRESENCE_UNSUBSCRIBED")
presence = Presence(from_jid=stanza.get_to(), return [Presence(from_jid=stanza.get_to(),
to_jid=stanza.get_from(), to_jid=stanza.get_from(),
stanza_type="unavailable") stanza_type="unavailable")]
self.send_stanzas([presence])
return 1
def handle_message(self, message): def handle_message(self, message):
"""Handle new message """Handle new message
Handle password response message Handle password response message
""" """
self.__logger.debug("MESSAGE: " + str(message.get_body())) self.__logger.debug("MESSAGE: " + str(message.get_body()))
self.apply_registered_behavior(self.msg_handlers, message) return self.apply_registered_behavior(self.msg_handlers, message,
return 1 send_result=False)
def handle_command(self, info_query): def handle_command(self, info_query):
""" """
@@ -1096,23 +1085,22 @@ class JCLComponent(Component, object):
if action is None: if action is None:
action = "execute" action = "execute"
try: try:
result = command.command_manager.apply_command_action(info_query, return command.command_manager.apply_command_action(info_query,
command_node, command_node,
action) action)
self.send_stanzas(result)
except: except:
self.__logger.error("Error in command " + str(command_node) + self.__logger.error("Error in command " + str(command_node) +
" with " + str(info_query) + ":", " with " + str(info_query) + ":",
exc_info=True) exc_info=True)
return 1 return []
def handle_vcard(self, info_query): def handle_vcard(self, info_query):
""" """
Handle VCard request Handle VCard request
""" """
self.__logger.debug("VCard request") self.__logger.debug("VCard request")
self.apply_registered_behavior(self.vcard_handlers, info_query) return self.apply_registered_behavior(self.vcard_handlers, info_query,
return 1 send_result=False)
########################################################################### ###########################################################################
# Utils # Utils

View File

@@ -27,6 +27,7 @@ import traceback
import re import re
import pyxmpp.error as error import pyxmpp.error as error
import pyxmpp.jid
from jcl.error import FieldError, MandatoryFieldError, NotWellFormedFieldError from jcl.error import FieldError, MandatoryFieldError, NotWellFormedFieldError
import jcl.jabber as jabber import jcl.jabber as jabber
@@ -68,10 +69,10 @@ class SetRegisterHandler(object):
return self.handle_error(\ return self.handle_error(\
MandatoryFieldError("name"), MandatoryFieldError("name"),
info_query, lang_class) info_query, lang_class)
if not self.field_name_regexp.match(form["name"].value): if pyxmpp.jid.node_invalid_re.search(form["name"].value):
return self.handle_error(\ return self.handle_error(\
NotWellFormedFieldError("name", NotWellFormedFieldError("name",
lang_class.arobase_in_name_forbidden), lang_class.forbidden_char_in_name),
info_query, lang_class) info_query, lang_class)
return None return None

View File

@@ -248,6 +248,20 @@ class CommandManager_TestCase(unittest.TestCase):
"execute") "execute")
self.assertEquals(result, []) self.assertEquals(result, [])
def test_complete_admin_command_action_as_admin(self):
self.command_manager.commands["command1"] = (True,
command.root_node_re)
self.command_manager.apply_execute_command = \
lambda iq, command_name: []
self.command_manager.component = MockComponent()
info_query = Iq(stanza_type="set",
from_jid="admin@test.com",
to_jid="jcl.test.com")
result = self.command_manager.apply_command_action(info_query,
"command1",
"complete")
self.assertEquals(result, [])
def test_apply_admin_command_action_as_admin_fulljid(self): def test_apply_admin_command_action_as_admin_fulljid(self):
self.command_manager.commands["command1"] = (True, self.command_manager.commands["command1"] = (True,
command.root_node_re) command.root_node_re)

File diff suppressed because it is too large Load Diff

View File

@@ -71,7 +71,7 @@ class SetRegisterHandler_TestCase(JCLTestCase):
error = result[0].get_error() error = result[0].get_error()
self.assertEquals(error.get_condition().name, "not-acceptable") self.assertEquals(error.get_condition().name, "not-acceptable")
self.assertEquals(error.get_text(), Lang.en.field_error \ self.assertEquals(error.get_text(), Lang.en.field_error \
% ("name", Lang.en.arobase_in_name_forbidden)) % ("name", Lang.en.forbidden_char_in_name))
def test_handle_invalid_name_with_whitespace(self): def test_handle_invalid_name_with_whitespace(self):
"""Test with invalid supplied name""" """Test with invalid supplied name"""
@@ -88,7 +88,7 @@ class SetRegisterHandler_TestCase(JCLTestCase):
error = result[0].get_error() error = result[0].get_error()
self.assertEquals(error.get_condition().name, "not-acceptable") self.assertEquals(error.get_condition().name, "not-acceptable")
self.assertEquals(error.get_text(), Lang.en.field_error \ self.assertEquals(error.get_text(), Lang.en.field_error \
% ("name", Lang.en.arobase_in_name_forbidden)) % ("name", Lang.en.forbidden_char_in_name))
def test_handle_invalid_empty_name(self): def test_handle_invalid_empty_name(self):
"""Test with empty supplied name""" """Test with empty supplied name"""

View File

@@ -92,7 +92,8 @@ class Lang:
field_error = u"Error with '%s' field: %s" field_error = u"Error with '%s' field: %s"
mandatory_field = u"required field" mandatory_field = u"required field"
not_well_formed_field = u"not well formed field" not_well_formed_field = u"not well formed field"
arobase_in_name_forbidden = u"'@' is not allowed in account's name" forbidden_char_in_name = u"Account's name contains an invalid character"
not_a_number = u"field must be a number"
field_chat_action = u"Action when state is 'Free For Chat'" field_chat_action = u"Action when state is 'Free For Chat'"
field_online_action = u"Action when state is 'Online'" field_online_action = u"Action when state is 'Online'"
@@ -270,7 +271,8 @@ class Lang:
field_error = u"Erreur dans le champs '%s': %s" field_error = u"Erreur dans le champs '%s': %s"
mandatory_field = u"%s est requis" mandatory_field = u"%s est requis"
not_well_formed_field = u"Le champs %s n'est pas acceptable" not_well_formed_field = u"Le champs %s n'est pas acceptable"
arobase_in_name_forbidden = u"Le nom du compte ne peux contenir le charactère '@'" forbidden_char_in_name = u"Le nom du compte contient un charactère invalide"
not_a_number = u"Le champs doit être un nombre"
field_chat_action = u"Action lorsque l'état est 'Free For Chat'" field_chat_action = u"Action lorsque l'état est 'Free For Chat'"
field_online_action = u"Action lorsque l'état est 'Online'" field_online_action = u"Action lorsque l'état est 'Online'"

View File

@@ -28,6 +28,7 @@ __revision__ = "$Id: account.py,v 1.3 2005/09/18 20:24:07 dax Exp $"
import datetime import datetime
import re import re
import exceptions
from sqlobject.inheritance import InheritableSQLObject from sqlobject.inheritance import InheritableSQLObject
from sqlobject.col import StringCol, IntCol, BoolCol, ForeignKey, DateTimeCol from sqlobject.col import StringCol, IntCol, BoolCol, ForeignKey, DateTimeCol
@@ -64,7 +65,10 @@ def int_post_func(field_value, default_func, bare_from_jid):
"""Return an integer from integer field value""" """Return an integer from integer field value"""
if field_value is None or str(field_value) == "": if field_value is None or str(field_value) == "":
return int(default_func(bare_from_jid)) return int(default_func(bare_from_jid))
try:
return int(field_value) return int(field_value)
except exceptions.ValueError:
raise FieldError("TODO", message_property="not_a_number")
def mandatory_field(field_name, field_value): def mandatory_field(field_name, field_value):
"""Used as default function for field that must be specified """Used as default function for field that must be specified

View File

@@ -182,11 +182,16 @@ class AccountModule_TestCase(JCLTestCase):
"user1@jcl.test.com") "user1@jcl.test.com")
self.assertEquals(result, 42) self.assertEquals(result, 42)
def test_int_post_func_default_value(self): def test_int_post_func_default_value2(self):
result = account.int_post_func(None, lambda bare_from_jid: 42, \ result = account.int_post_func(None, lambda bare_from_jid: 42, \
"user1@jcl.test.com") "user1@jcl.test.com")
self.assertEquals(result, 42) self.assertEquals(result, 42)
def test_int_post_func_invalid_value(self):
self.assertRaises(FieldError,
account.int_post_func,
"notanint", None, "user1@jcl.test.com")
def test_mandatory_field_empty(self): def test_mandatory_field_empty(self):
self.assertRaises(FieldError, self.assertRaises(FieldError,
account.mandatory_field, account.mandatory_field,

View File

@@ -94,7 +94,8 @@ class Language_TestCase(unittest.TestCase):
self.assertNotEquals(self.lang_class.field_error % ("", ""), None) self.assertNotEquals(self.lang_class.field_error % ("", ""), None)
self.assertNotEquals(self.lang_class.mandatory_field, None) self.assertNotEquals(self.lang_class.mandatory_field, None)
self.assertNotEquals(self.lang_class.not_well_formed_field, None) self.assertNotEquals(self.lang_class.not_well_formed_field, None)
self.assertNotEquals(self.lang_class.arobase_in_name_forbidden, None) self.assertNotEquals(self.lang_class.forbidden_char_in_name, None)
self.assertNotEquals(self.lang_class.not_a_number, None)
self.assertNotEquals(self.lang_class.field_chat_action, None) self.assertNotEquals(self.lang_class.field_chat_action, None)
self.assertNotEquals(self.lang_class.field_online_action, None) self.assertNotEquals(self.lang_class.field_online_action, None)