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()
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()
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()
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()
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()