daemon: Save and restore daemon clients.

This commit is contained in:
Damir Jelić 2019-04-11 14:22:55 +02:00
parent 25f30f2e36
commit b1444568d4
2 changed files with 55 additions and 17 deletions

View File

@ -2,14 +2,15 @@ import asyncio
from pprint import pformat from pprint import pformat
from typing import Any, Dict from typing import Any, Dict
from nio import (AsyncClient, EncryptionError, GroupEncryptionError, from nio import (AsyncClient, ClientConfig, EncryptionError,
KeysQueryResponse, LocalProtocolError, MegolmEvent, GroupEncryptionError, KeysQueryResponse, MegolmEvent,
RoomEncryptedEvent, SyncResponse) RoomEncryptedEvent, SyncResponse)
from nio.store import SqliteStore
from pantalaimon.log import logger from pantalaimon.log import logger
class PantaClient(AsyncClient): class PanClient(AsyncClient):
"""A wrapper class around a nio AsyncClient extending its functionality.""" """A wrapper class around a nio AsyncClient extending its functionality."""
def __init__( def __init__(

View File

@ -17,8 +17,9 @@ from logbook import StderrHandler
from multidict import CIMultiDict from multidict import CIMultiDict
from nio import GroupEncryptionError, LoginResponse from nio import GroupEncryptionError, LoginResponse
from pantalaimon.client import PantaClient from pantalaimon.client import PanClient
from pantalaimon.log import logger from pantalaimon.log import logger
from pantalaimon.store import PanStore
@attr.s @attr.s
@ -34,13 +35,44 @@ class ProxyDaemon:
proxy = attr.ib(default=None) proxy = attr.ib(default=None)
ssl = attr.ib(default=None) ssl = attr.ib(default=None)
panta_clients = attr.ib(init=False, default=attr.Factory(dict)) store = attr.ib(type=PanStore, init=False)
pan_clients = attr.ib(init=False, default=attr.Factory(dict))
client_info = attr.ib( client_info = attr.ib(
init=False, init=False,
default=attr.Factory(dict), default=attr.Factory(dict),
type=dict type=dict
) )
default_session = attr.ib(init=False, default=None) default_session = attr.ib(init=False, default=None)
database_name = "pan.db"
def __attrs_post_init__(self):
self.store = PanStore(self.data_dir)
accounts = self.store.get_users()
for user_id, device_id in accounts:
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.homeserver,
user_id,
device_id,
store_path=self.data_dir,
ssl=self.ssl,
proxy=self.proxy
)
pan_client.user_id = user_id
pan_client.access_token = token
pan_client.load_store()
self.pan_clients[user_id] = pan_client
pan_client.start_loop()
def get_access_token(self, request): def get_access_token(self, request):
# type: (aiohttp.web.BaseRequest) -> str # type: (aiohttp.web.BaseRequest) -> str
@ -125,34 +157,39 @@ class ProxyDaemon:
return user return user
async def start_panta_client(self, access_token, user, user_id, password): async def start_pan_client(self, access_token, user, user_id, password):
client = Client(user_id, access_token) client = Client(user_id, access_token)
self.client_info[access_token] = client self.client_info[access_token] = client
if user_id in self.panta_clients: if user_id in self.pan_clients:
logger.info(f"Background sync client already exists for {user_id}," logger.info(f"Background sync client already exists for {user_id},"
f" not starting new one") f" not starting new one")
return return
panta_client = PantaClient( pan_client = PanClient(
self.homeserver, self.homeserver,
user, user,
store_path=self.data_dir, store_path=self.data_dir,
ssl=self.ssl, ssl=self.ssl,
proxy=self.proxy proxy=self.proxy
) )
response = await panta_client.login(password, "pantalaimon") response = await pan_client.login(password, "pantalaimon")
if not isinstance(response, LoginResponse): if not isinstance(response, LoginResponse):
await panta_client.close() await pan_client.close()
return return
logger.info(f"Succesfully started new background sync client for " logger.info(f"Succesfully started new background sync client for "
f"{user_id}") f"{user_id}")
self.panta_clients[user_id] = panta_client self.pan_clients[user_id] = pan_client
self.store.save_access_token(
user_id,
pan_client.device_id,
pan_client.access_token
)
panta_client.start_loop() pan_client.start_loop()
async def login(self, request): async def login(self, request):
try: try:
@ -194,8 +231,8 @@ class ProxyDaemon:
if user_id and access_token: if user_id and access_token:
logger.info(f"User: {user} succesfully logged in, starting " logger.info(f"User: {user} succesfully logged in, starting "
f"a background sync client.") f"a background sync client.")
await self.start_panta_client(access_token, user, user_id, await self.start_pan_client(access_token, user, user_id,
password) password)
return web.Response( return web.Response(
status=response.status, status=response.status,
@ -240,7 +277,7 @@ class ProxyDaemon:
try: try:
client_info = self.client_info[access_token] client_info = self.client_info[access_token]
client = self.panta_clients[client_info.user_id] client = self.pan_clients[client_info.user_id]
except KeyError: except KeyError:
return self._unknown_token return self._unknown_token
@ -295,7 +332,7 @@ class ProxyDaemon:
try: try:
client_info = self.client_info[access_token] client_info = self.client_info[access_token]
client = self.panta_clients[client_info.user_id] client = self.pan_clients[client_info.user_id]
except KeyError: except KeyError:
return self._unknown_token return self._unknown_token
@ -337,7 +374,7 @@ class ProxyDaemon:
This method is called when we shut the whole app down This method is called when we shut the whole app down
""" """
for client in self.panta_clients.values(): for client in self.pan_clients.values():
await client.loop_stop() await client.loop_stop()
await client.close() await client.close()