remove user when removing his last account
darcs-hash:20070913205318-86b55-30685cc7b0c84bb50d90a7c5167fdfb87c11683f.gz
This commit is contained in:
@@ -516,7 +516,7 @@ class JCLCommandManager(CommandManager):
|
|||||||
result = []
|
result = []
|
||||||
for account_name in session_context["account_names"]:
|
for account_name in session_context["account_names"]:
|
||||||
name, user_jid = self.get_name_and_jid(account_name)
|
name, user_jid = self.get_name_and_jid(account_name)
|
||||||
result += self.account_manager.remove_account_from_name(user_jid,
|
result += self.account_manager.remove_account_from_name(JID(user_jid),
|
||||||
name)
|
name)
|
||||||
command_node.setProp("status", STATUS_COMPLETED)
|
command_node.setProp("status", STATUS_COMPLETED)
|
||||||
return (None, result)
|
return (None, result)
|
||||||
@@ -944,10 +944,9 @@ class JCLCommandManager(CommandManager):
|
|||||||
motd = self.component.get_motd()
|
motd = self.component.get_motd()
|
||||||
if motd is not None:
|
if motd is not None:
|
||||||
for user in users:
|
for user in users:
|
||||||
for _account in user.accounts:
|
|
||||||
if _account.status == account.OFFLINE:
|
|
||||||
user.has_received_motd = False
|
user.has_received_motd = False
|
||||||
else:
|
for _account in user.accounts:
|
||||||
|
if _account.status != account.OFFLINE:
|
||||||
user.has_received_motd = True
|
user.has_received_motd = True
|
||||||
if user.has_received_motd:
|
if user.has_received_motd:
|
||||||
result.append(Message(from_jid=self.component.jid,
|
result.append(Message(from_jid=self.component.jid,
|
||||||
|
|||||||
@@ -57,7 +57,8 @@ from jcl.jabber.command import CommandDiscoGetItemsHandler, \
|
|||||||
from jcl.jabber.presence import AccountPresenceAvailableHandler, \
|
from jcl.jabber.presence import AccountPresenceAvailableHandler, \
|
||||||
RootPresenceAvailableHandler, AccountPresenceUnavailableHandler, \
|
RootPresenceAvailableHandler, AccountPresenceUnavailableHandler, \
|
||||||
RootPresenceUnavailableHandler, AccountPresenceSubscribeHandler, \
|
RootPresenceUnavailableHandler, AccountPresenceSubscribeHandler, \
|
||||||
RootPresenceSubscribeHandler, AccountPresenceUnsubscribeHandler
|
RootPresenceSubscribeHandler, AccountPresenceUnsubscribeHandler, \
|
||||||
|
RootPresenceUnsubscribeHandler
|
||||||
from jcl.jabber.register import RootSetRegisterHandler, \
|
from jcl.jabber.register import RootSetRegisterHandler, \
|
||||||
AccountSetRegisterHandler, AccountTypeSetRegisterHandler
|
AccountSetRegisterHandler, AccountTypeSetRegisterHandler
|
||||||
import jcl.model as model
|
import jcl.model as model
|
||||||
@@ -110,7 +111,8 @@ class JCLComponent(Component, object):
|
|||||||
self.msg_handlers = []
|
self.msg_handlers = []
|
||||||
self.presence_subscribe_handlers = [[AccountPresenceSubscribeHandler(self),
|
self.presence_subscribe_handlers = [[AccountPresenceSubscribeHandler(self),
|
||||||
RootPresenceSubscribeHandler(self)]]
|
RootPresenceSubscribeHandler(self)]]
|
||||||
self.presence_unsubscribe_handlers = [[AccountPresenceUnsubscribeHandler(self)]]
|
self.presence_unsubscribe_handlers = [[AccountPresenceUnsubscribeHandler(self),
|
||||||
|
RootPresenceUnsubscribeHandler(self)]]
|
||||||
self.presence_available_handlers = [[AccountPresenceAvailableHandler(self),
|
self.presence_available_handlers = [[AccountPresenceAvailableHandler(self),
|
||||||
RootPresenceAvailableHandler(self)]]
|
RootPresenceAvailableHandler(self)]]
|
||||||
self.presence_unavailable_handlers = [[AccountPresenceUnavailableHandler(self),
|
self.presence_unavailable_handlers = [[AccountPresenceUnavailableHandler(self),
|
||||||
@@ -448,7 +450,7 @@ class JCLComponent(Component, object):
|
|||||||
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(unicode(from_jid.bare()))
|
result = self.account_manager.remove_all_accounts(from_jid)
|
||||||
self.send_stanzas(result)
|
self.send_stanzas(result)
|
||||||
return 1
|
return 1
|
||||||
|
|
||||||
@@ -720,16 +722,9 @@ class AccountManager(object):
|
|||||||
model.db_connect()
|
model.db_connect()
|
||||||
result = []
|
result = []
|
||||||
for _account in account.get_accounts(user_jid):
|
for _account in account.get_accounts(user_jid):
|
||||||
self.__logger.debug("Deleting " + _account.name
|
result.extend(self.remove_account(_account, user_jid, False))
|
||||||
+ " for " + unicode(user_jid))
|
user = account.get_user(unicode(user_jid.bare()))
|
||||||
# get_jid
|
user.destroySelf()
|
||||||
result.append(Presence(from_jid=_account.jid,
|
|
||||||
to_jid=user_jid,
|
|
||||||
stanza_type="unsubscribe"))
|
|
||||||
result.append(Presence(from_jid=_account.jid,
|
|
||||||
to_jid=user_jid,
|
|
||||||
stanza_type="unsubscribed"))
|
|
||||||
_account.destroySelf()
|
|
||||||
result.append(Presence(from_jid=self.component.jid,
|
result.append(Presence(from_jid=self.component.jid,
|
||||||
to_jid=user_jid,
|
to_jid=user_jid,
|
||||||
stanza_type="unsubscribe"))
|
stanza_type="unsubscribe"))
|
||||||
@@ -746,7 +741,7 @@ class AccountManager(object):
|
|||||||
else:
|
else:
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def remove_account(self, _account, user_jid):
|
def remove_account(self, _account, user_jid, remove_user=True):
|
||||||
self.__logger.debug("Deleting account: " + str(_account))
|
self.__logger.debug("Deleting account: " + str(_account))
|
||||||
result = []
|
result = []
|
||||||
model.db_connect()
|
model.db_connect()
|
||||||
@@ -757,6 +752,12 @@ class AccountManager(object):
|
|||||||
to_jid=user_jid,
|
to_jid=user_jid,
|
||||||
stanza_type="unsubscribed"))
|
stanza_type="unsubscribed"))
|
||||||
_account.destroySelf()
|
_account.destroySelf()
|
||||||
|
if remove_user:
|
||||||
|
bare_user_jid = unicode(user_jid.bare())
|
||||||
|
accounts_count = account.get_accounts_count(bare_user_jid)
|
||||||
|
if accounts_count == 0:
|
||||||
|
user = account.get_user(bare_user_jid)
|
||||||
|
user.destroySelf()
|
||||||
model.db_disconnect()
|
model.db_disconnect()
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@@ -841,7 +842,10 @@ class AccountManager(object):
|
|||||||
bare_from_jid = unicode(from_jid.bare())
|
bare_from_jid = unicode(from_jid.bare())
|
||||||
first_account = (account.get_accounts_count(bare_from_jid) == 0)
|
first_account = (account.get_accounts_count(bare_from_jid) == 0)
|
||||||
model.db_connect()
|
model.db_connect()
|
||||||
_account = account_class(user=User(jid=unicode(bare_from_jid)),
|
user = account.get_user(bare_from_jid)
|
||||||
|
if user is None:
|
||||||
|
user = User(jid=bare_from_jid)
|
||||||
|
_account = account_class(user=user,
|
||||||
name=account_name,
|
name=account_name,
|
||||||
jid=self.get_account_jid(account_name))
|
jid=self.get_account_jid(account_name))
|
||||||
model.db_disconnect()
|
model.db_disconnect()
|
||||||
|
|||||||
@@ -164,3 +164,14 @@ class AccountPresenceUnsubscribeHandler(Handler):
|
|||||||
from_jid = stanza.get_from()
|
from_jid = stanza.get_from()
|
||||||
_account = data
|
_account = data
|
||||||
return self.component.account_manager.remove_account(_account, from_jid)
|
return self.component.account_manager.remove_account(_account, from_jid)
|
||||||
|
|
||||||
|
class RootPresenceUnsubscribeHandler(Handler):
|
||||||
|
""""""
|
||||||
|
|
||||||
|
filter = jabber.get_accounts_root_filter
|
||||||
|
|
||||||
|
def handle(self, stanza, lang_class, data):
|
||||||
|
"""Handle \"unsubscribe\" iq sent to account JID"""
|
||||||
|
from_jid = stanza.get_from()
|
||||||
|
_account = data
|
||||||
|
return self.component.account_manager.remove_all_accounts(from_jid)
|
||||||
|
|||||||
@@ -1352,15 +1352,15 @@ class JCLComponent_TestCase(JCLTestCase):
|
|||||||
self.comp.stream_class = MockStream
|
self.comp.stream_class = MockStream
|
||||||
self.comp.account_manager.account_classes = (ExampleAccount,)
|
self.comp.account_manager.account_classes = (ExampleAccount,)
|
||||||
x_data = Form("submit")
|
x_data = Form("submit")
|
||||||
x_data.add_field(name = "name", \
|
x_data.add_field(name="name",
|
||||||
value = "account1", \
|
value="account1",
|
||||||
field_type = "text-single")
|
field_type="text-single")
|
||||||
x_data.add_field(name = "login", \
|
x_data.add_field(name="login",
|
||||||
value = "mylogin", \
|
value="mylogin",
|
||||||
field_type = "text-single")
|
field_type="text-single")
|
||||||
iq_set = Iq(stanza_type = "set", \
|
iq_set = Iq(stanza_type="set",
|
||||||
from_jid = "user1@test.com", \
|
from_jid="user1@test.com",
|
||||||
to_jid = "jcl.test.com")
|
to_jid="jcl.test.com")
|
||||||
query = iq_set.new_query("jabber:iq:register")
|
query = iq_set.new_query("jabber:iq:register")
|
||||||
x_data.as_xml(query)
|
x_data.as_xml(query)
|
||||||
self.comp.handle_set_register(iq_set)
|
self.comp.handle_set_register(iq_set)
|
||||||
@@ -1378,6 +1378,67 @@ class JCLComponent_TestCase(JCLTestCase):
|
|||||||
self.assertEquals(_account.test_int, 44)
|
self.assertEquals(_account.test_int, 44)
|
||||||
model.db_disconnect()
|
model.db_disconnect()
|
||||||
|
|
||||||
|
def test_handle_set_register_user_already_exists(self):
|
||||||
|
self.comp.stream = MockStream()
|
||||||
|
self.comp.stream_class = MockStream
|
||||||
|
self.comp.account_manager.account_classes = (ExampleAccount,)
|
||||||
|
x_data = Form("submit")
|
||||||
|
x_data.add_field(name="name",
|
||||||
|
value="account1",
|
||||||
|
field_type="text-single")
|
||||||
|
x_data.add_field(name="login",
|
||||||
|
value="mylogin1",
|
||||||
|
field_type="text-single")
|
||||||
|
iq_set = Iq(stanza_type="set",
|
||||||
|
from_jid="user1@test.com",
|
||||||
|
to_jid="jcl.test.com")
|
||||||
|
query = iq_set.new_query("jabber:iq:register")
|
||||||
|
x_data.as_xml(query)
|
||||||
|
self.comp.handle_set_register(iq_set)
|
||||||
|
|
||||||
|
model.db_connect()
|
||||||
|
_account = account.get_account("user1@test.com", "account1")
|
||||||
|
self.assertNotEquals(_account, None)
|
||||||
|
self.assertEquals(_account.user.jid, "user1@test.com")
|
||||||
|
self.assertEquals(_account.name, "account1")
|
||||||
|
self.assertEquals(_account.jid, "account1@jcl.test.com")
|
||||||
|
self.assertEquals(_account.login, "mylogin1")
|
||||||
|
self.assertEquals(_account.password, None)
|
||||||
|
self.assertTrue(_account.store_password)
|
||||||
|
self.assertEquals(_account.test_enum, "choice2")
|
||||||
|
self.assertEquals(_account.test_int, 44)
|
||||||
|
model.db_disconnect()
|
||||||
|
|
||||||
|
x_data = Form("submit")
|
||||||
|
x_data.add_field(name="name",
|
||||||
|
value="account2",
|
||||||
|
field_type="text-single")
|
||||||
|
x_data.add_field(name="login",
|
||||||
|
value="mylogin2",
|
||||||
|
field_type="text-single")
|
||||||
|
iq_set = Iq(stanza_type="set",
|
||||||
|
from_jid="user1@test.com",
|
||||||
|
to_jid="jcl.test.com")
|
||||||
|
query = iq_set.new_query("jabber:iq:register")
|
||||||
|
x_data.as_xml(query)
|
||||||
|
self.comp.handle_set_register(iq_set)
|
||||||
|
|
||||||
|
model.db_connect()
|
||||||
|
_account = account.get_account("user1@test.com", "account2")
|
||||||
|
self.assertNotEquals(_account, None)
|
||||||
|
self.assertEquals(_account.user.jid, "user1@test.com")
|
||||||
|
self.assertEquals(_account.name, "account2")
|
||||||
|
self.assertEquals(_account.jid, "account2@jcl.test.com")
|
||||||
|
self.assertEquals(_account.login, "mylogin2")
|
||||||
|
self.assertEquals(_account.password, None)
|
||||||
|
self.assertTrue(_account.store_password)
|
||||||
|
self.assertEquals(_account.test_enum, "choice2")
|
||||||
|
self.assertEquals(_account.test_int, 44)
|
||||||
|
|
||||||
|
users = account.get_all_users(filter=(User.q.jid == "user1@test.com"))
|
||||||
|
self.assertEquals(users.count(), 1)
|
||||||
|
model.db_disconnect()
|
||||||
|
|
||||||
def test_handle_set_register_new_name_mandatory(self):
|
def test_handle_set_register_new_name_mandatory(self):
|
||||||
self.comp.stream = MockStream()
|
self.comp.stream = MockStream()
|
||||||
self.comp.stream_class = MockStream
|
self.comp.stream_class = MockStream
|
||||||
@@ -1539,6 +1600,8 @@ class JCLComponent_TestCase(JCLTestCase):
|
|||||||
model.db_connect()
|
model.db_connect()
|
||||||
self.assertEquals(account.get_accounts_count("user1@test.com"),
|
self.assertEquals(account.get_accounts_count("user1@test.com"),
|
||||||
0)
|
0)
|
||||||
|
self.assertEquals(account.get_all_users(filter=(User.q.jid == "user1@test.com")).count(),
|
||||||
|
0)
|
||||||
accounts = account.get_accounts("user2@test.com")
|
accounts = account.get_accounts("user2@test.com")
|
||||||
i = 0
|
i = 0
|
||||||
for _account in accounts:
|
for _account in accounts:
|
||||||
@@ -2369,6 +2432,111 @@ class JCLComponent_TestCase(JCLTestCase):
|
|||||||
1)
|
1)
|
||||||
self.assertEquals(account.get_all_accounts_count(),
|
self.assertEquals(account.get_all_accounts_count(),
|
||||||
2)
|
2)
|
||||||
|
self.assertEquals(account.get_all_users(filter=(User.q.jid == "user1@test.com")).count(),
|
||||||
|
1)
|
||||||
|
model.db_disconnect()
|
||||||
|
|
||||||
|
def test_handle_presence_unsubscribe_to_last_account(self):
|
||||||
|
self.comp.stream = MockStream()
|
||||||
|
self.comp.stream_class = MockStream
|
||||||
|
model.db_connect()
|
||||||
|
user1 = User(jid="user1@test.com")
|
||||||
|
account11 = Account(user=user1,
|
||||||
|
name="account11",
|
||||||
|
jid="account11@jcl.test.com")
|
||||||
|
account2 = Account(user=User(jid="user2@test.com"),
|
||||||
|
name="account2",
|
||||||
|
jid="account2@jcl.test.com")
|
||||||
|
model.db_disconnect()
|
||||||
|
self.comp.handle_presence_unsubscribe(Presence(\
|
||||||
|
stanza_type="unsubscribe",
|
||||||
|
from_jid="user1@test.com",
|
||||||
|
to_jid="account11@jcl.test.com"))
|
||||||
|
presence_sent = self.comp.stream.sent
|
||||||
|
self.assertEqual(len(presence_sent), 2)
|
||||||
|
presence = presence_sent[0]
|
||||||
|
self.assertEqual(presence.get_from(), "account11@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribe")
|
||||||
|
presence = presence_sent[1]
|
||||||
|
self.assertEqual(presence.get_from(), "account11@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribed")
|
||||||
|
model.db_connect()
|
||||||
|
self.assertEquals(account.get_account("user1@test.com", "account11"),
|
||||||
|
None)
|
||||||
|
self.assertEquals(account.get_accounts_count("user1@test.com"),
|
||||||
|
0)
|
||||||
|
self.assertEquals(account.get_all_accounts_count(),
|
||||||
|
1)
|
||||||
|
self.assertEquals(account.get_all_users(filter=(User.q.jid == "user1@test.com")).count(),
|
||||||
|
0)
|
||||||
|
model.db_disconnect()
|
||||||
|
|
||||||
|
def test_handle_presence_unsubscribe_to_root(self):
|
||||||
|
self.comp.stream = MockStream()
|
||||||
|
self.comp.stream_class = MockStream
|
||||||
|
model.db_connect()
|
||||||
|
user1 = User(jid="user1@test.com")
|
||||||
|
account11 = Account(user=user1,
|
||||||
|
name="account11",
|
||||||
|
jid="account11@jcl.test.com")
|
||||||
|
account12 = Account(user=user1,
|
||||||
|
name="account12",
|
||||||
|
jid="account12@jcl.test.com")
|
||||||
|
account2 = Account(user=User(jid="user2@test.com"),
|
||||||
|
name="account2",
|
||||||
|
jid="account2@jcl.test.com")
|
||||||
|
model.db_disconnect()
|
||||||
|
self.comp.handle_presence_unsubscribe(Presence(\
|
||||||
|
stanza_type="unsubscribe",
|
||||||
|
from_jid="user1@test.com",
|
||||||
|
to_jid="jcl.test.com"))
|
||||||
|
presence_sent = self.comp.stream.sent
|
||||||
|
self.assertEqual(len(presence_sent), 6)
|
||||||
|
presence = presence_sent[0]
|
||||||
|
self.assertEqual(presence.get_from(), "account11@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribe")
|
||||||
|
presence = presence_sent[1]
|
||||||
|
self.assertEqual(presence.get_from(), "account11@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribed")
|
||||||
|
presence = presence_sent[2]
|
||||||
|
self.assertEqual(presence.get_from(), "account12@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribe")
|
||||||
|
presence = presence_sent[3]
|
||||||
|
self.assertEqual(presence.get_from(), "account12@jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribed")
|
||||||
|
presence = presence_sent[4]
|
||||||
|
self.assertEqual(presence.get_from(), "jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribe")
|
||||||
|
presence = presence_sent[5]
|
||||||
|
self.assertEqual(presence.get_from(), "jcl.test.com")
|
||||||
|
self.assertEqual(presence.get_to(), "user1@test.com")
|
||||||
|
self.assertEqual(presence.xpath_eval("@type")[0].get_content(),
|
||||||
|
"unsubscribed")
|
||||||
|
model.db_connect()
|
||||||
|
self.assertEquals(account.get_account("user1@test.com", "account11"),
|
||||||
|
None)
|
||||||
|
self.assertEquals(account.get_account("user1@test.com", "account12"),
|
||||||
|
None)
|
||||||
|
self.assertEquals(account.get_accounts_count("user1@test.com"),
|
||||||
|
0)
|
||||||
|
self.assertEquals(account.get_all_accounts_count(),
|
||||||
|
1)
|
||||||
|
self.assertEquals(account.get_all_users(filter=(User.q.jid == "user1@test.com")).count(),
|
||||||
|
0)
|
||||||
model.db_disconnect()
|
model.db_disconnect()
|
||||||
|
|
||||||
def test_handle_presence_unsubscribe_to_registered_handlers(self):
|
def test_handle_presence_unsubscribe_to_registered_handlers(self):
|
||||||
|
|||||||
@@ -308,17 +308,17 @@ class Lang:
|
|||||||
|
|
||||||
command_get_user_password = u"Récupérer le mot de passe d'un compte"
|
command_get_user_password = u"Récupérer le mot de passe d'un compte"
|
||||||
command_get_user_password_1_description = \
|
command_get_user_password_1_description = \
|
||||||
u"Remplir ce formulaire avec le(s) Jabber ID(s) utilisateur(s)" \
|
u"Remplir ce formulaire avec le Jabber ID utilisateur" \
|
||||||
u" pour rechercher le(s) compte(s) pour récupérer leur mot de passe"
|
u" pour rechercher le compte pour récupérer leur mot de passe"
|
||||||
command_get_user_password_2_description = \
|
command_get_user_password_2_description = \
|
||||||
u"Sélectionner le(s) compte(s) pour récupérer leur mot de passe"
|
u"Sélectionner le compte pour récupérer leur mot de passe"
|
||||||
|
|
||||||
command_change_user_password = u"Changer le mot de passe d'un compte"
|
command_change_user_password = u"Changer le mot de passe d'un compte"
|
||||||
command_change_user_password_1_description = \
|
command_change_user_password_1_description = \
|
||||||
u"Remplir ce formulaire avec le(s) Jabber ID(s) utilisateur(s)" \
|
u"Remplir ce formulaire avec le Jabber ID utilisateur" \
|
||||||
u" pour rechercher le(s) compte(s) pour changer leur mot de passe"
|
u" pour rechercher le compte pour changer leur mot de passe"
|
||||||
command_change_user_password_2_description = \
|
command_change_user_password_2_description = \
|
||||||
u"Sélectionner le(s) compte(s) pour changer leur mot de passe"
|
u"Sélectionner le compte pour changer leur mot de passe"
|
||||||
|
|
||||||
command_get_user_roster = u"Récupérer les comptes utilisateurs"
|
command_get_user_roster = u"Récupérer les comptes utilisateurs"
|
||||||
command_get_user_roster_1_description = \
|
command_get_user_roster_1_description = \
|
||||||
|
|||||||
@@ -70,7 +70,6 @@ def get_user(bare_from_jid, user_class=User):
|
|||||||
result = None
|
result = None
|
||||||
model.db_connect()
|
model.db_connect()
|
||||||
users = user_class.select(User.q.jid == bare_from_jid)
|
users = user_class.select(User.q.jid == bare_from_jid)
|
||||||
model.db_disconnect()
|
|
||||||
if users.count() > 0:
|
if users.count() > 0:
|
||||||
result = users[0]
|
result = users[0]
|
||||||
return result
|
return result
|
||||||
|
|||||||
Reference in New Issue
Block a user