Beispiel #1
0
 async def on_logged_in(self, state: AndroidState) -> None:
     self.fbid = state.session.uid
     self.state = state
     self.client = AndroidAPI(state, log=self.log.getChild("api"))
     await self.save()
     self.stop_listen()
     asyncio.ensure_future(self.post_login(), loop=self.loop)
Beispiel #2
0
 async def load_session(self, _override: bool = False, _raise_errors: bool = False) -> bool:
     if self._is_logged_in and not _override:
         return True
     elif not self.state:
         return False
     attempt = 0
     client = AndroidAPI(self.state, log=self.log.getChild("api"))
     while True:
         try:
             user_info = await client.get_self()
             break
         except (ProxyError, ProxyTimeoutError, ProxyConnectionError, ConnectionError) as e:
             attempt += 1
             wait = min(attempt * 10, 60)
             self.log.warning(f"{e.__class__.__name__} while trying to restore session, "
                              f"retrying in {wait} seconds: {e}")
             await asyncio.sleep(wait)
         except Exception:
             self.log.exception("Failed to restore session")
             if _raise_errors:
                 raise
             return False
     if user_info:
         self.log.info("Loaded session successfully")
         self.client = client
         self._track_metric(METRIC_LOGGED_IN, True)
         self._is_logged_in = True
         self.is_connected = None
         self.stop_listen()
         asyncio.ensure_future(self.post_login(), loop=self.loop)
         return True
     return False
Beispiel #3
0
 async def login_prepare(self, request: web.Request) -> web.Response:
     user = await self.check_token(request)
     state = AndroidState()
     state.generate(user.mxid)
     api = AndroidAPI(state, log=user.log.getChild("login-api"))
     user.command_status = {
         "action": "Login",
         "state": state,
         "api": api,
     }
     try:
         await api.mobile_config_sessionless()
     except Exception as e:
         self.log.exception(
             "Failed to get mobile_config_sessionless to prepare login "
             f"for {user.mxid}")
         return web.json_response({"error": str(e)},
                                  headers=self._acao_headers)
     return web.json_response(
         {
             "status":
             "login",
             "password_encryption_key_id":
             state.session.password_encryption_key_id,
             "password_encryption_pubkey":
             state.session.password_encryption_pubkey
         },
         headers=self._acao_headers)
Beispiel #4
0
    async def login(self, request: web.Request) -> web.Response:
        user = await self.check_token(request)

        try:
            data = await request.json()
        except json.JSONDecodeError:
            raise web.HTTPBadRequest(text='{"error": "Malformed JSON"}', headers=self._headers)

        try:
            email = data["email"]
        except KeyError:
            raise web.HTTPBadRequest(text='{"error": "Missing email"}', headers=self._headers)
        try:
            password = data["password"]
            encrypted_password = None
        except KeyError:
            try:
                encrypted_password = data["encrypted_password"]
                password = None
            except KeyError:
                raise web.HTTPBadRequest(text='{"error": "Missing password"}',
                                         headers=self._headers)

        if encrypted_password:
            if not user.command_status or user.command_status["action"] != "Login":
                raise web.HTTPBadRequest(text='{"error": "No login in progress"}',
                                         headers=self._headers)
            state: AndroidState = user.command_status["state"]
            api: AndroidAPI = user.command_status["api"]
        else:
            state = AndroidState()
            state.generate(user.mxid)
            api = AndroidAPI(state, log=user.log.getChild("login-api"))
            await api.mobile_config_sessionless()

        try:
            await api.login(email, password=password, encrypted_password=encrypted_password)
            await user.on_logged_in(state)
            return web.json_response({"status": "logged-in"}, headers=self._acao_headers)
        except TwoFactorRequired as e:
            user.command_status = {
                "action": "Login",
                "state": state,
                "api": api,
            }
            return web.json_response({
                "status": "two-factor",
                "error": e.data,
            }, headers=self._acao_headers)
        except OAuthException as e:
            return web.json_response({"error": str(e)}, headers=self._acao_headers)
Beispiel #5
0
async def login(evt: CommandEvent) -> None:
    if len(evt.args) < 2:
        await evt.reply("Usage: `$cmdprefix+sp login <email> <password>`")
        return

    email, password = evt.args[0], " ".join(evt.args[1:])
    try:
        await evt.az.intent.redact(evt.room_id, evt.event_id)
    except MForbidden:
        pass

    if evt.sender.client:
        await evt.reply("You're already logged in")
        return

    state = AndroidState()
    state.generate(evt.sender.mxid)
    api = AndroidAPI(state, log=evt.sender.log.getChild("login-api"))
    try:
        await api.mobile_config_sessionless()
        await api.login(email, password)
        await evt.sender.on_logged_in(state)
        await evt.reply("Successfully logged in")
    except TwoFactorRequired:
        await evt.reply(
            "You have two-factor authentication turned on. Please either send the code"
            " from SMS or your authenticator app here, or approve the login from"
            " another device logged into Messenger.")
        checker_task = asyncio.create_task(
            check_approved_login(state, api, evt))
        evt.sender.command_status = {
            "action": "Login",
            "room_id": evt.room_id,
            "next": enter_2fa_code,
            "state": state,
            "api": api,
            "email": email,
            "checker_task": checker_task,
        }
    except OAuthException as e:
        await evt.reply(f"Error from Messenger:\n\n> {e}")
    except Exception as e:
        evt.log.exception("Failed to log in")
        evt.sender.command_status = None
        await evt.reply(f"Failed to log in: {e}")