def sign_in(self, phone_number, code): """Completes the authorization of a phone number by providing the received code""" if phone_number not in self.phone_code_hashes: raise ValueError( 'Please make sure you have called send_code_request first.') try: result = self.invoke( SignInRequest(phone_number, self.phone_code_hashes[phone_number], code)) except RPCError as error: if error.message.startswith('PHONE_CODE_'): print(error) return False else: raise error # Result is an Auth.Authorization TLObject self.session.user = result.user self.session.save() # Now that we're authorized, set the signed_in flag # to True so update handlers can be added self.signed_in = True return True
def sign_in(self, phone_number=None, code=None, password=None, bot_token=None): """Completes the authorization of a phone number by providing the received code. If no phone or code is provided, then the sole password will be used. The password should be used after a normal authorization attempt has happened and an RPCError with `.password_required = True` was raised. To login as a bot, only `bot_token` should be provided. This should equal to the bot access hash provided by https://t.me/BotFather during your bot creation.""" if phone_number and code: if phone_number not in self.phone_code_hashes: raise ValueError( 'Please make sure you have called send_code_request first.' ) try: result = self.invoke( SignInRequest(phone_number, self.phone_code_hashes[phone_number], code)) except RPCError as error: if error.message.startswith('PHONE_CODE_'): print(error) return False else: raise error elif password: salt = self.invoke(GetPasswordRequest()).current_salt result = self.invoke( CheckPasswordRequest(utils.get_password_hash(password, salt))) elif bot_token: result = self.invoke( ImportBotAuthorizationRequest(flags=0, api_id=self.api_id, api_hash=self.api_hash, bot_auth_token=bot_token)) else: raise ValueError( 'You must provide a phone_number and a code for the first time, ' 'and a password only if an RPCError was raised before.') # Result is an Auth.Authorization TLObject self.session.user = result.user self.session.save() # Now that we're authorized, set the signed_in flag # to True so update handlers can be added self.signed_in = True return True
def sign_in(self, phone_number=None, code=None, password=None, bot_token=None): if phone_number and code: if phone_number not in self.phone_code_hashes: raise ValueError( "Please make sure you have called send_code_request first." ) try: result = self.invoke( SignInRequest(phone_number, self.phone_code_hashes[phone_number], code)) except RPCError as error: if error.message.startswith("PHONE_CODE_"): print(error) return False else: raise error elif password: salt = self.invoke(GetPasswordRequest()).current_salt result = self.invoke( CheckPasswordRequest(utils.get_password_hash(password, salt))) elif bot_token: result = self.invoke( ImportBotAuthorizationRequest(flags=0, api_id=self.api_id, api_hash=self.api_hash, bot_auth_token=bot_token)) else: raise ValueError( "You must provide a phone_number and a code for the first time, " "and a password only if an RPCError was raised before.") self.session.user = result.user self.session.save() self.signed_in = True return True
async def authorize_phone( phone: str, password: Union[None, str] = None, bot_token: Union[None, str] = None, force_sms: bool = False, code: Union[None, str] = None, phone_code_hash: Union[None, str] = None, session: Union[None, str] = None, ): logger.info( f"Args: phone={phone}, password={password}, bot_token={bot_token}, force_sms={force_sms}, code={code}." ) bot = TelegramClientUpdateCollector( session=StringSession(session), api_id=TG_APP_ID, api_hash=TG_APP_HASH, mode=UpdateModes.SILENT, ) if not bot.is_connected(): await bot.connect() # end if if not bot_token: # Turn the callable into a valid phone number (or bot token) phone = parse_phone(phone) else: me = await bot.sign_in(bot_token=bot_token) if not isinstance(me, User): me = await bot.get_me() # end if user_id = me.user_id if hasattr(me, 'user_id') else me.id assert user_id bots[user_id] = bot return r_success( result=PhoneAuthorisation( message='SUCCESS: registered bot', reason=PhoneAuthorisationReasons.SUCCESS_BOT, data=PhoneAuthorisationData(token='bot' + bot_token, # session=bot.session.save(), )), description= "OK: Logged in. Use the token to connect to this service.", status_code=200, ) # end if logger.info(f'Phone Number: {phone}') if not code: logger.info('Sending code request.') sent_code = await bot.send_code_request(phone, force_sms=force_sms) logger.info(f'sent_code: {sent_code}') # sign_up = not sent_code.phone_registered logger.warning( "Needs code now!\n" "Please provide via '$TELEGRAM_LOGGER_PHONE_LOGIN_CODE' environment variable.\n" f"Also set '$TELEGRAM_LOGGER_PHONE_LOGIN_HASH={sent_code.phone_code_hash}'." ) session_str = bot.session.save() return r_error( result=PhoneAuthorisation( message='LOGIN FAILED: Please provide the code sent to you', reason=PhoneAuthorisationReasons.CODE_NEEDED, data=PhoneAuthorisationData( phone_code_hash=sent_code.phone_code_hash, session=session_str, ), ), error_code=401, description= "UNAUTHORIZED: Login failed, please provide the code sent to you", ) else: logger.info('Signing in.') try: # me = await self.sign_in(phone, code=code, phone_code_hash=phone_code_hash) result = await bot(SignInRequest(phone, phone_code_hash, str(code))) logger.warning(f"Sign in result: {result}") me = bot._on_login(result.user) except PhoneCodeExpiredError: session_str = bot.session.save() # TODO: Status 502 return r_error( result=PhoneAuthorisation( message= 'LOGIN FAILED: Code expired. Please provide the new code sent to you', reason=PhoneAuthorisationReasons.CODE_EXPIRED, data=PhoneAuthorisationData( phone_code_hash=phone_code_hash, session=session_str, )), error_code=401, description= 'UNAUTHORIZED: Login failed, code expired. Please provide the new code sent to you', ) except SessionPasswordNeededError: if not password: txt = "Two-step verification is enabled for this account. Please provide the 'TELEGRAM_LOGGER_PHONE_LOGIN_CODE' environment variable." session_str = bot.session.save() logger.error(txt) # TODO: Status 502 return r_error( result=PhoneAuthorisation( message= 'LOGIN FAILED: Please provide your personal two factor login (2FA) password you set in your account', reason=PhoneAuthorisationReasons. TWO_FACTOR_PASSWORD_NEEDED, data=PhoneAuthorisationData( phone_code_hash=phone_code_hash, code=code, session=session_str, )), error_code=401, description= 'UNAUTHORIZED: Login failed, please provide your personal two factor login (2FA) password you set in your account', ) # end if me = await bot.sign_in(phone=phone, password=password, phone_code_hash=phone_code_hash) except Exception as e: logger.exception('sign in didn\'t work') raise e # end try assert await bot.is_user_authorized(), "should be authorized now." if not isinstance(me, User): me = await bot.get_me() # end if if hasattr(me, 'id'): chat_id = me.id elif hasattr(me, 'chat_id'): chat_id = me.chat_id elif hasattr(me, 'channel_id'): chat_id = me.channel_id elif hasattr(me, 'user_id'): chat_id = me.user_id else: logger.warn(f'me has no id like attribute:\n{me!r}\n{me!s}') raise ValueError('me is wrong?') # end if secret = bot.session.save() user_token = f'user{chat_id!s}@{secret}' # noinspection PyTypeChecker return r_success( result=SuccessfulPhoneAuthorisationData(user_token=user_token), description= "OK: Logged in. Use the token to connect to this service.", status_code=200)