mirror of
https://github.com/matrix-org/pantalaimon.git
synced 2025-02-02 18:44:50 -05:00
daemon: Handle the room/messages endpoint.
This commit is contained in:
parent
1bbf38e240
commit
f2907b1811
@ -1,6 +1,6 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
from pprint import pformat
|
from pprint import pformat
|
||||||
from typing import Any, Dict
|
from typing import Any, Dict, Optional
|
||||||
|
|
||||||
from nio import (AsyncClient, ClientConfig, EncryptionError,
|
from nio import (AsyncClient, ClientConfig, EncryptionError,
|
||||||
GroupEncryptionError, KeysQueryResponse, MegolmEvent,
|
GroupEncryptionError, KeysQueryResponse, MegolmEvent,
|
||||||
@ -110,6 +110,71 @@ class PanClient(AsyncClient):
|
|||||||
content
|
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):
|
def decrypt_sync_body(self, body):
|
||||||
# type: (Dict[Any, Any]) -> Dict[Any, Any]
|
# type: (Dict[Any, Any]) -> Dict[Any, Any]
|
||||||
"""Go through a json sync response and decrypt megolm encrypted events.
|
"""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.
|
Returns the json response with decrypted events.
|
||||||
"""
|
"""
|
||||||
|
logger.info("Decrypting sync")
|
||||||
for room_id, room_dict in body["rooms"]["join"].items():
|
for room_id, room_dict in body["rooms"]["join"].items():
|
||||||
try:
|
try:
|
||||||
if not self.rooms[room_id].encrypted:
|
if not self.rooms[room_id].encrypted:
|
||||||
@ -131,43 +197,6 @@ class PanClient(AsyncClient):
|
|||||||
continue
|
continue
|
||||||
|
|
||||||
for event in room_dict["timeline"]["events"]:
|
for event in room_dict["timeline"]["events"]:
|
||||||
if event["type"] != "m.room.encrypted":
|
self.pan_decrypt_event(event, room_id)
|
||||||
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
|
|
||||||
|
|
||||||
return body
|
return body
|
||||||
|
@ -319,6 +319,34 @@ class ProxyDaemon:
|
|||||||
text=await response.text()
|
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):
|
async def to_web_response(self, response):
|
||||||
return web.Response(status=response.status, text=await response.text())
|
return web.Response(status=response.status, text=await response.text())
|
||||||
|
|
||||||
@ -396,6 +424,7 @@ async def init(homeserver, http_proxy, ssl):
|
|||||||
app.add_routes([
|
app.add_routes([
|
||||||
web.post("/_matrix/client/r0/login", proxy.login),
|
web.post("/_matrix/client/r0/login", proxy.login),
|
||||||
web.get("/_matrix/client/r0/sync", proxy.sync),
|
web.get("/_matrix/client/r0/sync", proxy.sync),
|
||||||
|
web.get("/_matrix/client/r0/rooms/{room_id}/messages", proxy.messages),
|
||||||
web.put(
|
web.put(
|
||||||
r"/_matrix/client/r0/rooms/{room_id}/send/{event_type}/{txnid}",
|
r"/_matrix/client/r0/rooms/{room_id}/send/{event_type}/{txnid}",
|
||||||
proxy.send_message
|
proxy.send_message
|
||||||
|
Loading…
x
Reference in New Issue
Block a user