Skip to content

Commit

Permalink
daemon: Ask the homeserver about unknown access tokens.
Browse files Browse the repository at this point in the history
This patch changes the way clients register to pantalaimon. If there is
already a pan client running for a given user ID clients can now avoid
logging in.

Pantalaimon checks with the homeserver if the access token
is valid and for a user that we already have a pan client running.

This also removes the need to remember access tokens that don't belong
to a pan client.

This partially fixes #14.
  • Loading branch information
poljar committed May 21, 2019
1 parent a6bc5de commit 3d87b46
Showing 1 changed file with 52 additions and 16 deletions.
68 changes: 52 additions & 16 deletions pantalaimon/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,8 @@
from aiohttp import ClientSession, web
from aiohttp.client_exceptions import ClientConnectionError, ContentTypeError
from multidict import CIMultiDict
from nio import EncryptionError, LoginResponse, SendRetryError, OlmTrustError
from nio import (EncryptionError, LoginResponse, SendRetryError, OlmTrustError,
Api)

from pantalaimon.client import PanClient
from pantalaimon.log import logger
Expand Down Expand Up @@ -61,8 +62,6 @@ def __attrs_post_init__(self):
self.store = PanStore(self.data_dir)
accounts = self.store.load_users(self.name)

self.client_info = self.store.load_clients(self.name)

for user_id, device_id in accounts:
token = keyring.get_password(
"pantalaimon",
Expand Down Expand Up @@ -92,6 +91,50 @@ def __attrs_post_init__(self):

pan_client.start_loop()

async def _find_client(self, access_token):
client_info = self.client_info.get(access_token, None)

if not client_info:
async with aiohttp.ClientSession() as session:
try:
method, path = Api.whoami(access_token)
resp = await session.request(
method,
self.homeserver_url + path,
proxy=self.proxy,
ssl=self.ssl
)
except ClientConnectionError:
return None

if resp.status != 200:
return None

try:
body = await resp.json()
except (JSONDecodeError, ContentTypeError):
return None

try:
user_id = body["user_id"]
except KeyError:
return None

if user_id not in self.pan_clients:
logger.warn(f"User {user_id} doesn't have a matching pan "
f"client.")
return None

logger.info(f"Homeserver confirmed valid access token "
f"for user {user_id}, caching info.")

client_info = ClientInfo(user_id, access_token)
self.client_info[access_token] = client_info

client = self.pan_clients.get(client_info.user_id, None)

return client

async def _verify_device(self, message_id, client, device):
ret = client.verify_device(device)

Expand Down Expand Up @@ -424,7 +467,6 @@ def _get_login_user(self, body):
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_client(self.name, client)
self.store.save_server_user(self.name, user_id)

if user_id in self.pan_clients:
Expand Down Expand Up @@ -578,10 +620,8 @@ async def sync(self, request):
if not access_token:
return self._missing_token

try:
client_info = self.client_info[access_token]
client = self.pan_clients[client_info.user_id]
except KeyError:
client = await self._find_client(access_token)
if not client:
return self._unknown_token

sync_filter = request.query.get("filter", None)
Expand Down Expand Up @@ -631,10 +671,8 @@ async def messages(self, request):
if not access_token:
return self._missing_token

try:
client_info = self.client_info[access_token]
client = self.pan_clients[client_info.user_id]
except KeyError:
client = await self._find_client(access_token)
if not client:
return self._unknown_token

try:
Expand Down Expand Up @@ -670,10 +708,8 @@ async def send_message(self, request):
if not access_token:
return self._missing_token

try:
client_info = self.client_info[access_token]
client = self.pan_clients[client_info.user_id]
except KeyError:
client = await self._find_client(access_token)
if not client:
return self._unknown_token

room_id = request.match_info["room_id"]
Expand Down

0 comments on commit 3d87b46

Please sign in to comment.