diff --git a/mautrix_telegram/web/provisioning/__init__.py b/mautrix_telegram/web/provisioning/__init__.py index 1c609aaf..95919c58 100644 --- a/mautrix_telegram/web/provisioning/__init__.py +++ b/mautrix_telegram/web/provisioning/__init__.py @@ -31,6 +31,7 @@ class ProvisioningAPI(AuthAPI): self.app = web.Application(loop=loop) + self.app.router.add_route("GET", "/{mxid:@[^:]*:.+}/get_me", self.get_me) login_prefix = "/login/{mxid:@[^:]*:.+}" self.app.router.add_route("POST", f"{login_prefix}/bot_token", self.send_bot_token) self.app.router.add_route("POST", f"{login_prefix}/request_code", self.request_code) @@ -57,7 +58,7 @@ class ProvisioningAPI(AuthAPI): } return web.json_response(resp, status=status) - async def get_request_info(self, request: web.Request): + async def get_request_info(self, request: web.Request, get_data=True, fail_on_logged_in=True): auth = request.headers.get("Authorization", "") if auth != f"Bearer {self.secret}": return None, None, self.get_login_response(error="Shared secret is not valid.", @@ -65,23 +66,41 @@ class ProvisioningAPI(AuthAPI): status=401) data = None - try: - data = await request.json() - except json.JSONDecodeError: - pass - if not data: - return None, None, self.get_login_response(error="Invalid JSON.", - errcode="json_invalid", status=400) + if get_data: + try: + data = await request.json() + except json.JSONDecodeError: + pass + if not data: + return None, None, self.get_login_response(error="Invalid JSON.", + errcode="json_invalid", status=400) mxid = request.match_info["mxid"] user = await User.get_by_mxid(mxid).ensure_started(even_if_no_session=True) if not user.puppet_whitelisted: return None, user, self.get_login_response(error="You are not whitelisted.", errcode="mxid_not_whitelisted", status=403) - elif await user.is_logged_in(): + elif fail_on_logged_in and await user.is_logged_in(): return None, user, self.get_login_response(username=user.username, status=409) return data, user, None + async def get_me(self, request: web.Request): + data, user, err = await self.get_request_info(request, get_data=False, + fail_on_logged_in=False) + if err is not None: + return err + if not await user.is_logged_in(): + return self.get_login_response(status=403, error="You are not logged in.", + errcode="not_logged_in") + me = await user.client.get_me() + return web.json_response({ + "username": me.username, + "first_name": me.first_name, + "last_name": me.last_name, + "phone": me.phone, + "is_bot": me.bot, + }) + async def send_bot_token(self, request: web.Request): data, user, err = await self.get_request_info(request) if err is not None: diff --git a/mautrix_telegram/web/provisioning/spec.yaml b/mautrix_telegram/web/provisioning/spec.yaml index aa911d46..5766af2e 100644 --- a/mautrix_telegram/web/provisioning/spec.yaml +++ b/mautrix_telegram/web/provisioning/spec.yaml @@ -26,6 +26,51 @@ tags: - name: Authentication paths: + /{mxid}/get_me: + get: + operationId: get_me + summary: Get the info of the Telegram user the given Matrix user is logged in as + tags: [Authentication] + responses: + 200: + description: User is logged in + schema: + $ref: "#/definitions/AuthInfo" + 400: + $ref: "#/responses/MissingMXIDError" + 403: + description: User is not logged in or not whitelisted + schema: + type: object + title: Error + properties: + errcode: + type: string + title: Error code + description: A machine-readable error code + enum: + - not_logged_in + - mxid_not_whitelisted + error: + $ref: "#/definitions/HumanReadableError" + 500: + $ref: "#/responses/UnknownError" + parameters: + - name: mxid + in: path + description: The Matrix ID of the user who to log in as + required: true + type: string + - name: body + in: body + required: true + schema: + type: object + properties: + token: + type: string + description: The access token of the bot to log in as + example: "297900271:IXjeGEcAN61zHnjPgkWnYWyvVp9K4ulHBEv" /login/{mxid}/bot_token: post: operationId: post_bot_token @@ -388,6 +433,25 @@ definitions: type: string description: A human-readable description of the error example: A human-readable description of the error + AuthInfo: + type: object + properties: + username: + type: string + example: username + first_name: + type: string + example: Usern + last_name: + type: string + example: A. + phone: + type: string + example: +123456789 + is_bot: + type: boolean + example: false + AuthSuccess: type: object properties: