Even more migrations to mautrix-python
This commit is contained in:
@@ -13,27 +13,30 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from abc import abstractmethod
|
||||
from typing import Optional
|
||||
|
||||
from aiohttp import web
|
||||
from abc import abstractmethod
|
||||
import abc
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from aiohttp import web
|
||||
|
||||
from telethon.errors import *
|
||||
|
||||
from mautrix.bridge import OnlyLoginSelf, InvalidAccessToken
|
||||
|
||||
from ...commands.telegram.auth import enter_password
|
||||
from ...util import format_duration, ignore_coro
|
||||
from ...puppet import Puppet, PuppetError
|
||||
from ...puppet import Puppet
|
||||
from ...user import User
|
||||
|
||||
|
||||
class AuthAPI(abc.ABC):
|
||||
log = logging.getLogger("mau.web.auth") # type: logging.Logger
|
||||
log: logging.Logger = logging.getLogger("mau.web.auth")
|
||||
loop: asyncio.AbstractEventLoop
|
||||
|
||||
def __init__(self, loop: asyncio.AbstractEventLoop):
|
||||
self.loop = loop # type: asyncio.AbstractEventLoop
|
||||
self.loop = loop
|
||||
|
||||
@abstractmethod
|
||||
def get_login_response(self, status: int = 200, state: str = "", username: str = "",
|
||||
@@ -55,15 +58,14 @@ class AuthAPI(abc.ABC):
|
||||
error="You have already logged in with your Matrix "
|
||||
"account.", errcode="already-logged-in")
|
||||
|
||||
resp = await puppet.switch_mxid(token.strip(), user.mxid)
|
||||
if resp == PuppetError.OnlyLoginSelf:
|
||||
try:
|
||||
await puppet.switch_mxid(token.strip(), user.mxid)
|
||||
except OnlyLoginSelf:
|
||||
return self.get_mx_login_response(status=403, errcode="only-login-self",
|
||||
error="You can only log in as your own Matrix user.")
|
||||
elif resp == PuppetError.InvalidAccessToken:
|
||||
except InvalidAccessToken:
|
||||
return self.get_mx_login_response(status=401, errcode="invalid-access-token",
|
||||
error="Failed to verify access token.")
|
||||
assert resp == PuppetError.Success, "Encountered an unhandled PuppetError."
|
||||
|
||||
return self.get_mx_login_response(mxid=user.mxid, status=200, state="logged-in")
|
||||
|
||||
async def post_matrix_password(self, user: User, password: str) -> web.Response:
|
||||
|
||||
@@ -13,17 +13,21 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from aiohttp import web
|
||||
from typing import Awaitable, Callable, Dict, Optional, Tuple, TYPE_CHECKING
|
||||
import asyncio
|
||||
import logging
|
||||
import json
|
||||
|
||||
from aiohttp import web
|
||||
|
||||
from telethon.utils import get_peer_id, resolve_id
|
||||
from telethon.tl.types import ChatForbidden, ChannelForbidden, TypeChat
|
||||
from mautrix_appservice import AppService, MatrixRequestError, IntentError
|
||||
|
||||
from ...types import MatrixUserID, TelegramID
|
||||
from mautrix.appservice import AppService
|
||||
from mautrix.errors import MatrixRequestError, IntentError
|
||||
from mautrix.types import UserID
|
||||
|
||||
from ...types import TelegramID
|
||||
from ...user import User
|
||||
from ...portal import Portal
|
||||
from ...util import ignore_coro
|
||||
@@ -35,16 +39,19 @@ if TYPE_CHECKING:
|
||||
|
||||
|
||||
class ProvisioningAPI(AuthAPI):
|
||||
log = logging.getLogger("mau.web.provisioning") # type: logging.Logger
|
||||
log: logging.Logger = logging.getLogger("mau.web.provisioning")
|
||||
secret: str
|
||||
az: AppService
|
||||
context: 'Context'
|
||||
app: web.Application
|
||||
|
||||
def __init__(self, context: "Context") -> None:
|
||||
super().__init__(context.loop)
|
||||
self.secret = context.config["appservice.provisioning.shared_secret"] # type: str
|
||||
self.az = context.az # type: AppService
|
||||
self.context = context # type: Context
|
||||
self.secret = context.config["appservice.provisioning.shared_secret"]
|
||||
self.az = context.az
|
||||
self.context = context
|
||||
|
||||
self.app = web.Application(loop=context.loop, middlewares=[self.error_middleware]
|
||||
) # type: web.Application
|
||||
self.app = web.Application(loop=context.loop, middlewares=[self.error_middleware])
|
||||
|
||||
portal_prefix = "/portal/{mxid:![^/]+}"
|
||||
self.app.router.add_route("GET", f"{portal_prefix}", self.get_portal_by_mxid)
|
||||
@@ -76,18 +83,7 @@ class ProvisioningAPI(AuthAPI):
|
||||
if not portal:
|
||||
return self.get_error_response(404, "portal_not_found",
|
||||
"Portal with given Matrix ID not found.")
|
||||
user, _ = await self.get_user(request.query.get("user_id", None), expect_logged_in=None,
|
||||
require_puppeting=False)
|
||||
return web.json_response({
|
||||
"mxid": portal.mxid,
|
||||
"chat_id": get_peer_id(portal.peer),
|
||||
"peer_type": portal.peer_type,
|
||||
"title": portal.title,
|
||||
"about": portal.about,
|
||||
"username": portal.username,
|
||||
"megagroup": portal.megagroup,
|
||||
"can_unbridge": (await portal.can_user_perform(user, "unbridge")) if user else False,
|
||||
})
|
||||
return await self._get_portal_response(UserID(request.query.get("user_id", "")), portal)
|
||||
|
||||
async def get_portal_by_tgid(self, request: web.Request) -> web.Response:
|
||||
err = self.check_authorization(request)
|
||||
@@ -103,8 +99,10 @@ class ProvisioningAPI(AuthAPI):
|
||||
if not portal:
|
||||
return self.get_error_response(404, "portal_not_found",
|
||||
"Portal to given Telegram chat not found.")
|
||||
user, _ = await self.get_user(request.query.get("user_id", None), expect_logged_in=None,
|
||||
require_puppeting=False)
|
||||
return await self._get_portal_response(UserID(request.query.get("user_id", "")), portal)
|
||||
|
||||
async def _get_portal_response(self, user_id: UserID, portal: Portal) -> web.Response:
|
||||
user, _ = await self.get_user(user_id, expect_logged_in=None, require_puppeting=False)
|
||||
return web.json_response({
|
||||
"mxid": portal.mxid,
|
||||
"chat_id": get_peer_id(portal.peer),
|
||||
@@ -364,7 +362,8 @@ class ProvisioningAPI(AuthAPI):
|
||||
|
||||
async def bridge_info(self, request: web.Request) -> web.Response:
|
||||
return web.json_response({
|
||||
"relaybot_username": self.context.bot.username if self.context.bot is not None else None,
|
||||
"relaybot_username": (self.context.bot.username
|
||||
if self.context.bot is not None else None),
|
||||
}, status=200)
|
||||
|
||||
@staticmethod
|
||||
@@ -430,7 +429,7 @@ class ProvisioningAPI(AuthAPI):
|
||||
except json.JSONDecodeError:
|
||||
return None
|
||||
|
||||
async def get_user(self, mxid: MatrixUserID, expect_logged_in: Optional[bool] = False,
|
||||
async def get_user(self, mxid: Optional[UserID], expect_logged_in: Optional[bool] = False,
|
||||
require_puppeting: bool = True, require_user: bool = True
|
||||
) -> Tuple[Optional[User], Optional[web.Response]]:
|
||||
if not mxid:
|
||||
@@ -459,8 +458,7 @@ class ProvisioningAPI(AuthAPI):
|
||||
expect_logged_in: Optional[bool] = False,
|
||||
require_puppeting: bool = False,
|
||||
want_data: bool = True,
|
||||
) -> (Tuple[Optional[Dict],
|
||||
Optional[User],
|
||||
) -> (Tuple[Optional[Dict], Optional[User],
|
||||
Optional[web.Response]]):
|
||||
err = self.check_authorization(request)
|
||||
if err is not None:
|
||||
|
||||
@@ -14,16 +14,18 @@
|
||||
# You should have received a copy of the GNU Affero General Public License
|
||||
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
from typing import Optional
|
||||
from aiohttp import web
|
||||
from mako.template import Template
|
||||
import pkg_resources
|
||||
import asyncio
|
||||
import logging
|
||||
import random
|
||||
import string
|
||||
import time
|
||||
|
||||
from ...types import MatrixUserID
|
||||
from mako.template import Template
|
||||
from aiohttp import web
|
||||
import pkg_resources
|
||||
|
||||
from mautrix.types import UserID
|
||||
|
||||
from ...util import sign_token, verify_token
|
||||
from ...user import User
|
||||
from ...puppet import Puppet
|
||||
@@ -31,20 +33,23 @@ from ..common import AuthAPI
|
||||
|
||||
|
||||
class PublicBridgeWebsite(AuthAPI):
|
||||
log = logging.getLogger("mau.web.public") # type: logging.Logger
|
||||
log: logging.Logger = logging.getLogger("mau.web.public")
|
||||
secret_key: str
|
||||
login: Template
|
||||
mx_login: Template
|
||||
app: web.Application
|
||||
|
||||
def __init__(self, loop: asyncio.AbstractEventLoop):
|
||||
super().__init__(loop)
|
||||
self.secret_key = "".join(
|
||||
random.choice(string.ascii_lowercase + string.digits) for _ in range(64)) # type: str
|
||||
self.secret_key = "".join(random.choices(string.ascii_lowercase + string.digits, k=64))
|
||||
|
||||
self.login = Template(pkg_resources.resource_string(
|
||||
"mautrix_telegram", "web/public/login.html.mako")) # type: Template
|
||||
"mautrix_telegram", "web/public/login.html.mako"))
|
||||
|
||||
self.mx_login = Template(pkg_resources.resource_string(
|
||||
"mautrix_telegram", "web/public/matrix-login.html.mako")) # type: Template
|
||||
"mautrix_telegram", "web/public/matrix-login.html.mako"))
|
||||
|
||||
self.app = web.Application(loop=loop) # type: web.Application
|
||||
self.app = web.Application(loop=loop)
|
||||
self.app.router.add_route("GET", "/login", self.get_login)
|
||||
self.app.router.add_route("POST", "/login", self.post_login)
|
||||
self.app.router.add_route("GET", "/matrix-login", self.get_matrix_login)
|
||||
@@ -59,11 +64,11 @@ class PublicBridgeWebsite(AuthAPI):
|
||||
"expiry": int(time.time()) + expires_in,
|
||||
})
|
||||
|
||||
def verify_token(self, token: str, endpoint: str = "/login") -> Optional[MatrixUserID]:
|
||||
def verify_token(self, token: str, endpoint: str = "/login") -> Optional[UserID]:
|
||||
token = verify_token(self.secret_key, token)
|
||||
if token and (token.get("expiry", 0) > int(time.time()) and
|
||||
token.get("endpoint", None) == endpoint):
|
||||
return MatrixUserID(token.get("mxid", None))
|
||||
return UserID(token.get("mxid", None))
|
||||
return None
|
||||
|
||||
async def get_login(self, request: web.Request) -> web.Response:
|
||||
|
||||
Reference in New Issue
Block a user