mirror of
https://github.com/matrix-org/pantalaimon.git
synced 2024-10-01 03:35:38 -04:00
pan: Move the dbus code into a separate file.
This commit is contained in:
parent
7038462e01
commit
1613a2fa5a
@ -9,6 +9,7 @@ from nio import (AsyncClient, ClientConfig, EncryptionError,
|
||||
from nio.store import SqliteStore
|
||||
|
||||
from pantalaimon.log import logger
|
||||
from pantalaimon.ui import DevicesMessage
|
||||
|
||||
|
||||
class PanClient(AsyncClient):
|
||||
@ -17,6 +18,7 @@ class PanClient(AsyncClient):
|
||||
def __init__(
|
||||
self,
|
||||
homeserver,
|
||||
queue=None,
|
||||
user="",
|
||||
device_id="",
|
||||
store_path="",
|
||||
@ -29,6 +31,7 @@ class PanClient(AsyncClient):
|
||||
ssl, proxy)
|
||||
|
||||
self.task = None
|
||||
self.queue = queue
|
||||
self.loop_stopped = asyncio.Event()
|
||||
self.synced = asyncio.Event()
|
||||
|
||||
@ -78,6 +81,12 @@ class PanClient(AsyncClient):
|
||||
key_query_response = await self.keys_query()
|
||||
if isinstance(key_query_response, KeysQueryResponse):
|
||||
self.verify_devices(key_query_response.changed)
|
||||
message = DevicesMessage(
|
||||
self.user_id,
|
||||
self.device_id,
|
||||
key_query_response.changed
|
||||
)
|
||||
await self.queue.put(message)
|
||||
|
||||
if not isinstance(response, SyncResponse):
|
||||
# TODO error handling
|
||||
|
@ -4,27 +4,20 @@ import asyncio
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
from enum import Enum, auto
|
||||
from functools import partial
|
||||
from ipaddress import ip_address
|
||||
from json import JSONDecodeError
|
||||
from queue import Empty
|
||||
from urllib.parse import urlparse
|
||||
|
||||
import aiohttp
|
||||
import attr
|
||||
import click
|
||||
import dbus
|
||||
import dbus.exceptions
|
||||
import dbus.service
|
||||
import janus
|
||||
import keyring
|
||||
import logbook
|
||||
from aiohttp import ClientSession, web
|
||||
from aiohttp.client_exceptions import ContentTypeError
|
||||
from appdirs import user_data_dir
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GLib
|
||||
from logbook import StderrHandler
|
||||
from multidict import CIMultiDict
|
||||
from nio import EncryptionError, GroupEncryptionError, LoginResponse
|
||||
@ -32,69 +25,7 @@ from nio import EncryptionError, GroupEncryptionError, LoginResponse
|
||||
from pantalaimon.client import PanClient
|
||||
from pantalaimon.log import logger
|
||||
from pantalaimon.store import ClientInfo, PanStore
|
||||
|
||||
|
||||
class Tasks(Enum):
|
||||
shutdown = auto()
|
||||
|
||||
|
||||
class Devices(dbus.service.Object):
|
||||
def __init__(self, bus_name, device_list):
|
||||
super().__init__(bus_name, "/org/pantalaimon/Devices")
|
||||
self.device_list = device_list
|
||||
|
||||
@dbus.service.method("org.pantalaimon.devices.list",
|
||||
out_signature="a{sa{saa{ss}}}")
|
||||
def list(self):
|
||||
return self.device_list
|
||||
|
||||
|
||||
class Users(dbus.service.Object):
|
||||
def __init__(self, bus_name, user_list=None):
|
||||
super().__init__(bus_name, "/org/pantalaimon/Users")
|
||||
self.users = user_list
|
||||
|
||||
@dbus.service.method("org.pantalaimon.users.list",
|
||||
out_signature="a(ss)")
|
||||
def list(self):
|
||||
return self.users
|
||||
|
||||
|
||||
def dbus_loop(task_queue, data_dir):
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
loop = GLib.MainLoop()
|
||||
|
||||
bus_name = dbus.service.BusName("org.pantalaimon",
|
||||
bus=dbus.SessionBus(),
|
||||
do_not_queue=True)
|
||||
|
||||
store = PanStore(data_dir)
|
||||
users = store.load_all_users()
|
||||
devices = store.load_all_devices()
|
||||
|
||||
# TODO update bus data if the asyncio thread tells us so.
|
||||
Users(bus_name, users)
|
||||
Devices(bus_name, devices)
|
||||
|
||||
def task_callback():
|
||||
try:
|
||||
task = task_queue.get_nowait()
|
||||
except Empty:
|
||||
return True
|
||||
|
||||
if task == Tasks.shutdown:
|
||||
task_queue.task_done()
|
||||
loop.quit()
|
||||
return False
|
||||
|
||||
GLib.timeout_add(100, task_callback)
|
||||
|
||||
loop.run()
|
||||
|
||||
|
||||
async def shutdown_dbus(future, queue, app):
|
||||
await queue.put(Tasks.shutdown)
|
||||
await future
|
||||
from pantalaimon.ui import glib_loop, shutdown_glib_loop
|
||||
|
||||
|
||||
@attr.s
|
||||
@ -139,6 +70,7 @@ class ProxyDaemon:
|
||||
|
||||
pan_client = PanClient(
|
||||
self.homeserver_url,
|
||||
self.queue,
|
||||
user_id,
|
||||
device_id,
|
||||
store_path=self.data_dir,
|
||||
@ -248,6 +180,7 @@ class ProxyDaemon:
|
||||
|
||||
pan_client = PanClient(
|
||||
self.homeserver_url,
|
||||
self.queue,
|
||||
user,
|
||||
store_path=self.data_dir,
|
||||
ssl=self.ssl,
|
||||
@ -716,12 +649,12 @@ def start(
|
||||
))
|
||||
|
||||
data_dir = user_data_dir("pantalaimon", "")
|
||||
fut = loop.run_in_executor(None, dbus_loop, queue.sync_q, data_dir)
|
||||
fut = loop.run_in_executor(None, glib_loop, queue.sync_q, data_dir)
|
||||
|
||||
kill_dbus_loop = partial(shutdown_dbus, fut, queue.async_q)
|
||||
kill_glib = partial(shutdown_glib_loop, fut, queue.async_q)
|
||||
|
||||
app.on_shutdown.append(proxy.shutdown)
|
||||
app.on_shutdown.append(kill_dbus_loop)
|
||||
app.on_shutdown.append(kill_glib)
|
||||
|
||||
web.run_app(app, host=str(listen_address), port=listen_port)
|
||||
|
||||
|
@ -223,6 +223,9 @@ class PanStore:
|
||||
|
||||
for d in account.device_keys:
|
||||
|
||||
if d.deleted:
|
||||
continue
|
||||
|
||||
try:
|
||||
trust_state = d.trust_state[0].state
|
||||
except IndexError:
|
||||
|
152
pantalaimon/ui.py
Normal file
152
pantalaimon/ui.py
Normal file
@ -0,0 +1,152 @@
|
||||
import attr
|
||||
|
||||
import dbus
|
||||
import dbus.exceptions
|
||||
import dbus.service
|
||||
|
||||
from dbus.mainloop.glib import DBusGMainLoop
|
||||
from gi.repository import GLib
|
||||
|
||||
from queue import Empty
|
||||
|
||||
from nio.store import TrustState
|
||||
from pantalaimon.store import PanStore
|
||||
from pantalaimon.log import logger
|
||||
|
||||
|
||||
@attr.s
|
||||
class Message:
|
||||
pass
|
||||
|
||||
|
||||
@attr.s
|
||||
class ShutDownMessage(Message):
|
||||
pass
|
||||
|
||||
|
||||
@attr.s
|
||||
class DevicesMessage(Message):
|
||||
user_id = attr.ib()
|
||||
device_id = attr.ib()
|
||||
devices = attr.ib()
|
||||
|
||||
|
||||
@attr.s
|
||||
class DeviceVerifyMessage(Message):
|
||||
user_id = attr.ib()
|
||||
device_id = attr.ib()
|
||||
device_user = attr.ib()
|
||||
device_device_id = attr.ib()
|
||||
|
||||
|
||||
class Devices(dbus.service.Object):
|
||||
def __init__(self, bus_name, device_list):
|
||||
super().__init__(bus_name, "/org/pantalaimon/Devices")
|
||||
self.device_list = device_list
|
||||
|
||||
@dbus.service.method("org.pantalaimon.devices.list",
|
||||
out_signature="a{sa{saa{ss}}}")
|
||||
def list(self):
|
||||
return self.device_list
|
||||
|
||||
@dbus.service.method("org.pantalaimon.devices.verify",
|
||||
in_signature="ssss")
|
||||
def verify(self, user_id, device_id, devices_user, devices_id):
|
||||
device_store = self.device_list[user_id].get(device_id, None)
|
||||
|
||||
if not device_store:
|
||||
logger.debug(f"Not verifying device, no store found for user "
|
||||
f"{user_id}")
|
||||
return
|
||||
|
||||
logger.debug(f"Verifying device {devices_user} {devices_id}")
|
||||
return
|
||||
|
||||
@dbus.service.method("org.pantalaimon.devices.start_verification",
|
||||
in_signature="ssss")
|
||||
def start_verify(self, user_id, device_id, devices_user, devices_id):
|
||||
device_store = self.device_list[user_id].get(device_id, None)
|
||||
|
||||
if not device_store:
|
||||
logger.info(f"Not verifying device, no store found for user "
|
||||
f"{user_id}")
|
||||
return
|
||||
|
||||
logger.info(f"Verifying device {devices_user} {devices_id}")
|
||||
return
|
||||
|
||||
def update_devices(self, message):
|
||||
device_store = self.device_list[message.user_id][message.device_id]
|
||||
|
||||
for user_id, device_dict in message.devices.items():
|
||||
for device in device_dict.values():
|
||||
if device.deleted:
|
||||
device_store[user_id].pop(device.id, None)
|
||||
else:
|
||||
device_store[user_id][device.id] = {
|
||||
"user_id": device.user_id,
|
||||
"device_id": device.id,
|
||||
"fingerprint_key": device.ed25519,
|
||||
"sender_key": device.curve25519,
|
||||
"trust_state": TrustState.unset.name,
|
||||
}
|
||||
|
||||
|
||||
class Users(dbus.service.Object):
|
||||
def __init__(self, bus_name, user_list=None):
|
||||
super().__init__(bus_name, "/org/pantalaimon/Control")
|
||||
self.users = user_list
|
||||
|
||||
@dbus.service.method("org.pantalaimon.control.list_users",
|
||||
out_signature="a(ss)")
|
||||
def list(self):
|
||||
return self.users
|
||||
|
||||
@dbus.service.method("org.pantalaimon.control.export_keys",
|
||||
in_signature="ss")
|
||||
def export_keys(self, user, filepath):
|
||||
return
|
||||
|
||||
|
||||
def glib_loop(queue, data_dir):
|
||||
DBusGMainLoop(set_as_default=True)
|
||||
loop = GLib.MainLoop()
|
||||
|
||||
bus_name = dbus.service.BusName("org.pantalaimon",
|
||||
bus=dbus.SessionBus(),
|
||||
do_not_queue=True)
|
||||
|
||||
store = PanStore(data_dir)
|
||||
users = store.load_all_users()
|
||||
devices = store.load_all_devices()
|
||||
|
||||
# TODO update bus data if the asyncio thread tells us so.
|
||||
Users(bus_name, users)
|
||||
device_bus = Devices(bus_name, devices)
|
||||
|
||||
def message_callback():
|
||||
try:
|
||||
message = queue.get_nowait()
|
||||
except Empty:
|
||||
return True
|
||||
|
||||
logger.info(f"Dbus loop received message {message}")
|
||||
|
||||
if isinstance(message, ShutDownMessage):
|
||||
queue.task_done()
|
||||
loop.quit()
|
||||
return False
|
||||
|
||||
elif isinstance(message, DevicesMessage):
|
||||
device_bus.update_devices(message)
|
||||
|
||||
return True
|
||||
|
||||
GLib.timeout_add(100, message_callback)
|
||||
|
||||
loop.run()
|
||||
|
||||
|
||||
async def shutdown_glib_loop(future, queue, app):
|
||||
await queue.put(ShutDownMessage())
|
||||
await future
|
Loading…
Reference in New Issue
Block a user