ui: Rework the way the dbus thread and main thread communicate.

This commit is contained in:
Damir Jelić 2019-05-13 16:29:59 +02:00
parent 1cbe5b8a6d
commit 42450b51c7
6 changed files with 356 additions and 94 deletions

View File

@ -9,12 +9,15 @@ from nio import (AsyncClient, ClientConfig, EncryptionError,
KeyVerificationEvent, LocalProtocolError, KeyVerificationEvent, LocalProtocolError,
KeyVerificationStart, KeyVerificationKey, KeyVerificationMac) KeyVerificationStart, KeyVerificationKey, KeyVerificationMac)
from nio.store import SqliteStore from nio.store import SqliteStore
from nio.crypto import Sas
from pantalaimon.log import logger from pantalaimon.log import logger
from pantalaimon.thread_messages import ( from pantalaimon.thread_messages import (
DevicesMessage, DevicesMessage,
DeviceAuthStringMessage, InviteSasSignal,
InfoMessage ShowSasSignal,
SasDoneSignal,
DaemonResponse
) )
@ -72,9 +75,8 @@ class PanClient(AsyncClient):
} }
} }
async def send_info(self, string): async def send_message(self, message):
"""Send a info message to the UI thread.""" """Send a thread message to the UI thread."""
message = InfoMessage(string)
await self.queue.put(message) await self.queue.put(message)
async def sync_tasks(self, response): async def sync_tasks(self, response):
@ -125,10 +127,11 @@ class PanClient(AsyncClient):
logger.info(f"{event.sender} via {event.from_device} has started " logger.info(f"{event.sender} via {event.from_device} has started "
f"a key verification process.") f"a key verification process.")
message = DeviceStartSasMessage( message = InviteSasSignal(
self.user_id, self.user_id,
event.sender, event.sender,
event.from_device event.from_device,
event.transaction_id
) )
task = loop.create_task( task = loop.create_task(
@ -144,10 +147,11 @@ class PanClient(AsyncClient):
device = sas.other_olm_device device = sas.other_olm_device
emoji = sas.get_emoji() emoji = sas.get_emoji()
message = DeviceAuthStringMessage( message = ShowSasSignal(
self.user_id, self.user_id,
device.user_id, device.user_id,
device.id, device.id,
sas.transaction_id,
emoji emoji
) )
@ -163,11 +167,14 @@ class PanClient(AsyncClient):
device = sas.other_olm_device device = sas.other_olm_device
if sas.verified: if sas.verified:
task = loop.create_task( task = loop.create_task(self.send_message(
self.send_info(f"Device {device.id} of user " SasDoneSignal(
f"{device.user_id} succesfully " self.user_id,
f"verified.") device.user_id,
) device.id,
sas.transaction_id
)
))
self.key_verificatins_tasks.append(task) self.key_verificatins_tasks.append(task)
def start_loop(self): def start_loop(self):
@ -199,13 +206,42 @@ class PanClient(AsyncClient):
sas = self.get_active_sas(user_id, device_id) sas = self.get_active_sas(user_id, device_id)
if not sas: if not sas:
await self.send_info("No such verification process found.") await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
Sas._txid_error[0],
Sas._txid_error[1]
)
)
return return
try: try:
await self.accept_key_verification(sas.transaction_id) await self.accept_key_verification(sas.transaction_id)
except (LocalProtocolError, ClientConnectionError) as e: await self.send_message(
await self.send_info(f"Error accepting key verification: {e}") DaemonResponse(
message.message_id,
self.user_id,
"m.ok",
"Successfully accepted the key verification request"
))
except LocalProtocolError as e:
await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
Sas._unexpected_message_error[0],
e
))
except ClientConnectionError as e:
await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
"m.connection_error",
e
))
async def confirm_sas(self, message): async def confirm_sas(self, message):
user_id = message.user_id user_id = message.user_id
@ -214,20 +250,49 @@ class PanClient(AsyncClient):
sas = self.get_active_sas(user_id, device_id) sas = self.get_active_sas(user_id, device_id)
if not sas: if not sas:
await self.send_info("No such verification process found.") await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
Sas._txid_error[0],
Sas._txid_error[1]
)
)
return return
try: try:
await self.confirm_short_auth_string(sas.transaction_id) await self.confirm_short_auth_string(sas.transaction_id)
except ClientConnectionError as e: except ClientConnectionError as e:
await self.send_info(f"Error confirming short auth string: {e}") await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
"m.connection_error",
e
))
return
device = sas.other_olm_device device = sas.other_olm_device
if sas.verified: if sas.verified:
await self.send_info(f"Device {device.id} of user {device.user_id}" await self.send_message(
f" succesfully verified.") SasDoneSignal(
self.user_id,
device.user_id,
device.id,
sas.transaction_id
)
)
else: else:
await self.send_info(f"Waiting for {device.user_id} to confirm...") await self.send_message(
DaemonResponse(
message.message_id,
self.user_id,
"m.ok",
f"Waiting for {device.user_id} to confirm."
))
async def loop_stop(self): async def loop_stop(self):
"""Stop the client loop.""" """Stop the client loop."""

View File

@ -24,8 +24,9 @@ from pantalaimon.thread_messages import (
ExportKeysMessage, ExportKeysMessage,
ImportKeysMessage, ImportKeysMessage,
DeviceConfirmSasMessage, DeviceConfirmSasMessage,
DeviceAcceptSasMessage, SasMessage,
InfoMessage AcceptSasMessage,
DaemonResponse
) )
@ -89,7 +90,7 @@ class ProxyDaemon:
pan_client.start_loop() pan_client.start_loop()
async def _verify_device(self, client, device): async def _verify_device(self, message_id, client, device):
ret = client.verify_device(device) ret = client.verify_device(device)
if ret: if ret:
@ -100,9 +101,9 @@ class ProxyDaemon:
f"{device.user_id} already verified") f"{device.user_id} already verified")
logger.info(msg) logger.info(msg)
await self.send_info(msg) await self.send_response(message_id, client.user_id, "m.ok", msg)
async def _unverify_device(self, client, device): async def _unverify_device(self, message_id, client, device):
ret = client.unverify_device(device) ret = client.unverify_device(device)
if ret: if ret:
@ -113,11 +114,11 @@ class ProxyDaemon:
f"{device.user_id} already unverified") f"{device.user_id} already unverified")
logger.info(msg) logger.info(msg)
await self.send_info(msg) await self.send_response(message_id, client.user_id, "m.ok", msg)
async def send_info(self, string): async def send_response(self, message_id, pan_user, code, message):
"""Send a info message to the UI thread.""" """Send a thread response message to the UI thread."""
message = InfoMessage(string) message = DaemonResponse(message_id, pan_user, code, message)
await self.send_queue.put(message) await self.send_queue.put(message)
async def receive_message(self, message): async def receive_message(self, message):
@ -125,8 +126,7 @@ class ProxyDaemon:
if isinstance( if isinstance(
message, message,
(DeviceVerifyMessage, DeviceUnverifyMessage, (DeviceVerifyMessage, DeviceUnverifyMessage)
DeviceConfirmSasMessage, DeviceAcceptSasMessage)
): ):
device = client.device_store[message.user_id].get( device = client.device_store[message.user_id].get(
@ -137,15 +137,22 @@ class ProxyDaemon:
if not device: if not device:
msg = (f"No device found for {message.user_id} and " msg = (f"No device found for {message.user_id} and "
f"{message.device_id}") f"{message.device_id}")
await self.send_info(msg) await self.send_response(
message.message_id,
message.pan_user,
"m.unknown_device",
msg
)
logger.info(msg) logger.info(msg)
return return
if isinstance(message, DeviceVerifyMessage): if isinstance(message, DeviceVerifyMessage):
await self._verify_device(client, device) await self._verify_device(message.message_id, client, device)
elif isinstance(message, DeviceUnverifyMessage): elif isinstance(message, DeviceUnverifyMessage):
await self._unverify_device(client, device) await self._unverify_device(message.message_id, client, device)
elif isinstance(message, DeviceAcceptSasMessage):
elif isinstance(message, SasMessage):
if isinstance(message, AcceptSasMessage):
await client.accept_sas(message) await client.accept_sas(message)
elif isinstance(message, DeviceConfirmSasMessage): elif isinstance(message, DeviceConfirmSasMessage):
await client.confirm_sas(message) await client.confirm_sas(message)
@ -160,12 +167,23 @@ class ProxyDaemon:
info_msg = (f"Error exporting keys for {client.user_id} to" info_msg = (f"Error exporting keys for {client.user_id} to"
f" {path} {e}") f" {path} {e}")
logger.info(info_msg) logger.info(info_msg)
await self.send_info(info_msg) await self.send_response(
message.message_id,
client.user_id,
"m.os_error",
str(e)
)
else: else:
info_msg = (f"Succesfully exported keys for {client.user_id} " info_msg = (f"Succesfully exported keys for {client.user_id} "
f"to {path}") f"to {path}")
logger.info(info_msg) logger.info(info_msg)
await self.send_info(info_msg) await self.send_response(
message.message_id,
client.user_id,
"m.ok",
info_msg
)
elif isinstance(message, ImportKeysMessage): elif isinstance(message, ImportKeysMessage):
path = os.path.abspath(os.path.expanduser(message.file_path)) path = os.path.abspath(os.path.expanduser(message.file_path))
@ -177,12 +195,22 @@ class ProxyDaemon:
info_msg = (f"Error importing keys for {client.user_id} " info_msg = (f"Error importing keys for {client.user_id} "
f"from {path} {e}") f"from {path} {e}")
logger.info(info_msg) logger.info(info_msg)
await self.send_info(info_msg) await self.send_response(
message.message_id,
client.user_id,
"m.os_error",
str(e)
)
else: else:
info_msg = (f"Succesfully imported keys for {client.user_id} " info_msg = (f"Succesfully imported keys for {client.user_id} "
f"from {path}") f"from {path}")
logger.info(info_msg) logger.info(info_msg)
await self.send_info(info_msg) await self.send_response(
message.message_id,
client.user_id,
"m.ok",
info_msg
)
def get_access_token(self, request): def get_access_token(self, request):
# type: (aiohttp.web.BaseRequest) -> str # type: (aiohttp.web.BaseRequest) -> str

View File

@ -14,7 +14,7 @@ from logbook import StderrHandler
from aiohttp import web from aiohttp import web
from pantalaimon.ui import GlibT from pantalaimon.ui import GlibT
from pantalaimon.thread_messages import InfoMessage from pantalaimon.thread_messages import DaemonResponse
from pantalaimon.daemon import ProxyDaemon from pantalaimon.daemon import ProxyDaemon
from pantalaimon.config import PanConfig, PanConfigError, parse_log_level from pantalaimon.config import PanConfig, PanConfigError, parse_log_level
from pantalaimon.log import logger from pantalaimon.log import logger
@ -81,8 +81,8 @@ async def message_router(receive_queue, send_queue, proxies):
return None return None
async def send_info(string): async def send_info(message_id, pan_user, code, string):
message = InfoMessage(string) message = DaemonResponse(message_id, pan_user, code, string)
await send_queue.put(message) await send_queue.put(message)
while True: while True:
@ -94,7 +94,12 @@ async def message_router(receive_queue, send_queue, proxies):
if not proxy: if not proxy:
msg = f"No pan client found for {message.pan_user}." msg = f"No pan client found for {message.pan_user}."
logger.warn(msg) logger.warn(msg)
send_info(msg) await send_info(
message.message_id,
message.pan_user,
"m.unknown_client",
msg
)
await proxy.receive_message(message) await proxy.receive_message(message)

View File

@ -276,15 +276,34 @@ class PanCtl:
self.ctl = self.pan_bus["org.pantalaimon1.control"] self.ctl = self.pan_bus["org.pantalaimon1.control"]
self.devices = self.pan_bus["org.pantalaimon1.devices"] self.devices = self.pan_bus["org.pantalaimon1.devices"]
self.ctl.Info.connect(self.show_info) self.own_message_ids = []
self.devices.SasReceived.connect(self.show_sas)
def show_info(self, message): self.ctl.Response.connect(self.show_response)
print(message) self.devices.VerificationInvite.connect(self.show_sas_invite)
self.devices.VerificationString.connect(self.show_sas)
self.devices.VerificationDone.connect(self.sas_done)
def show_response(self, response_id, pan_user, message):
if response_id not in self.own_message_ids:
return
self.own_message_ids.remove(response_id)
print(message["message"])
def sas_done(self, pan_user, user_id, device_id, _):
print(f"Device {device_id} of user {user_id}"
f" succesfully verified for pan user {pan_user}.")
def show_sas_invite(self, pan_user, user_id, device_id, _):
print(f"{user_id} has started an interactive device "
f"verification for his device {device_id} with pan user "
f"{pan_user}\n"
f"Accept the invitation with the accept-verification command.")
# The emoji printing logic was taken from weechat-matrix and was written by # The emoji printing logic was taken from weechat-matrix and was written by
# dkasak. # dkasak.
def show_sas(self, pan_user, user_id, device_id, emoji): def show_sas(self, pan_user, user_id, device_id, _, emoji):
emojis = [x[0] for x in emoji] emojis = [x[0] for x in emoji]
descriptions = [x[1] for x in emoji] descriptions = [x[1] for x in emoji]
@ -378,27 +397,39 @@ class PanCtl:
self.list_users() self.list_users()
elif command == "import-keys": elif command == "import-keys":
self.ctl.ImportKeys(args.pan_user, args.path, args.passphrase) self.own_message_ids.append(
self.ctl.ImportKeys(
args.pan_user,
args.path,
args.passphrase
))
elif command == "export-keys": elif command == "export-keys":
self.ctl.ExportKeys(args.pan_user, args.path, args.passphrase) self.own_message_ids.append(
self.ctl.ExportKeys(
args.pan_user,
args.path,
args.passphrase
))
elif command == "list-devices": elif command == "list-devices":
self.list_devices(args) self.list_devices(args)
elif command == "accept-verification": elif command == "accept-verification":
self.devices.AcceptKeyVerification( self.own_message_ids.append(
args.pan_user, self.devices.AcceptKeyVerification(
args.user_id, args.pan_user,
args.device_id args.user_id,
) args.device_id
))
elif command == "confirm-verification": elif command == "confirm-verification":
self.devices.ConfirmKeyVerification( self.own_message_ids.append(
args.pan_user, self.devices.ConfirmKeyVerification(
args.user_id, args.pan_user,
args.device_id args.user_id,
) args.device_id
))
def main(): def main():

View File

@ -7,8 +7,11 @@ class Message:
@attr.s @attr.s
class InfoMessage(Message): class DaemonResponse(Message):
string = attr.ib() message_id = attr.ib()
pan_user = attr.ib()
code = attr.ib()
message = attr.ib()
@attr.s @attr.s
@ -19,6 +22,7 @@ class DevicesMessage(Message):
@attr.s @attr.s
class _KeysOperation(Message): class _KeysOperation(Message):
message_id = attr.ib()
pan_user = attr.ib() pan_user = attr.ib()
file_path = attr.ib() file_path = attr.ib()
passphrase = attr.ib() passphrase = attr.ib()
@ -36,6 +40,7 @@ class ExportKeysMessage(_KeysOperation):
@attr.s @attr.s
class _VerificationMessage(Message): class _VerificationMessage(Message):
message_id = attr.ib()
pan_user = attr.ib() pan_user = attr.ib()
user_id = attr.ib() user_id = attr.ib()
device_id = attr.ib() device_id = attr.ib()
@ -52,20 +57,43 @@ class DeviceUnverifyMessage(_VerificationMessage):
@attr.s @attr.s
class DeviceStartSasMessage(_VerificationMessage): class SasMessage(_VerificationMessage):
pass pass
@attr.s @attr.s
class DeviceAcceptSasMessage(_VerificationMessage): class DeviceConfirmSasMessage(SasMessage):
pass pass
@attr.s @attr.s
class DeviceConfirmSasMessage(_VerificationMessage): class AcceptSasMessage(SasMessage):
pass pass
@attr.s @attr.s
class DeviceAuthStringMessage(_VerificationMessage): class _SasSignal:
short_string = attr.ib() pan_user = attr.ib()
user_id = attr.ib()
device_id = attr.ib()
transaction_id = attr.ib()
@attr.s
class StartSasSignal(_SasSignal):
pass
@attr.s
class InviteSasSignal(_SasSignal):
pass
@attr.s
class ShowSasSignal(_SasSignal):
emoji = attr.ib()
@attr.s
class SasDoneSignal(_SasSignal):
pass

View File

@ -12,16 +12,31 @@ from pantalaimon.thread_messages import (
DeviceVerifyMessage, DeviceVerifyMessage,
DeviceUnverifyMessage, DeviceUnverifyMessage,
DevicesMessage, DevicesMessage,
InfoMessage, AcceptSasMessage,
DeviceAcceptSasMessage,
DeviceConfirmSasMessage, DeviceConfirmSasMessage,
DeviceAuthStringMessage,
ImportKeysMessage, ImportKeysMessage,
ExportKeysMessage, ExportKeysMessage,
StartSasSignal,
ShowSasSignal,
InviteSasSignal,
SasDoneSignal,
DaemonResponse
) )
from pantalaimon.log import logger from pantalaimon.log import logger
class IdCounter:
def __init__(self):
self._message_id = 0
@property
def message_id(self):
ret = self._message_id
self._message_id += 1
return ret
class Control: class Control:
""" """
<node> <node>
@ -34,40 +49,59 @@ class Control:
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='file_path' direction='in'/> <arg type='s' name='file_path' direction='in'/>
<arg type='s' name='passphrase' direction='in'/> <arg type='s' name='passphrase' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<method name='ImportKeys'> <method name='ImportKeys'>
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='file_path' direction='in'/> <arg type='s' name='file_path' direction='in'/>
<arg type='s' name='passphrase' direction='in'/> <arg type='s' name='passphrase' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<signal name="Info"> <signal name="Response">
<arg direction="out" type="s" name="message"/> <arg direction="out" type="i" name="id"/>
<arg direction="out" type="s" name="pan_user"/>
<arg direction="out" type="a{ss}" name="message"/>
</signal> </signal>
</interface> </interface>
</node> </node>
""" """
def __init__(self, queue, user_list=None): Response = signal()
def __init__(self, queue, user_list, id_counter):
self.users = user_list self.users = user_list
self.queue = queue self.queue = queue
self.id_counter = id_counter
@property
def message_id(self):
return self.id_counter.message_id
def ListUsers(self): def ListUsers(self):
"""Return the list of pan users.""" """Return the list of pan users."""
return self.users return self.users
def ExportKeys(self, pan_user, filepath, passphrase): def ExportKeys(self, pan_user, filepath, passphrase):
message = ExportKeysMessage(pan_user, filepath, passphrase) message = ExportKeysMessage(
self.message_id,
pan_user,
filepath,
passphrase
)
self.queue.put(message) self.queue.put(message)
return return message.message_id
def ImportKeys(self, pan_user, filepath, passphrase): def ImportKeys(self, pan_user, filepath, passphrase):
message = ImportKeysMessage(pan_user, filepath, passphrase) message = ImportKeysMessage(
self.message_id,
pan_user,
filepath,
passphrase
)
self.queue.put(message) self.queue.put(message)
return return message.message_id
Info = signal()
class Devices: class Devices:
@ -89,30 +123,64 @@ class Devices:
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='user_id' direction='in'/> <arg type='s' name='user_id' direction='in'/>
<arg type='s' name='device_id' direction='in'/> <arg type='s' name='device_id' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<method name='ConfirmKeyVerification'> <method name='ConfirmKeyVerification'>
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='user_id' direction='in'/> <arg type='s' name='user_id' direction='in'/>
<arg type='s' name='device_id' direction='in'/> <arg type='s' name='device_id' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<signal name="SasReceived"> <signal name="VerificationInvite">
<arg direction="out" type="s" name="pan_user"/> <arg direction="out" type="s" name="pan_user"/>
<arg direction="out" type="s" name="user_id"/> <arg direction="out" type="s" name="user_id"/>
<arg direction="out" type="s" name="device_id"/> <arg direction="out" type="s" name="device_id"/>
<arg direction="out" type="s" name="transaction_id"/>
</signal>
<signal name="VerificationString">
<arg direction="out" type="s" name="pan_user"/>
<arg direction="out" type="s" name="user_id"/>
<arg direction="out" type="s" name="device_id"/>
<arg direction="out" type="s" name="transaction_id"/>
<arg direction="out" type="a(ss)" name="emoji"/> <arg direction="out" type="a(ss)" name="emoji"/>
</signal> </signal>
<signal name="VerificationCancel">
<arg direction="out" type="s" name="pan_user"/>
<arg direction="out" type="s" name="user_id"/>
<arg direction="out" type="s" name="device_id"/>
<arg direction="out" type="s" name="transaction_id"/>
<arg direction="out" type="s" name="reason"/>
<arg direction="out" type="s" name="code"/>
</signal>
<signal name="VerificationDone">
<arg direction="out" type="s" name="pan_user"/>
<arg direction="out" type="s" name="user_id"/>
<arg direction="out" type="s" name="device_id"/>
<arg direction="out" type="s" name="transaction_id"/>
</signal>
</interface> </interface>
</node> </node>
""" """
SasReceived = signal() VerificationInvite = signal()
VerificationCancel = signal()
VerificationString = signal()
VerificationDone = signal()
def __init__(self, queue, device_list): def __init__(self, queue, device_list, id_counter):
self.device_list = device_list self.device_list = device_list
self.queue = queue self.queue = queue
self.id_counter = id_counter
@property
def message_id(self):
return self.id_counter.message_id
def List(self, pan_user): def List(self, pan_user):
device_store = self.device_list.get(pan_user, None) device_store = self.device_list.get(pan_user, None)
@ -170,14 +238,25 @@ class Devices:
return return
def ConfirmKeyVerification(self, pan_user, user_id, device_id): def ConfirmKeyVerification(self, pan_user, user_id, device_id):
message = DeviceConfirmSasMessage(pan_user, user_id, device_id) message = DeviceConfirmSasMessage(
self.message_id,
pan_user,
user_id,
device_id
)
print("HEEEELOOO {}".format(message.message_id))
self.queue.put(message) self.queue.put(message)
return return message.message_id
def AcceptKeyVerification(self, pan_user, user_id, device_id): def AcceptKeyVerification(self, pan_user, user_id, device_id):
message = DeviceAcceptSasMessage(pan_user, user_id, device_id) message = AcceptSasMessage(
self.message_id,
pan_user,
user_id,
device_id
)
self.queue.put(message) self.queue.put(message)
return return message.message_id
def update_devices(self, message): def update_devices(self, message):
device_store = self.device_list[message.user_id] device_store = self.device_list[message.user_id]
@ -217,8 +296,10 @@ class GlibT:
self.users = self.store.load_all_users() self.users = self.store.load_all_users()
self.devices = self.store.load_all_devices() self.devices = self.store.load_all_devices()
self.control_if = Control(self.send_queue, self.users) id_counter = IdCounter()
self.device_if = Devices(self.send_queue, self.devices)
self.control_if = Control(self.send_queue, self.users, id_counter)
self.device_if = Devices(self.send_queue, self.devices, id_counter)
self.bus = SessionBus() self.bus = SessionBus()
self.bus.publish("org.pantalaimon1", self.control_if, self.device_if) self.bus.publish("org.pantalaimon1", self.control_if, self.device_if)
@ -234,16 +315,40 @@ class GlibT:
if isinstance(message, DevicesMessage): if isinstance(message, DevicesMessage):
self.device_if.update_devices(message) self.device_if.update_devices(message)
elif isinstance(message, DeviceAuthStringMessage): elif isinstance(message, InviteSasSignal):
self.device_if.SasReceived( self.device_if.VerificationInvite(
message.pan_user, message.pan_user,
message.user_id, message.user_id,
message.device_id, message.device_id,
message.short_string message.transaction_id
) )
elif isinstance(message, InfoMessage): elif isinstance(message, ShowSasSignal):
self.control_if.Info(message.string) self.device_if.VerificationString(
message.pan_user,
message.user_id,
message.device_id,
message.transaction_id,
message.emoji,
)
elif isinstance(message, SasDoneSignal):
self.device_if.VerificationDone(
message.pan_user,
message.user_id,
message.device_id,
message.transaction_id,
)
elif isinstance(message, DaemonResponse):
self.control_if.Response(
message.message_id,
message.pan_user,
{
"code": message.code,
"message": message.message
}
)
self.receive_queue.task_done() self.receive_queue.task_done()
return True return True