mirror of
https://github.com/matrix-org/pantalaimon.git
synced 2025-01-23 13:51:15 -05:00
daemon: Handle the room/messages endpoint.
This commit is contained in:
parent
1bbf38e240
commit
f2907b1811
@ -1,6 +1,6 @@
|
||||
import asyncio
|
||||
from pprint import pformat
|
||||
from typing import Any, Dict
|
||||
from typing import Any, Dict, Optional
|
||||
|
||||
from nio import (AsyncClient, ClientConfig, EncryptionError,
|
||||
GroupEncryptionError, KeysQueryResponse, MegolmEvent,
|
||||
@ -110,6 +110,71 @@ class PanClient(AsyncClient):
|
||||
content
|
||||
)
|
||||
|
||||
def pan_decrypt_event(self, event_dict, room_id=None):
|
||||
# type: (Dict[Any, Any], Optional[str]) -> ()
|
||||
event = RoomEncryptedEvent.parse_event(event_dict)
|
||||
|
||||
if not event.room_id:
|
||||
event.room_id = room_id
|
||||
|
||||
if not isinstance(event, MegolmEvent):
|
||||
logger.warn("Encrypted event is not a megolm event:"
|
||||
"\n{}".format(pformat(event_dict)))
|
||||
return None
|
||||
|
||||
try:
|
||||
decrypted_event = self.decrypt_event(event)
|
||||
logger.info("Decrypted event: {}".format(decrypted_event))
|
||||
event_dict["type"] = "m.room.message"
|
||||
|
||||
# TODO support other event types
|
||||
# This should be best done in nio, modify events so they
|
||||
# keep the dictionary from which they are built in a source
|
||||
# attribute.
|
||||
event_dict["content"] = {
|
||||
"msgtype": "m.text",
|
||||
"body": decrypted_event.body
|
||||
}
|
||||
|
||||
if decrypted_event.formatted_body:
|
||||
event_dict["content"]["formatted_body"] = (
|
||||
decrypted_event.formatted_body)
|
||||
event_dict["content"]["format"] = decrypted_event.format
|
||||
|
||||
event_dict["decrypted"] = True
|
||||
event_dict["verified"] = decrypted_event.verified
|
||||
|
||||
except EncryptionError as error:
|
||||
logger.warn(error)
|
||||
return
|
||||
|
||||
def decrypt_messages_body(self, body):
|
||||
# type: (Dict[Any, Any]) -> Dict[Any, Any]
|
||||
"""Go through a messages response and decrypt megolm encrypted events.
|
||||
|
||||
Args:
|
||||
body (Dict[Any, Any]): The dictionary of a Sync response.
|
||||
|
||||
Returns the json response with decrypted events.
|
||||
"""
|
||||
if "chunk" not in body:
|
||||
return body
|
||||
|
||||
logger.info("Decrypting room messages")
|
||||
|
||||
for event in body["chunk"]:
|
||||
if "type" not in event:
|
||||
continue
|
||||
|
||||
if event["type"] != "m.room.encrypted":
|
||||
logger.debug("Event is not encrypted: "
|
||||
"\n{}".format(pformat(event)))
|
||||
continue
|
||||
|
||||
self.pan_decrypt_event(event)
|
||||
|
||||
return body
|
||||
|
||||
def decrypt_sync_body(self, body):
|
||||
# type: (Dict[Any, Any]) -> Dict[Any, Any]
|
||||
"""Go through a json sync response and decrypt megolm encrypted events.
|
||||
@ -119,6 +184,7 @@ class PanClient(AsyncClient):
|
||||
|
||||
Returns the json response with decrypted events.
|
||||
"""
|
||||
logger.info("Decrypting sync")
|
||||
for room_id, room_dict in body["rooms"]["join"].items():
|
||||
try:
|
||||
if not self.rooms[room_id].encrypted:
|
||||
@ -131,43 +197,6 @@ class PanClient(AsyncClient):
|
||||
continue
|
||||
|
||||
for event in room_dict["timeline"]["events"]:
|
||||
if event["type"] != "m.room.encrypted":
|
||||
logger.info("Event is not encrypted: "
|
||||
"\n{}".format(pformat(event)))
|
||||
continue
|
||||
|
||||
parsed_event = RoomEncryptedEvent.parse_event(event)
|
||||
parsed_event.room_id = room_id
|
||||
|
||||
if not isinstance(parsed_event, MegolmEvent):
|
||||
logger.warn("Encrypted event is not a megolm event:"
|
||||
"\n{}".format(pformat(event)))
|
||||
continue
|
||||
|
||||
try:
|
||||
decrypted_event = self.decrypt_event(parsed_event)
|
||||
logger.info("Decrypted event: {}".format(decrypted_event))
|
||||
event["type"] = "m.room.message"
|
||||
|
||||
# TODO support other event types
|
||||
# This should be best done in nio, modify events so they
|
||||
# keep the dictionary from which they are built in a source
|
||||
# attribute.
|
||||
event["content"] = {
|
||||
"msgtype": "m.text",
|
||||
"body": decrypted_event.body
|
||||
}
|
||||
|
||||
if decrypted_event.formatted_body:
|
||||
event["content"]["formatted_body"] = (
|
||||
decrypted_event.formatted_body)
|
||||
event["content"]["format"] = decrypted_event.format
|
||||
|
||||
event["decrypted"] = True
|
||||
event["verified"] = decrypted_event.verified
|
||||
|
||||
except EncryptionError as error:
|
||||
logger.warn(error)
|
||||
continue
|
||||
self.pan_decrypt_event(event, room_id)
|
||||
|
||||
return body
|
||||
|
@ -319,6 +319,34 @@ class ProxyDaemon:
|
||||
text=await response.text()
|
||||
)
|
||||
|
||||
async def messages(self, request):
|
||||
access_token = self.get_access_token(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:
|
||||
return self._unknown_token
|
||||
|
||||
response = await self.forward_request(request)
|
||||
|
||||
if response.status == 200:
|
||||
json_response = await response.json()
|
||||
json_response = client.decrypt_messages_body(json_response)
|
||||
|
||||
return web.Response(
|
||||
status=response.status,
|
||||
text=json.dumps(json_response)
|
||||
)
|
||||
else:
|
||||
return web.Response(
|
||||
status=response.status,
|
||||
text=await response.text()
|
||||
)
|
||||
|
||||
async def to_web_response(self, response):
|
||||
return web.Response(status=response.status, text=await response.text())
|
||||
|
||||
@ -396,6 +424,7 @@ async def init(homeserver, http_proxy, ssl):
|
||||
app.add_routes([
|
||||
web.post("/_matrix/client/r0/login", proxy.login),
|
||||
web.get("/_matrix/client/r0/sync", proxy.sync),
|
||||
web.get("/_matrix/client/r0/rooms/{room_id}/messages", proxy.messages),
|
||||
web.put(
|
||||
r"/_matrix/client/r0/rooms/{room_id}/send/{event_type}/{txnid}",
|
||||
proxy.send_message
|
||||
|
Loading…
Reference in New Issue
Block a user