Ejemplo n.º 1
0
    async def start_pan_client(self, access_token, user, user_id, password):
        client = ClientInfo(user_id, access_token)
        self.client_info[access_token] = client
        self.store.save_server_user(self.name, user_id)

        if user_id in self.pan_clients:
            logger.info(
                f"Background sync client already exists for {user_id},"
                f" not starting new one"
            )
            return

        pan_client = PanClient(
            self.name,
            self.store,
            self.conf,
            self.homeserver_url,
            self.send_queue,
            user_id,
            store_path=self.data_dir,
            ssl=self.ssl,
            proxy=self.proxy,
            store_class=self.client_store_class,
            media_info=self.media_info,
        )
        response = await pan_client.login(password, "pantalaimon")

        if not isinstance(response, LoginResponse):
            await pan_client.close()
            return

        logger.info(f"Succesfully started new background sync client for " f"{user_id}")

        await self.send_ui_message(
            UpdateUsersMessage(self.name, user_id, pan_client.device_id)
        )

        self.pan_clients[user_id] = pan_client

        if self.conf.keyring:
            try:
                keyring.set_password(
                    "pantalaimon",
                    f"{user_id}-{pan_client.device_id}-token",
                    pan_client.access_token,
                )
            except RuntimeError as e:
                logger.error(e)
        else:
            self.store.save_access_token(
                user_id, pan_client.device_id, pan_client.access_token
            )

        pan_client.start_loop()
Ejemplo n.º 2
0
    def __attrs_post_init__(self):
        loop = asyncio.get_event_loop()

        self.homeserver_url = self.homeserver.geturl()
        self.hostname = self.homeserver.hostname
        self.store = PanStore(self.data_dir)
        accounts = self.store.load_users(self.name)
        self.media_info = self.store.load_media(self.name)

        for user_id, device_id in accounts:
            if self.conf.keyring:
                try:
                    token = keyring.get_password(
                        "pantalaimon", f"{user_id}-{device_id}-token"
                    )
                except RuntimeError as e:
                    logger.error(e)
            else:
                token = self.store.load_access_token(user_id, device_id)

            if not token:
                logger.warn(
                    f"Not restoring client for {user_id} {device_id}, "
                    f"missing access token."
                )
                continue

            logger.info(f"Restoring client for {user_id} {device_id}")

            pan_client = PanClient(
                self.name,
                self.store,
                self.conf,
                self.homeserver_url,
                self.send_queue,
                user_id,
                device_id,
                store_path=self.data_dir,
                ssl=self.ssl,
                proxy=self.proxy,
                store_class=self.client_store_class,
                media_info=self.media_info,
            )
            pan_client.user_id = user_id
            pan_client.access_token = token
            pan_client.load_store()
            self.pan_clients[user_id] = pan_client

            loop.create_task(
                self.send_ui_message(
                    UpdateUsersMessage(self.name, user_id, pan_client.device_id)
                )
            )

            loop.create_task(pan_client.send_update_devices(pan_client.device_store))

            pan_client.start_loop()
Ejemplo n.º 3
0
async def client(tmpdir, loop):
    store = PanStore(tmpdir)
    queue = janus.Queue()
    conf = ServerConfig("example", "https://exapmle.org")
    conf.history_fetch_delay = 0.1

    store.save_server_user("example", "@example:example.org")

    pan_client = PanClient(
        "example",
        store,
        conf,
        "https://example.org",
        queue.async_q,
        "@example:example.org",
        "DEVICEID",
        tmpdir,
        store_class=SqliteStore,
    )

    yield pan_client

    await pan_client.close()
