patch a9bce1e704e2e0a7c711e4b984e87b2919384554 Author: E. Bosch Date: Tue Mar 8 22:58:55 CET 2022 * service: Add code command, add ask_code option diff -rN -u old-irgramd/irc.py new-irgramd/irc.py --- old-irgramd/irc.py 2024-11-22 21:35:53.558859220 +0100 +++ new-irgramd/irc.py 2024-11-22 21:35:53.562859214 +0100 @@ -108,6 +108,7 @@ def set_telegram(self, tg): self.tg = tg + self.service = service(self.conf, self.tg) # IRC @@ -142,7 +143,6 @@ self.service_user = IRCUser(None, ('Services.{}'.format(self.hostname),), self.conf['service_user'], 'Control', 'Telegram Service', is_service=True) self.users[self.conf['service_user'].lower()] = self.service_user - self.service = service() async def send_irc_command(self, user, command): self.logger.debug('Send IRC Command: %s', command) @@ -380,7 +380,7 @@ tgl = target.lower() if self.service_user.irc_nick.lower() == tgl: - reply = self.service.parse_command(message) + reply = await self.service.parse_command(message) for reply_line in reply: await self.send_msg(self.service_user, user.irc_nick, reply_line) return @@ -415,6 +415,7 @@ user.registered = True await self.send_greeting(user) await self.send_help(user) + await self.check_telegram_auth(user) async def send_msg(self, source, target, message): messages = split_lines(message) @@ -503,6 +504,18 @@ ): await self.send_msg(self.service_user, user.irc_nick, line) + async def check_telegram_auth(self, user): + if not self.tg.authorized and not self.tg.ask_code: + for line in ( + '----', + 'Your Telegram account is not authorized yet,', + 'you must supply the code that Telegram sent to your phone', + 'or another client that is currently connected', + 'use /msg {} code '.format(self.service_user.irc_nick), + 'e.g. /msg {} code 12345'.format(self.service_user.irc_nick), + ): + await self.send_msg(self.service_user, user.irc_nick, line) + async def send_users_irc(self, prfx, command, params): for usr in [x for x in self.users.values() if x.stream]: await self.reply_command(usr, prfx, command, params) diff -rN -u old-irgramd/irgramd new-irgramd/irgramd --- old-irgramd/irgramd 2024-11-22 21:35:53.558859220 +0100 +++ new-irgramd/irgramd 2024-11-22 21:35:53.562859214 +0100 @@ -68,6 +68,7 @@ logger = logging.getLogger() tornado.options.define('api_hash', default=None, metavar='HASH', help='Telegram API Hash for your account (obtained from https://my.telegram.org/apps)') tornado.options.define('api_id', type=int, default=None, metavar='ID', help='Telegram API ID for your account (obtained from https://my.telegram.org/apps)') + tornado.options.define('ask_code', default=False, help='Ask authentication code (sent by Telegram) in console instead of "code" service command in IRC') tornado.options.define('config', default='irgramdrc', metavar='CONFIGFILE', help='Config file absolute or relative to `config_dir` (command line options override it)') tornado.options.define('config_dir', default='~/.config/irgramd', metavar='PATH', help='Configuration directory where telegram session info is saved') tornado.options.define('irc_address', default='127.0.0.1', metavar='ADDRESS', help='Address to listen on for IRC') diff -rN -u old-irgramd/service.py new-irgramd/service.py --- old-irgramd/service.py 2024-11-22 21:35:53.558859220 +0100 +++ new-irgramd/service.py 2024-11-22 21:35:53.562859214 +0100 @@ -7,13 +7,16 @@ # can be found in the LICENSE file included in this project. class service: - def __init__(self): + def __init__(self, settings, telegram): self.commands = \ { # Command Handler Arguments Min Max + 'code': (self.handle_command_code, 1, 1), 'help': (self.handle_command_help, 0, 1), } + self.ask_code = settings['ask_code'] + self.tg = telegram - def parse_command(self, line): + async def parse_command(self, line): words = line.split() command = words.pop(0).lower() @@ -23,13 +26,41 @@ if num_words < min_args or num_words > max_args: reply = ('Wrong number of arguments',) else: - reply = handler(*words) + reply = await handler(*words) else: reply = ('Unknown command',) return reply - def handle_command_help(self, help_command=None, help=None): + async def handle_command_code(self, code=None, help=None): + if not help: + if self.ask_code: + reply = ('Code will be asked on console',) + elif code.isdigit(): + try: + await self.tg.telegram_client.sign_in(code=code) + except: + reply = ('Invalid code',) + else: + reply = ('Valid code', 'Telegram account authorized') + await self.tg.continue_auth() + else: # not isdigit + reply = ('Code must be numeric',) + + else: # HELP.brief or HELP.desc (first line) + reply = (' code Enter authorization code',) + if help == HELP.desc: # rest of HELP.desc + reply += \ + ( + ' code ', + 'Enter authorization code sent by Telegram to the phone or to', + 'another client connected.', + 'This authorization code usually is only needed the first time', + 'that irgramd connects to Telegram with a given account.', + ) + return reply + + async def handle_command_help(self, help_command=None, help=None): start_help = ('*** Telegram Service Help ***',) end_help = ('*** End of Help ***',) @@ -45,7 +76,7 @@ ) for command in self.commands.values(): handler = command[0] - help_text += handler(help=HELP.brief) + help_text += await handler(help=HELP.brief) help_text += \ ( 'If you need more information about a specific command you can use', @@ -55,7 +86,7 @@ elif help_command in self.commands.keys(): handler = self.commands[help_command][0] help_text = start_help - help_text += handler(help=HELP.desc) + help_text += await handler(help=HELP.desc) help_text += end_help else: help_text = ('help: Unknown command',) diff -rN -u old-irgramd/telegram.py new-irgramd/telegram.py --- old-irgramd/telegram.py 2024-11-22 21:35:53.558859220 +0100 +++ new-irgramd/telegram.py 2024-11-22 21:35:53.562859214 +0100 @@ -42,6 +42,7 @@ self.test_dc = settings['test_datacenter'] self.test_ip = settings['test_host'] if settings['test_host'] else TEST_IPS[self.test_dc] self.test_port = settings['test_port'] + self.ask_code = settings['ask_code'] self.media_cn = 0 self.irc = irc self.authorized = False @@ -89,15 +90,21 @@ await self.telegram_client.connect() while not await self.telegram_client.is_user_authorized(): - self.logger.info('Telegram account not authorized, you must provide the Login code ' - 'that Telegram will sent you via SMS or another connected client') + self.logger.info('Telegram account not authorized') await self.telegram_client.send_code_request(self.phone) + if not self.ask_code: + return + self.logger.info('You must provide the Login code that Telegram will ' + 'sent you via SMS or another connected client') code = await aioconsole.ainput('Login code: ') try: await self.telegram_client.sign_in(code=code) except: pass + await self.continue_auth() + + async def continue_auth(self): self.logger.info('Telegram account authorized') self.authorized = True await self.init_mapping()