Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Client.get_authorizations method and accompanying types #4539

Open
wants to merge 1 commit into
base: v2
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion client/src/telethon/_impl/client/client/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
from ...session import DataCenter
from ...session import User as SessionUser
from ...tl import abcs, functions, types
from ..types import LoginToken, PasswordToken, User
from ..types import Authorizations, LoginToken, PasswordToken, User
from .net import connect_sender

if TYPE_CHECKING:
Expand Down Expand Up @@ -266,3 +266,15 @@ async def sign_out(self: Client) -> None:
self._session.user = None
self._session.state = None
await self._storage.save(self._session)


async def get_authorizations(self: Client) -> Optional[Authorizations]:
try:
result = await self(functions.account.get_authorizations())
except RpcError as e:
if e.code == 401:
return None
else:
raise

return Authorizations._from_raw(self, result)
21 changes: 21 additions & 0 deletions client/src/telethon/_impl/client/client/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@
AdminRight,
AlbumBuilder,
AsyncList,
Authorizations,
Channel,
ChatRestriction,
Dialog,
Expand All @@ -51,6 +52,7 @@
from .auth import (
bot_sign_in,
check_password,
get_authorizations,
interactive_login,
is_authorized,
request_login_code,
Expand Down Expand Up @@ -681,6 +683,25 @@ def get_admin_log(
"""
return get_admin_log(self, chat)

async def get_authorizations(self) -> Optional[Authorizations]:
"""
Gets all current authorizations (sessions) of the logged in user.

:return:
The authorizations (sessions) associated with the logged-in account, or :data:`None` if the client is not authorized.

.. rubric:: Example

.. code-block:: python

authorizations = await client.get_authorizations()
assert authorizations is not None, "not logged in!"

for auth in authorizations.sessions:
print(auth.device_model, auth.platform, auth.app_name)
"""
return await get_authorizations(self)

def get_contacts(self) -> AsyncList[User]:
"""
Get the users in your contact list.
Expand Down
1 change: 1 addition & 0 deletions client/src/telethon/_impl/client/types/__init__.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from .admin_right import AdminRight
from .album_builder import AlbumBuilder
from .async_list import AsyncList
from .authorizations import Authorizations, Authorization
from .callback_answer import CallbackAnswer
from .chat_restriction import ChatRestriction
from .dialog import Dialog
Expand Down
144 changes: 144 additions & 0 deletions client/src/telethon/_impl/client/types/authorizations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
from __future__ import annotations

from typing import TYPE_CHECKING, List, Optional

from typing_extensions import Self

from ...tl import abcs
from .meta import NoPublicConstructor

if TYPE_CHECKING:
from ..client.client import Client


class Authorizations(metaclass=NoPublicConstructor):
"""
Authorizations, logged in sessions.

You can get a user's authorizations from methods such as :meth:`telethon.Client.get_authorizations`.
"""

def __init__(
self,
client: Client,
raw: abcs.account.Authorizations,
) -> None:
assert isinstance(raw, abcs.account.Authorizations)
self._client = client
self._raw = raw
self._authorizations = [Authorization._from_raw(client, auth) for auth in self._raw.authorizations]

@classmethod
def _from_raw(
cls,
client: Client,
authorizations: abcs.account.Authorizations,
) -> Self:
return cls._create(client, authorizations)

@property
def ttl_days(self) -> int:
return self._raw.authorization_ttl_days

@property
def sessions(self) -> List[abcs.Authorization]:
return self._authorizations


class Authorization(metaclass=NoPublicConstructor):
"""
A single authorization.

This will only be constructed as part of :meth:`telethon.Client.get_authorizations`.
"""

def __init__(
self,
client: Client,
raw: abcs.Authorization,
) -> None:
assert isinstance(raw, abcs.Authorization)
self._client = client
self._raw = raw

@classmethod
def _from_raw(
cls,
client: Client,
authorization: abcs.Authorization,
) -> Self:
return cls._create(client, authorization)

@property
def api_id(self) -> int:
return self._raw.api_id

@property
def app_name(self) -> str:
return self._raw.app_name

@property
def app_version(self) -> str:
return self._raw.app_version

@property
def call_requests_disabled(self) -> bool:
return self._raw.call_requests_disabled

@property
def country(self) -> str:
return self._raw.country

@property
def current(self) -> bool:
return self._raw.current

@property
def date_active(self) -> int:
return self._raw.date_active

@property
def date_created(self) -> int:
return self._raw.date_created

@property
def device_model(self) -> str:
return self._raw.device_model

@property
def encrypted_requests_disabled(self) -> bool:
return self._raw.encrypted_requests_disabled

@property
def hash(self) -> int:
return self._raw.hash

@property
def ip(self) -> Optional[str]:
if self._raw.ip == '':
return None
return self._raw.ip

@property
def official_app(self) -> bool:
return self._raw.official_app

@property
def password_pending(self) -> bool:
return self._raw.password_pending

@property
def platform(self) -> str:
return self._raw.platform

@property
def region(self) -> str:
return self._raw.region

@property
def system_version(self) -> str:
return self._raw.system_version

@property
def unconfirmed(self) -> bool:
return self._raw.unconfirmed