Remove requesting SMS login codes and signing up

This commit is contained in:
Tulir Asokan 2023-02-10 21:02:13 +02:00
parent acfde7132b
commit 6bb0ee081f

View File

@ -25,7 +25,7 @@ class AuthMethods:
bot_token: str = None,
force_sms: bool = False,
code_callback: typing.Callable[[], typing.Union[str, int]] = None,
first_name: str = 'New User',
first_name: str = '',
last_name: str = '',
max_attempts: int = 3) -> 'TelegramClient':
"""
@ -34,11 +34,9 @@ class AuthMethods:
By default, this method will be interactive (asking for
user input if needed), and will handle 2FA if enabled too.
If the phone doesn't belong to an existing account (and will hence
`sign_up` for a new one), **you are agreeing to Telegram's
Terms of Service. This is required and your account
will be banned otherwise.** See https://telegram.org/tos
and https://core.telegram.org/api/terms.
If the phone doesn't belong to an existing account, an error
will be raised, as Telegram requires using an official mobile
client for signing up.
If the event loop is already running, this method returns a
coroutine that you should await on your own code; otherwise
@ -62,8 +60,8 @@ class AuthMethods:
one of either allowed).
force_sms (`bool`, optional):
Whether to force sending the code request as SMS.
This only makes sense when signing in with a `phone`.
Deprecated: third-party clients aren't allowed to request SMS anymore.
This parameter does nothing.
code_callback (`callable`, optional):
A callable that will be used to retrieve the Telegram
@ -71,11 +69,12 @@ class AuthMethods:
The argument may be a coroutine.
first_name (`str`, optional):
The first name to be used if signing up. This has no
effect if the account already exists and you sign in.
Deprecated: Signing up is no longer supported.
This parameter does nothing.
last_name (`str`, optional):
Similar to the first name, but for the last. Optional.
Deprecated: Signing up is no longer supported.
This parameter does nothing.
max_attempts (`int`, optional):
How many times the code/password callback should be
@ -103,6 +102,10 @@ class AuthMethods:
with client:
pass
"""
if force_sms:
warnings.warn("force_sms is deprecated and does nothing", DeprecationWarning)
if first_name or last_name:
warnings.warn("first_name and last_name are deprecated and do nothing", DeprecationWarning)
if code_callback is None:
def code_callback():
return input('Please enter the code you received: ')
@ -123,10 +126,7 @@ class AuthMethods:
phone=phone,
password=password,
bot_token=bot_token,
force_sms=force_sms,
code_callback=code_callback,
first_name=first_name,
last_name=last_name,
max_attempts=max_attempts
)
return (
@ -135,8 +135,8 @@ class AuthMethods:
)
async def _start(
self: 'TelegramClient', phone, password, bot_token, force_sms,
code_callback, first_name, last_name, max_attempts):
self: 'TelegramClient', phone, password, bot_token,
code_callback, max_attempts):
if not self.is_connected():
await self.connect()
@ -187,8 +187,7 @@ class AuthMethods:
attempts = 0
two_step_detected = False
await self.send_code_request(phone, force_sms=force_sms)
sign_up = False # assume login
await self.send_code_request(phone)
while attempts < max_attempts:
try:
value = code_callback()
@ -201,19 +200,14 @@ class AuthMethods:
if not value:
raise errors.PhoneCodeEmptyError(request=None)
if sign_up:
me = await self.sign_up(value, first_name, last_name)
else:
# Raises SessionPasswordNeededError if 2FA enabled
me = await self.sign_in(phone, code=value)
# Raises SessionPasswordNeededError if 2FA enabled
me = await self.sign_in(phone, code=value)
break
except errors.SessionPasswordNeededError:
two_step_detected = True
break
except errors.PhoneNumberOccupiedError:
sign_up = False
except errors.PhoneNumberUnoccupiedError:
sign_up = True
raise RuntimeError("Phone number not registered. Sign up using an official mobile client first.")
except (errors.PhoneCodeEmptyError,
errors.PhoneCodeExpiredError,
errors.PhoneCodeHashEmptyError,
@ -374,101 +368,6 @@ class AuthMethods:
return await self._on_login(result.user)
async def sign_up(
self: 'TelegramClient',
code: typing.Union[str, int],
first_name: str,
last_name: str = '',
*,
phone: str = None,
phone_code_hash: str = None) -> 'types.User':
"""
Signs up to Telegram as a new user account.
Use this if you don't have an account yet.
You must call `send_code_request` first.
**By using this method you're agreeing to Telegram's
Terms of Service. This is required and your account
will be banned otherwise.** See https://telegram.org/tos
and https://core.telegram.org/api/terms.
Arguments
code (`str` | `int`):
The code sent by Telegram
first_name (`str`):
The first name to be used by the new account.
last_name (`str`, optional)
Optional last name.
phone (`str` | `int`, optional):
The phone to sign up. This will be the last phone used by
default (you normally don't need to set this).
phone_code_hash (`str`, optional):
The hash returned by `send_code_request`. This can be left as
`None` to use the last hash known for the phone to be used.
Returns
The new created :tl:`User`.
Example
.. code-block:: python
phone = '+34 123 123 123'
await client.send_code_request(phone)
code = input('enter code: ')
await client.sign_up(code, first_name='Anna', last_name='Banana')
"""
me = await self.get_me()
if me:
return me
# To prevent abuse, one has to try to sign in before signing up. This
# is the current way in which Telegram validates the code to sign up.
#
# `sign_in` will set `_tos`, so if it's set we don't need to call it
# because the user already tried to sign in.
#
# We're emulating pre-layer 104 behaviour so except the right error:
if not self._tos:
try:
return await self.sign_in(
phone=phone,
code=code,
phone_code_hash=phone_code_hash,
)
except errors.PhoneNumberUnoccupiedError:
pass # code is correct and was used, now need to sign in
if self._tos and self._tos.text:
if self.parse_mode:
t = self.parse_mode.unparse(self._tos.text, self._tos.entities)
else:
t = self._tos.text
sys.stderr.write("{}\n".format(t))
sys.stderr.flush()
phone, phone_code_hash = \
self._parse_phone_and_hash(phone, phone_code_hash)
result = await self(functions.auth.SignUpRequest(
phone_number=phone,
phone_code_hash=phone_code_hash,
first_name=first_name,
last_name=last_name
))
if self._tos:
await self(
functions.help.AcceptTermsOfServiceRequest(self._tos.id))
return await self._on_login(result.user)
async def _on_login(self, user):
"""
Callback called whenever the login or sign up process completes.
@ -498,7 +397,8 @@ class AuthMethods:
The phone to which the code will be sent.
force_sms (`bool`, optional):
Whether to force sending as SMS.
Deprecated: third-party clients aren't allowed to request SMS anymore.
This parameter does nothing.
Returns
An instance of :tl:`SentCode`.
@ -510,55 +410,29 @@ class AuthMethods:
sent = await client.send_code_request(phone)
print(sent)
"""
result = None
if force_sms:
warnings.warn("force_sms is deprecated and does nothing", DeprecationWarning)
phone = utils.parse_phone(phone) or self._phone
phone_hash = self._phone_code_hash.get(phone)
if not phone_hash:
try:
result = await self(functions.auth.SendCodeRequest(
phone, self.api_id, self.api_hash, types.CodeSettings()))
except errors.AuthRestartError:
if _retry_count > 2:
raise
return await self.send_code_request(
phone, force_sms=force_sms, _retry_count=_retry_count+1)
try:
result = await self(functions.auth.SendCodeRequest(
phone, self.api_id, self.api_hash, types.CodeSettings()))
except errors.AuthRestartError:
if _retry_count > 2:
raise
return await self.send_code_request(
phone, _retry_count=_retry_count+1)
# TODO figure out when/if/how this can happen
if isinstance(result, types.auth.SentCodeSuccess):
raise RuntimeError('logged in right after sending the code')
# TODO figure out when/if/how this can happen
if isinstance(result, types.auth.SentCodeSuccess):
raise RuntimeError('logged in right after sending the code')
# If we already sent a SMS, do not resend the code (hash may be empty)
if isinstance(result.type, types.auth.SentCodeTypeSms):
force_sms = False
# phone_code_hash may be empty, if it is, do not save it (#1283)
if result.phone_code_hash:
self._phone_code_hash[phone] = phone_hash = result.phone_code_hash
else:
force_sms = True
# phone_code_hash may be empty, if it is, do not save it (#1283)
if result.phone_code_hash:
self._phone_code_hash[phone] = result.phone_code_hash
self._phone = phone
if force_sms:
try:
result = await self(
functions.auth.ResendCodeRequest(phone, phone_hash))
except errors.PhoneCodeExpiredError:
if _retry_count > 2:
raise
self._phone_code_hash.pop(phone, None)
self._log[__name__].info(
"Phone code expired in ResendCodeRequest, requesting a new code"
)
return await self.send_code_request(
phone, force_sms=False, _retry_count=_retry_count+1)
if isinstance(result, types.auth.SentCodeSuccess):
raise RuntimeError('logged in right after resending the code')
self._phone_code_hash[phone] = result.phone_code_hash
return result
async def qr_login(self: 'TelegramClient', ignored_ids: typing.List[int] = None) -> custom.QRLogin: