コード例 #1
0
    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
コード例 #2
0
    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
コード例 #3
0
    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
コード例 #4
0
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)