diff --git a/src/jcl/jabber/command.py b/src/jcl/jabber/command.py index 74eeaa2..a1ad4e4 100644 --- a/src/jcl/jabber/command.py +++ b/src/jcl/jabber/command.py @@ -579,8 +579,26 @@ class JCLCommandManager(CommandManager): command_node.setProp("status", STATUS_COMPLETED) return (result_form, []) - def execute_get_user_lastlogin(self, info_query): - return [] + execute_get_user_lastlogin_1 = select_user_jid_step_1 + execute_get_user_lastlogin_2 = select_account_step_2 + + def execute_get_user_lastlogin_3(self, info_query, session_context, + command_node, lang_class): + self.__logger.debug("Executing command 'get-user-roster' step 2") + result_form = Form(xmlnode_or_type="result") + result_form.add_field(field_type="hidden", + name="FORM_TYPE", + value="http://jabber.org/protocol/admin") + user_jid = session_context["user_jid"][0] + _account = account.get_account(user_jid, + session_context["account_name"][0]) + result_form.fields.append(FieldNoType(name="user_jid", + value=user_jid)) + result_form.fields.append(FieldNoType(name="lastlogin", + value=_account.lastlogin)) + result_form.as_xml(command_node) + command_node.setProp("status", STATUS_COMPLETED) + return (result_form, []) def execute_user_stats(self, info_query): return [] diff --git a/src/jcl/jabber/tests/command.py b/src/jcl/jabber/tests/command.py index 05b46ec..31bef5c 100644 --- a/src/jcl/jabber/tests/command.py +++ b/src/jcl/jabber/tests/command.py @@ -1405,14 +1405,106 @@ class JCLCommandManager_TestCase(JCLTestCase): self.assertEquals(items[2].prop("jid"), "test121%test.com@test.com") self.assertEquals(items[2].prop("name"), "test121@test.com") -# def test_execute_get_user_last_login(self): -# #TODO : implement command -# info_query = Iq(stanza_type="set", -# from_jid="user1@test.com", -# to_jid="jcl.test.com") -# result = self.command_manager.execute_add_user(info_query) -# self.assertNotEquals(result, None) -# self.assertEquals(len(result), 1) + def test_execute_get_user_lastlogin(self): + self.comp.account_manager.account_classes = (ExampleAccount, + Example2Account) + model.db_connect() + account11 = ExampleAccount(user_jid="test1@test.com", + name="account11", + jid="account11@jcl.test.com") + account11.status = account.ONLINE + account12 = Example2Account(user_jid="test1@test.com", + name="account12", + jid="account12@jcl.test.com") + account21 = ExampleAccount(user_jid="test2@test.com", + name="account21", + jid="account21@jcl.test.com") + account22 = ExampleAccount(user_jid="test2@test.com", + name="account11", + jid="account11@jcl.test.com") + model.db_disconnect() + info_query = Iq(stanza_type="set", + from_jid="user1@test.com", + to_jid="jcl.test.com") + command_node = info_query.set_new_content(command.COMMAND_NS, "command") + command_node.setProp("node", "http://jabber.org/protocol/admin#get-user-lastlogin") + result = self.command_manager.apply_command_action(info_query, + "http://jabber.org/protocol/admin#get-user-lastlogin", + "execute") + self.assertNotEquals(result, None) + self.assertEquals(len(result), 1) + xml_command = result[0].xpath_eval("c:command", + {"c": "http://jabber.org/protocol/commands"})[0] + self.assertEquals(xml_command.prop("status"), "executing") + self.assertNotEquals(xml_command.prop("sessionid"), None) + self.__check_actions(result[0], ["next"]) + + # Second step + info_query = Iq(stanza_type="set", + from_jid="user1@test.com", + to_jid="jcl.test.com") + command_node = info_query.set_new_content(command.COMMAND_NS, "command") + command_node.setProp("node", "http://jabber.org/protocol/admin#get-user-lastlogin") + session_id = xml_command.prop("sessionid") + command_node.setProp("sessionid", session_id) + command_node.setProp("action", "next") + submit_form = Form(xmlnode_or_type="submit") + submit_form.add_field(field_type="jid-single", + name="user_jid", + value="test1@test.com") + submit_form.as_xml(command_node) + result = self.command_manager.apply_command_action(info_query, + "http://jabber.org/protocol/admin#get-user-lastlogin", + "execute") + self.assertNotEquals(result, None) + self.assertEquals(len(result), 1) + xml_command = result[0].xpath_eval("c:command", + {"c": "http://jabber.org/protocol/commands"})[0] + self.assertEquals(xml_command.prop("status"), "executing") + self.assertEquals(xml_command.prop("sessionid"), session_id) + self.__check_actions(result[0], ["prev", "complete"], 1) + context_session = self.command_manager.sessions[session_id][1] + self.assertEquals(context_session["user_jid"], + ["test1@test.com"]) + + # Third step + info_query = Iq(stanza_type="set", + from_jid="user1@test.com", + to_jid="jcl.test.com") + command_node = info_query.set_new_content(command.COMMAND_NS, "command") + command_node.setProp("node", "http://jabber.org/protocol/admin#get-user-lastlogin") + command_node.setProp("sessionid", session_id) + command_node.setProp("action", "complete") + submit_form = Form(xmlnode_or_type="submit") + submit_form.add_field(field_type="list-single", + name="account_name", + value="account11") + submit_form.as_xml(command_node) + result = self.command_manager.apply_command_action(info_query, + "http://jabber.org/protocol/admin#get-user-lastlogin", + "execute") + xml_command = result[0].xpath_eval("c:command", + {"c": "http://jabber.org/protocol/commands"})[0] + self.assertEquals(xml_command.prop("status"), "completed") + self.assertEquals(xml_command.prop("sessionid"), session_id) + self.__check_actions(result[0]) + self.assertEquals(context_session["account_name"], + ["account11"]) + fields = result[0].xpath_eval("c:command/data:x/data:field", + {"c": "http://jabber.org/protocol/commands", + "data": "jabber:x:data"}) + self.assertEquals(len(fields), 3) + self.assertEquals(fields[0].prop("var"), "FORM_TYPE") + self.assertEquals(fields[0].prop("type"), "hidden") + self.assertEquals(fields[0].children.name, "value") + self.assertEquals(fields[0].children.content, + "http://jabber.org/protocol/admin") + self.assertEquals(fields[1].prop("var"), "user_jid") + self.assertEquals(fields[1].children.name, "value") + self.assertEquals(fields[1].children.content, "test1@test.com") + self.assertEquals(fields[2].prop("var"), "lastlogin") + self.assertEquals(fields[2].children.name, "value") + self.assertEquals(fields[2].children.content, account11.lastlogin.isoformat(" ")) # def test_execute_user_stats(self): # #TODO : implement command diff --git a/src/jcl/model/account.py b/src/jcl/model/account.py index d82950c..aaf1bad 100644 --- a/src/jcl/model/account.py +++ b/src/jcl/model/account.py @@ -26,8 +26,10 @@ __revision__ = "$Id: account.py,v 1.3 2005/09/18 20:24:07 dax Exp $" +import datetime + from sqlobject.inheritance import InheritableSQLObject -from sqlobject.col import StringCol, IntCol, BoolCol, ForeignKey +from sqlobject.col import StringCol, IntCol, BoolCol, ForeignKey, DateTimeCol from sqlobject.joins import MultipleJoin from sqlobject.sqlbuilder import AND @@ -68,7 +70,8 @@ class Account(InheritableSQLObject): in_error = BoolCol(default=False) legacy_jids = MultipleJoin('LegacyJID') enabled = BoolCol(default=True) - + lastlogin = DateTimeCol(default=datetime.datetime.today()) + ## Use these attributs to support volatile password ## login = StringCol(default = "") ## password = StringCol(default = None) @@ -103,9 +106,10 @@ class Account(InheritableSQLObject): if not getattr(self, 'store_password'): setattr(self, 'password', None) else: - # TODO seems to be a bug : first_check = True only - # if previous status was OFFLINE - self.first_check = True + if self._status == OFFLINE: + # TODO : first_check + self.first_check = True + self.lastlogin = datetime.datetime.today() self._status = status status = property(get_status, set_status)