Ejemplo n.º 4
0
    async def start_pan_client(self,
                               access_token,
                               user,
                               user_id,
                               password,
                               device_id=None):
        client = ClientInfo(user_id, access_token)
        self.client_info[access_token] = client
        self.store.save_server_user(self.name, user_id)

        if user_id in self.pan_clients:
            logger.info(f"Background sync client already exists for {user_id},"
                        f" not starting new one")
            return

        pan_client = PanClient(
            self.name,
            self.store,
            self.conf,
            self.homeserver_url,
            self.send_queue,
            user_id,
            store_path=self.data_dir,
            ssl=self.ssl,
            proxy=self.proxy,
            store_class=self.client_store_class,
            media_info=self.media_info,
        )

        if password == "":
            if device_id is None:
                logger.warn(
                    "Empty password provided and device_id was also None, not "
                    "starting background sync client ")
                return
            # If password is blank, we cannot login normally and must
            # fall back to using the provided device_id.
            pan_client.restore_login(user_id, device_id, access_token)
        else:
            response = await pan_client.login(password, "pantalaimon")

            if not isinstance(response, LoginResponse):
                await pan_client.close()
                return

        logger.info(f"Succesfully started new background sync client for "
                    f"{user_id}")

        await self.send_ui_message(
            UpdateUsersMessage(self.name, user_id, pan_client.device_id))

        self.pan_clients[user_id] = pan_client

        if self.conf.keyring:
            try:
                keyring.set_password(
                    "pantalaimon",
                    f"{user_id}-{pan_client.device_id}-token",
                    pan_client.access_token,
                )
            except RuntimeError as e:
                logger.error(e)
        else:
            self.store.save_access_token(user_id, pan_client.device_id,
                                         pan_client.access_token)

        pan_client.start_loop()
Ejemplo n.º 5
0
    async def test_history_fetching_resume(self, client, aioresponse, loop):
        if not INDEXING_ENABLED:
            pytest.skip("Indexing needs to be enabled to test this")

        sync_url = re.compile(
            r"^https://example\.org/_matrix/client/r0/sync\?access_token=.*")

        aioresponse.get(
            sync_url,
            status=200,
            payload=self.initial_sync_response,
        )

        aioresponse.get(sync_url,
                        status=200,
                        payload=self.empty_sync,
                        repeat=True)

        aioresponse.post(
            "https://example.org/_matrix/client/r0/keys/upload?access_token=abc123",
            status=200,
            payload=self.keys_upload_response,
            repeat=True,
        )

        aioresponse.post(
            "https://example.org/_matrix/client/r0/keys/query?access_token=abc123",
            status=200,
            payload=self.keys_query_response,
            repeat=True,
        )

        messages_url = re.compile(
            r"^https://example\.org/_matrix/client/r0/rooms/{}/messages\?.*".
            format(TEST_ROOM_ID))

        aioresponse.get(messages_url,
                        status=200,
                        payload=self.messages_response)

        aioresponse.get(messages_url,
                        status=200,
                        payload=self.empty_messages,
                        repeat=True)

        await client.receive_response(self.login_response)

        client.start_loop(100)

        await client.new_fetch_task.wait()
        await client.new_fetch_task.wait()

        await client.loop_stop()

        index_path = os.path.join(client.store_path, client.server_name,
                                  client.user_id)

        # Remove the lock file since the GC won't do it for us
        writer_lock = os.path.join(index_path, ".tantivy-writer.lock")
        os.remove(writer_lock)

        # Create a new client
        client2 = PanClient(
            client.server_name,
            client.pan_store,
            client.pan_conf,
            client.homeserver,
            client.queue,
            client.user_id,
            client.device_id,
            client.store_path,
        )
        client2.user_id = client.user_id
        client2.access_token = client.access_token

        tasks = client2.pan_store.load_fetcher_tasks(client2.server_name,
                                                     client2.user_id)
        assert len(tasks) == 1

        # Check that the task is our end token from the messages resposne
        assert tasks[0].room_id == TEST_ROOM_ID
        assert tasks[0].token == "t47409-4357353_219380_26003_2265"

        client2.start_loop(100)

        # We wait for two events here because the event gets fired at the start
        # of the loop
        await client2.fetch_loop_event.wait()
        await client2.fetch_loop_event.wait()

        tasks = client2.pan_store.load_fetcher_tasks(client2.server_name,
                                                     client2.user_id)
        # Check that there are no more tasks since we reached the start of the
        # room timeline.
        assert not tasks

        await client2.loop_stop()