libervia-backend/sat_frontends/jp/cmd_account.py
Goffi 76aadbb3fb jp: jp asyncio port:
/!\ this commit is huge. Jp is temporarily not working with `dbus` bridge /!\

This patch implements the port of jp to asyncio, so it is now correctly using the bridge
asynchronously, and it can be used with bridges like `pb`. This also simplify the code,
notably for things which were previously implemented with many callbacks (like pagination
with RSM).

During the process, some behaviours have been modified/fixed, in jp and backends, check
diff for details.
2019-09-25 08:56:41 +02:00

224 lines
7 KiB
Python

#!/usr/bin/env python2
# -*- coding: utf-8 -*-
# jp: a SAT command line tool
# Copyright (C) 2009-2019 Jérôme Poisson (goffi@goffi.org)
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
"""This module permits to manage XMPP accounts using in-band registration (XEP-0077)"""
from sat_frontends.jp.constants import Const as C
from sat.core.log import getLogger
log = getLogger(__name__)
from sat.core.i18n import _
from sat_frontends.jp import base
from sat_frontends.tools import jid
__commands__ = ["Account"]
class AccountCreate(base.CommandBase):
def __init__(self, host):
super(AccountCreate, self).__init__(
host,
"create",
use_profile=False,
use_verbose=True,
help=_("create a XMPP account"),
)
def add_parser_options(self):
self.parser.add_argument(
"jid", help=_("jid to create")
)
self.parser.add_argument(
"password", help=_("password of the account")
)
self.parser.add_argument(
"-p",
"--profile",
help=_(
"create a profile to use this account (default: don't create profile)"
),
)
self.parser.add_argument(
"-e",
"--email",
default="",
help=_("email (usage depends of XMPP server)"),
)
self.parser.add_argument(
"-H",
"--host",
default="",
help=_("server host (IP address or domain, default: use localhost)"),
)
self.parser.add_argument(
"-P",
"--port",
type=int,
default=0,
help=_(f"server port (default: {C.XMPP_C2S_PORT})"),
)
async def start(self):
try:
await self.host.bridge.inBandAccountNew(
self.args.jid,
self.args.password,
self.args.email,
self.args.host,
self.args.port,
)
except Exception as e:
self.disp(
f"can't create account on {self.args.host or 'localhost'!r} with jid "
f"{self.args.jid!r} using In-Band Registration: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
self.disp(_("XMPP account created"), 1)
if self.args.profile is None:
self.host.quit()
self.disp(_("creating profile"), 2)
try:
await self.host.bridge.profileCreate(
self.args.profile,
self.args.password,
"",
)
except Exception as e:
self.disp(
_(f"Can't create profile {self.args.profile} to associate with jid "
f"{self.args.jid}: {e}"),
error=True,
)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
self.disp(_("profile created"), 1)
try:
await self.host.bridge.profileStartSession(
self.args.password,
self.args.profile,
)
except Exception as e:
self.disp(f"can't start profile session: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
try:
await self.host.bridge.setParam(
"JabberID",
self.args.jid,
"Connection",
profile_key=self.args.profile,
)
except Exception as e:
self.disp(f"can't set JabberID parameter: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
try:
await self.host.bridge.setParam(
"Password",
self.args.password,
"Connection",
profile_key=self.args.profile,
)
except Exception as e:
self.disp(f"can't set Password parameter: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
self.disp(
f"profile {self.args.profile} successfully created and associated to the new "
f"account", 1)
self.host.quit()
class AccountModify(base.CommandBase):
def __init__(self, host):
super(AccountModify, self).__init__(
host, "modify", help=_("change password for XMPP account")
)
def add_parser_options(self):
self.parser.add_argument(
"password", help=_("new XMPP password")
)
async def start(self):
try:
await self.host.bridge.inBandPasswordChange(
self.args.password,
self.args.profile,
)
except Exception as e:
self.disp(f"can't change XMPP password: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
else:
self.host.quit()
class AccountDelete(base.CommandBase):
def __init__(self, host):
super(AccountDelete, self).__init__(
host, "delete", help=_("delete a XMPP account")
)
def add_parser_options(self):
self.parser.add_argument(
"-f",
"--force",
action="store_true",
help=_("delete account without confirmation"),
)
async def start(self):
try:
jid_str = await self.host.bridge.asyncGetParamA(
"JabberID",
"Connection",
profile_key=self.profile,
)
except Exception as e:
self.disp(f"can't get JID of the profile: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
jid_ = jid.JID(jid_str)
if not self.args.force:
message = (
f"You are about to delete the XMPP account with jid {jid_!r}\n"
f"This is the XMPP account of profile {self.profile!r}\n"
f"Are you sure that you want to delete this account?"
)
await self.host.confirmOrQuit(message, _("Account deletion cancelled"))
try:
await self.host.bridge.inBandUnregister(jid_.domain, self.args.profile)
except Exception as e:
self.disp(f"can't delete XMPP account with jid {jid_!r}: {e}", error=True)
self.host.quit(C.EXIT_BRIDGE_ERRBACK)
self.host.quit()
class Account(base.CommandBase):
subcommands = (AccountCreate, AccountModify, AccountDelete)
def __init__(self, host):
super(Account, self).__init__(
host, "account", use_profile=False, help=("XMPP account management")
)