Repository: matrix-org/synapse

Issue:
can't adapt type 'dict' when doing something with room keys
```
[homeserver_1] 2020-03-04 17:46:42,842 - synapse.http.server - 110 - ERROR - PUT-58- Failed handle request via 'RoomKeysServlet': <XForwardedForRequest at 0x7fd4f193bd68 method='PUT' uri='/_matrix/client/unstable/room_keys/keys?version=2' clientproto='HTTP/1.0' site=8118>
Traceback (most recent call last):
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/http/server.py", line 78, in wrapped_request_handler
    await h(self, request)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/http/server.py", line 331, in _async_render
    callback_return = await callback_return
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/rest/client/v2_alpha/room_keys.py", line 134, in on_PUT
    ret = await self.e2e_room_keys_handler.upload_room_keys(user_id, version, body)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/failure.py", line 491, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/handlers/e2e_room_keys.py", line 226, in upload_room_keys
    user_id, version, room_id, session_id, room_key
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/failure.py", line 491, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/data_stores/main/e2e_room_keys.py", line 55, in update_e2e_room_key
    desc="update_e2e_room_key",
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/failure.py", line 491, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 495, in runInteraction
    **kwargs
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/internet/defer.py", line 1416, in _inlineCallbacks
    result = result.throwExceptionIntoGenerator(g)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/failure.py", line 491, in throwExceptionIntoGenerator
    return g.throw(self.type, self.value, self.tb)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 543, in runWithConnection
    self._db_pool.runWithConnection(inner_func, *args, **kwargs)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/threadpool.py", line 250, in inContext
    result = inContext.theWork()
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/threadpool.py", line 266, in <lambda>
    inContext.theWork = lambda: context.call(ctx, func, *args, **kw)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/context.py", line 122, in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/context.py", line 85, in callWithContext
    return func(*args,**kw)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/enterprise/adbapi.py", line 306, in _runWithConnection
    compat.reraise(excValue, excTraceback)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/python/compat.py", line 464, in reraise
    raise exception.with_traceback(traceback)
  File "/home/matrix/synapse/lib/python3.6/site-packages/twisted/enterprise/adbapi.py", line 297, in _runWithConnection
    result = func(conn, *args, **kw)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 540, in inner_func
    return func(conn, *args, **kwargs)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 378, in new_transaction
    r = func(cursor, *args, **kwargs)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 1211, in simple_update_one_txn
    rowcount = cls.simple_update_txn(txn, table, keyvalues, updatevalues)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 1181, in simple_update_txn
    txn.execute(update_sql, list(updatevalues.values()) + list(keyvalues.values()))
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 175, in execute
    self._do_execute(self.txn.execute, sql, *args)
  File "/home/matrix/synapse/lib/python3.6/site-packages/synapse/storage/database.py", line 201, in _do_execute
    return func(sql, *args)
psycopg2.ProgrammingError: can't adapt type 'dict'
[homeserver_1] 2020-03-04 17:46:42,941 - synapse.access.http.8118 - 302 - INFO - PUT-58- 174.3.196.16 - 8118 - {@travis:t2l.io} Processed request: 0.144sec/0.000sec (0.093sec, 0.000sec) (0.002sec/0.047sec/3) 67B 500 "PUT /_matrix/client/unstable/room_keys/keys?version=2 HTTP/1.0" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.122 Safari/537.36" [0 dbevts]
```

Synapse 1.11.1


Discussion:
This is a Riot regression, will fix in https://github.com/vector-im/riot-web/issues/12618.
Riot fix merged, should appear on develop momentarily.
Not sure why this is open, it's solved as far as I can tell.
Sorry, I didn't get the time to write our conclusion here, the action from the backend team on that is to add a bit of input control to this endpoint to provide more understandable failures should this happen again. I'll close the issue once it's done.

Resolving patch:
diff --git a/synapse/handlers/e2e_room_keys.py b/synapse/handlers/e2e_room_keys.py
--- a/synapse/handlers/e2e_room_keys.py
+++ b/synapse/handlers/e2e_room_keys.py
@@ -207,6 +207,13 @@ def upload_room_keys(self, user_id, version, room_keys):
             changed = False  # if anything has changed, we need to update the etag
             for room_id, room in iteritems(room_keys["rooms"]):
                 for session_id, room_key in iteritems(room["sessions"]):
+                    if not isinstance(room_key["is_verified"], bool):
+                        msg = (
+                            "is_verified must be a boolean in keys for session %s in"
+                            "room %s" % (session_id, room_id)
+                        )
+                        raise SynapseError(400, msg, Codes.INVALID_PARAM)
+
                     log_kv(
                         {
                             "message": "Trying to upload room key",


Test patch: