daemon: Connect the queue for unverified devices messages while sending.

This commit is contained in:
Damir Jelić 2019-05-22 11:51:49 +02:00
parent 212baad49e
commit 186560dd4f
4 changed files with 86 additions and 17 deletions

View File

@ -31,14 +31,17 @@ from pantalaimon.client import PanClient
from pantalaimon.log import logger from pantalaimon.log import logger
from pantalaimon.store import ClientInfo, PanStore from pantalaimon.store import ClientInfo, PanStore
from pantalaimon.thread_messages import (AcceptSasMessage, CancelSasMessage, from pantalaimon.thread_messages import (AcceptSasMessage, CancelSasMessage,
CancelSendingMessage,
ConfirmSasMessage, DaemonResponse, ConfirmSasMessage, DaemonResponse,
DeviceBlacklistMessage, DeviceBlacklistMessage,
DeviceUnblacklistMessage, DeviceUnblacklistMessage,
DeviceUnverifyMessage, DeviceUnverifyMessage,
DeviceVerifyMessage, DeviceVerifyMessage,
ExportKeysMessage, ImportKeysMessage, ExportKeysMessage, ImportKeysMessage,
SasMessage, StartSasMessage, SasMessage, SendAnywaysMessage,
StartSasMessage,
UnverifiedDevicesSignal, UnverifiedDevicesSignal,
UnverifiedResponse,
UpdateDevicesMessage, UpdateDevicesMessage,
UpdateUsersMessage) UpdateUsersMessage)
@ -55,7 +58,7 @@ class ProxyDaemon:
ssl = attr.ib(default=None) ssl = attr.ib(default=None)
decryption_timeout = 10 decryption_timeout = 10
unverified_send_timeout = 10 unverified_send_timeout = 60
store = attr.ib(type=PanStore, init=False) store = attr.ib(type=PanStore, init=False)
homeserver_url = attr.ib(init=False, default=attr.Factory(dict)) homeserver_url = attr.ib(init=False, default=attr.Factory(dict))
@ -314,6 +317,23 @@ class ProxyDaemon:
info_msg info_msg
) )
elif isinstance(message, UnverifiedResponse):
client = self.pan_clients[message.pan_user]
if message.room_id not in client.send_decision_queues:
msg = (f"No send request found for user {message.pan_user} "
f"and room {message.room_id}.")
await self.send_response(
message.message_id,
message.pan_user,
"m.unknown_request",
msg
)
return
queue = client.send_decision_queues[message.room_id]
await queue.put(message)
def get_access_token(self, request): def get_access_token(self, request):
# type: (aiohttp.web.BaseRequest) -> str # type: (aiohttp.web.BaseRequest) -> str
"""Extract the access token from the request. """Extract the access token from the request.
@ -777,15 +797,15 @@ class ProxyDaemon:
# There are unverified/unblocked devices in the room, notify # There are unverified/unblocked devices in the room, notify
# the UI thread about this and wait for a response. # the UI thread about this and wait for a response.
queue = asyncio.Queue() queue = asyncio.Queue()
client.send_decision_queues[room_id] = queue
message = UnverifiedDevicesSignal( message = UnverifiedDevicesSignal(
client.user_id, client.user_id,
room_id, room_id,
room.display_name room.display_name
) )
await self.send_queue.put(message)
# TODO allow dbus clients to answer us here. await self.send_queue.put(message)
try: try:
response = await asyncio.wait_for( response = await asyncio.wait_for(
@ -793,12 +813,34 @@ class ProxyDaemon:
self.unverified_send_timeout self.unverified_send_timeout
) )
if response == "cancel": if isinstance(response, CancelSendingMessage):
# The send was canceled notify the client that sent the # The send was canceled notify the client that sent the
# request about this. # request about this.
info_msg = (f"Canceled message sending for room "
f"{room.display_name} ({room_id}).")
logger.info(info_msg)
await self.send_response(
response.message_id,
client.user_id,
"m.ok",
info_msg
)
return web.Response(status=503, text=str(e)) return web.Response(status=503, text=str(e))
elif response == "send-anyways":
elif isinstance(response, SendAnywaysMessage):
# We are sending and ignoring devices along the way. # We are sending and ignoring devices along the way.
info_msg = (f"Ignoring unverified devices and sending "
f"message to room "
f"{room.display_name} ({room_id}).")
logger.info(info_msg)
await self.send_response(
response.message_id,
client.user_id,
"m.ok",
info_msg
)
ret = await _send(True) ret = await _send(True)
await self.send_update_devcies() await self.send_update_devcies()
return ret return ret
@ -807,11 +849,6 @@ class ProxyDaemon:
# We didn't get a response to our signal, send out an error # We didn't get a response to our signal, send out an error
# response. # response.
ret = await _send(True)
await self.send_update_devcies()
return ret
return web.Response( return web.Response(
status=503, status=503,
text=(f"Room contains unverified devices and no " text=(f"Room contains unverified devices and no "
@ -821,8 +858,7 @@ class ProxyDaemon:
) )
finally: finally:
# Clear up the queue client.send_decision_queues.pop(room_id)
pass
async def filter(self, request): async def filter(self, request):
access_token = self.get_access_token(request) access_token = self.get_access_token(request)

View File

@ -356,7 +356,7 @@ class PanCtl:
self.completer.rooms[pan_user].add(room_id) self.completer.rooms[pan_user].add(room_id)
print(f"Error sending message for user {pan_user}, " print(f"Error sending message for user {pan_user}, "
f"there are unverified devices in the room {display_name} " f"there are unverified devices in the room {display_name} "
f"({room_id}). Use the send-anyways or cancel-sending commands " f"({room_id}).\nUse the send-anyways or cancel-sending commands "
f"to ignore the devices or cancel the sending.") f"to ignore the devices or cancel the sending.")
def show_response(self, response_id, pan_user, message): def show_response(self, response_id, pan_user, message):

View File

@ -27,6 +27,23 @@ class UnverifiedDevicesSignal(Message):
room_display_name = attr.ib() room_display_name = attr.ib()
@attr.s
class UnverifiedResponse(Message):
message_id = attr.ib()
pan_user = attr.ib()
room_id = attr.ib()
@attr.s
class SendAnywaysMessage(UnverifiedResponse):
pass
@attr.s
class CancelSendingMessage(UnverifiedResponse):
pass
@attr.s @attr.s
class DaemonResponse(Message): class DaemonResponse(Message):
message_id = attr.ib() message_id = attr.ib()

View File

@ -23,6 +23,7 @@ from pydbus.generic import signal
from pantalaimon.log import logger from pantalaimon.log import logger
from pantalaimon.store import PanStore from pantalaimon.store import PanStore
from pantalaimon.thread_messages import (AcceptSasMessage, CancelSasMessage, from pantalaimon.thread_messages import (AcceptSasMessage, CancelSasMessage,
CancelSendingMessage,
ConfirmSasMessage, DaemonResponse, ConfirmSasMessage, DaemonResponse,
DeviceBlacklistMessage, DeviceBlacklistMessage,
DeviceUnblacklistMessage, DeviceUnblacklistMessage,
@ -30,7 +31,8 @@ from pantalaimon.thread_messages import (AcceptSasMessage, CancelSasMessage,
DeviceVerifyMessage, DeviceVerifyMessage,
ExportKeysMessage, ImportKeysMessage, ExportKeysMessage, ImportKeysMessage,
InviteSasSignal, SasDoneSignal, InviteSasSignal, SasDoneSignal,
ShowSasSignal, StartSasMessage, SendAnywaysMessage, ShowSasSignal,
StartSasMessage,
UnverifiedDevicesSignal, UnverifiedDevicesSignal,
UpdateDevicesMessage, UpdateDevicesMessage,
UpdateUsersMessage) UpdateUsersMessage)
@ -73,11 +75,13 @@ class Control:
<method name='SendAnyways'> <method name='SendAnyways'>
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='room_id' direction='in'/> <arg type='s' name='room_id' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<method name='CancelSending'> <method name='CancelSending'>
<arg type='s' name='pan_user' direction='in'/> <arg type='s' name='pan_user' direction='in'/>
<arg type='s' name='room_id' direction='in'/> <arg type='s' name='room_id' direction='in'/>
<arg type='u' name='id' direction='out'/>
</method> </method>
<signal name="Response"> <signal name="Response">
@ -140,10 +144,22 @@ class Control:
return message.message_id return message.message_id
def SendAnyways(self, pan_user, room_id): def SendAnyways(self, pan_user, room_id):
pass message = SendAnywaysMessage(
self.message_id,
pan_user,
room_id
)
self.queue.put(message)
return message.message_id
def CancelSending(self, pan_user, room_id): def CancelSending(self, pan_user, room_id):
pass message = CancelSendingMessage(
self.message_id,
pan_user,
room_id
)
self.queue.put(message)
return message.message_id
class Devices: class Devices: