mirror of
https://github.com/LonamiWebs/Telethon.git
synced 2025-07-10 16:12:22 +03:00
Remove phone and hash from sign in
This commit is contained in:
parent
df0e710fa1
commit
90bd5de74a
|
@ -978,3 +978,7 @@ todo update send_message and send_file docs (well review all functions)
|
||||||
album overhaul. use a list of Message instead.
|
album overhaul. use a list of Message instead.
|
||||||
|
|
||||||
is_connected is now a property (consistent with the rest of ``is_`` properties)
|
is_connected is now a property (consistent with the rest of ``is_`` properties)
|
||||||
|
|
||||||
|
send_code_request now returns a custom type (reducing raw api).
|
||||||
|
sign_in no longer has phone or phone_hash (these are impl details, and now it's less error prone). also mandatory code=. also no longer is a no-op if already logged in. different error for sign up required.
|
||||||
|
send code / sign in now only expect a single phone. resend code with new phone is send code, not resend.
|
||||||
|
|
|
@ -196,43 +196,22 @@ async def _start(
|
||||||
|
|
||||||
return self
|
return self
|
||||||
|
|
||||||
def _parse_phone_and_hash(self, phone, phone_hash):
|
|
||||||
"""
|
|
||||||
Helper method to both parse and validate phone and its hash.
|
|
||||||
"""
|
|
||||||
phone = utils.parse_phone(phone) or self._phone
|
|
||||||
if not phone:
|
|
||||||
raise ValueError(
|
|
||||||
'Please make sure to call send_code_request first.'
|
|
||||||
)
|
|
||||||
|
|
||||||
phone_hash = phone_hash or self._phone_code_hash.get(phone, None)
|
|
||||||
if not phone_hash:
|
|
||||||
raise ValueError('You also need to provide a phone_code_hash.')
|
|
||||||
|
|
||||||
return phone, phone_hash
|
|
||||||
|
|
||||||
async def sign_in(
|
async def sign_in(
|
||||||
self: 'TelegramClient',
|
self: 'TelegramClient',
|
||||||
phone: str = None,
|
|
||||||
code: typing.Union[str, int] = None,
|
|
||||||
*,
|
*,
|
||||||
|
code: typing.Union[str, int] = None,
|
||||||
password: str = None,
|
password: str = None,
|
||||||
bot_token: str = None,
|
bot_token: str = None,) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
||||||
phone_code_hash: str = None) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
if code:
|
||||||
me = await self.get_me()
|
if not self._phone_code_hash:
|
||||||
if me:
|
raise ValueError('Must call client.send_code_request before sign in')
|
||||||
return me
|
|
||||||
|
|
||||||
if phone and code:
|
phone, phone_code_hash = self._phone_code_hash
|
||||||
phone, phone_code_hash = \
|
|
||||||
_parse_phone_and_hash(self, phone, phone_code_hash)
|
|
||||||
|
|
||||||
# May raise PhoneCodeEmptyError, PhoneCodeExpiredError,
|
# May raise PhoneCodeEmptyError, PhoneCodeExpiredError,
|
||||||
# PhoneCodeHashEmptyError or PhoneCodeInvalidError.
|
# PhoneCodeHashEmptyError or PhoneCodeInvalidError.
|
||||||
request = _tl.fn.auth.SignIn(
|
request = _tl.fn.auth.SignIn(*self._phone_code_hash, str(code))
|
||||||
phone, phone_code_hash, str(code)
|
|
||||||
)
|
|
||||||
elif password:
|
elif password:
|
||||||
pwd = await self(_tl.fn.account.GetPassword())
|
pwd = await self(_tl.fn.account.GetPassword())
|
||||||
request = _tl.fn.auth.CheckPassword(
|
request = _tl.fn.auth.CheckPassword(
|
||||||
|
@ -244,13 +223,13 @@ async def sign_in(
|
||||||
api_id=self._api_id, api_hash=self._api_hash
|
api_id=self._api_id, api_hash=self._api_hash
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
raise ValueError('You must provide either phone and code, password, or bot_token.')
|
raise ValueError('You must provide code, password, or bot_token.')
|
||||||
|
|
||||||
result = await self(request)
|
result = await self(request)
|
||||||
if isinstance(result, _tl.auth.AuthorizationSignUpRequired):
|
if isinstance(result, _tl.auth.AuthorizationSignUpRequired):
|
||||||
# Emulate pre-layer 104 behaviour
|
# The method must return the User but we don't have it, so raise instead (matches pre-layer 104 behaviour)
|
||||||
self._tos = result.terms_of_service
|
self._tos = result.terms_of_service
|
||||||
raise errors.PhoneNumberUnoccupiedError(request=request)
|
raise errors.SignUpRequired()
|
||||||
|
|
||||||
return await _update_session_state(self, result.user)
|
return await _update_session_state(self, result.user)
|
||||||
|
|
||||||
|
@ -287,8 +266,10 @@ async def sign_up(
|
||||||
sys.stderr.write("{}\n".format(self._tos.text))
|
sys.stderr.write("{}\n".format(self._tos.text))
|
||||||
sys.stderr.flush()
|
sys.stderr.flush()
|
||||||
|
|
||||||
phone, phone_code_hash = \
|
if not self._phone_code_hash:
|
||||||
_parse_phone_and_hash(self, phone, phone_code_hash)
|
raise ValueError('Must call client.send_code_request before sign up')
|
||||||
|
|
||||||
|
phone, phone_code_hash = self._phone_code_hash
|
||||||
|
|
||||||
result = await self(_tl.fn.auth.SignUp(
|
result = await self(_tl.fn.auth.SignUp(
|
||||||
phone_number=phone,
|
phone_number=phone,
|
||||||
|
@ -321,6 +302,7 @@ async def _update_session_state(self, user, save=True):
|
||||||
seq=state.seq,
|
seq=state.seq,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
self._phone_code_hash = None
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
|
@ -336,15 +318,10 @@ async def _replace_session_state(self, *, save=True, **changes):
|
||||||
async def send_code_request(
|
async def send_code_request(
|
||||||
self: 'TelegramClient',
|
self: 'TelegramClient',
|
||||||
phone: str) -> 'SentCode':
|
phone: str) -> 'SentCode':
|
||||||
result = None
|
phone = utils.parse_phone(phone)
|
||||||
phone = utils.parse_phone(phone) or self._phone
|
|
||||||
phone_hash = self._phone_code_hash.get(phone)
|
|
||||||
|
|
||||||
if phone_hash:
|
if self._phone_code_hash and phone == self._phone_code_hash[0]:
|
||||||
result = await self(
|
result = await self(_tl.fn.auth.ResendCode(*self._phone_code_hash))
|
||||||
_tl.fn.auth.ResendCode(phone, phone_hash))
|
|
||||||
|
|
||||||
self._phone_code_hash[phone] = result.phone_code_hash
|
|
||||||
else:
|
else:
|
||||||
try:
|
try:
|
||||||
result = await self(_tl.fn.auth.SendCode(
|
result = await self(_tl.fn.auth.SendCode(
|
||||||
|
@ -353,13 +330,14 @@ async def send_code_request(
|
||||||
return await self.send_code_request(phone)
|
return await self.send_code_request(phone)
|
||||||
|
|
||||||
# phone_code_hash may be empty, if it is, do not save it (#1283)
|
# phone_code_hash may be empty, if it is, do not save it (#1283)
|
||||||
if result.phone_code_hash:
|
if not result.phone_code_hash:
|
||||||
self._phone_code_hash[phone] = phone_hash = result.phone_code_hash
|
# The hash is required to login, so this pretty much means send code failed
|
||||||
|
raise ValueError('Failed to send code')
|
||||||
self._phone = phone
|
|
||||||
|
|
||||||
|
self._phone_code_hash = (phone, result.phone_code_hash)
|
||||||
return _custom.SentCode._new(result)
|
return _custom.SentCode._new(result)
|
||||||
|
|
||||||
|
|
||||||
async def qr_login(self: 'TelegramClient', ignored_ids: typing.List[int] = None) -> _custom.QRLogin:
|
async def qr_login(self: 'TelegramClient', ignored_ids: typing.List[int] = None) -> _custom.QRLogin:
|
||||||
qr_login = _custom.QRLogin(self, ignored_ids or [])
|
qr_login = _custom.QRLogin(self, ignored_ids or [])
|
||||||
await qr_login.recreate()
|
await qr_login.recreate()
|
||||||
|
|
|
@ -141,7 +141,7 @@ def init(
|
||||||
self._connect_timeout = connect_timeout
|
self._connect_timeout = connect_timeout
|
||||||
self.flood_sleep_threshold = flood_sleep_threshold
|
self.flood_sleep_threshold = flood_sleep_threshold
|
||||||
self._flood_waited_requests = {} # prevent calls that would floodwait entirely
|
self._flood_waited_requests = {} # prevent calls that would floodwait entirely
|
||||||
self._phone_code_hash = {} # used during login to prevent exposing the hash to end users
|
self._phone_code_hash = None # used during login to prevent exposing the hash to end users
|
||||||
|
|
||||||
# Update handling.
|
# Update handling.
|
||||||
self._catch_up = catch_up
|
self._catch_up = catch_up
|
||||||
|
|
|
@ -395,12 +395,10 @@ class TelegramClient:
|
||||||
@forward_call(auth.sign_in)
|
@forward_call(auth.sign_in)
|
||||||
async def sign_in(
|
async def sign_in(
|
||||||
self: 'TelegramClient',
|
self: 'TelegramClient',
|
||||||
phone: str = None,
|
|
||||||
code: typing.Union[str, int] = None,
|
|
||||||
*,
|
*,
|
||||||
|
code: typing.Union[str, int] = None,
|
||||||
password: str = None,
|
password: str = None,
|
||||||
bot_token: str = None,
|
bot_token: str = None) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
||||||
phone_code_hash: str = None) -> 'typing.Union[_tl.User, _tl.auth.SentCode]':
|
|
||||||
"""
|
"""
|
||||||
Logs in to Telegram to an existing user or bot account.
|
Logs in to Telegram to an existing user or bot account.
|
||||||
|
|
||||||
|
@ -411,16 +409,13 @@ class TelegramClient:
|
||||||
In most cases, you should simply use `start()` and not this method.
|
In most cases, you should simply use `start()` and not this method.
|
||||||
|
|
||||||
Arguments
|
Arguments
|
||||||
phone (`str` | `int`):
|
|
||||||
The phone to send the code to if no code was provided,
|
|
||||||
or to override the phone that was previously used with
|
|
||||||
these requests.
|
|
||||||
|
|
||||||
code (`str` | `int`):
|
code (`str` | `int`):
|
||||||
The code that Telegram sent. Note that if you have sent this
|
The code that Telegram sent.
|
||||||
code through the application itself it will immediately
|
|
||||||
expire. If you want to send the code, obfuscate it somehow.
|
To login to a user account, you must use `client.send_code_request` first.
|
||||||
If you're not doing any of this you can ignore this note.
|
|
||||||
|
The code will expire immediately if you send it through the application itself
|
||||||
|
as a safety measure.
|
||||||
|
|
||||||
password (`str`):
|
password (`str`):
|
||||||
2FA password, should be used if a previous call raised
|
2FA password, should be used if a previous call raised
|
||||||
|
@ -431,22 +426,19 @@ class TelegramClient:
|
||||||
This should be the hash the `@BotFather <https://t.me/BotFather>`_
|
This should be the hash the `@BotFather <https://t.me/BotFather>`_
|
||||||
gave you.
|
gave you.
|
||||||
|
|
||||||
phone_code_hash (`str`, optional):
|
You do not need to call `client.send_code_request` to login to a bot account.
|
||||||
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
|
Returns
|
||||||
The signed in user, or the information about
|
The signed in `User`, if the method did not fail.
|
||||||
:meth:`send_code_request`.
|
|
||||||
|
|
||||||
Example
|
Example
|
||||||
.. code-block:: python
|
.. code-block:: python
|
||||||
|
|
||||||
phone = '+34 123 123 123'
|
phone = '+34 123 123 123'
|
||||||
await client.sign_in(phone) # send code
|
await client.send_code_request(phone) # send code
|
||||||
|
|
||||||
code = input('enter code: ')
|
code = input('enter code: ')
|
||||||
await client.sign_in(phone, code)
|
await client.sign_in(code=code)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@forward_call(auth.sign_up)
|
@forward_call(auth.sign_up)
|
||||||
|
|
|
@ -7,6 +7,7 @@ from ._custom import (
|
||||||
CdnFileTamperedError,
|
CdnFileTamperedError,
|
||||||
BadMessageError,
|
BadMessageError,
|
||||||
MultiError,
|
MultiError,
|
||||||
|
SignUpRequired,
|
||||||
)
|
)
|
||||||
from ._rpcbase import (
|
from ._rpcbase import (
|
||||||
RpcError,
|
RpcError,
|
||||||
|
|
|
@ -150,3 +150,9 @@ class MultiError(Exception):
|
||||||
self.results = list(result)
|
self.results = list(result)
|
||||||
self.requests = list(requests)
|
self.requests = list(requests)
|
||||||
return self
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
class SignUpRequired(Exception):
|
||||||
|
"""
|
||||||
|
Occurs when trying to sign in with a phone number that doesn't have an account registered yet.
|
||||||
|
"""
|
||||||
|
|
Loading…
Reference in New Issue
Block a user