forked from MirrorHub/synapse
Merge pull request #2818 from turt2live/travis/admin-list-media
Add an admin route to get all the media in a room
This commit is contained in:
commit
33cac3dc29
3 changed files with 143 additions and 57 deletions
23
docs/admin_api/media_admin_api.md
Normal file
23
docs/admin_api/media_admin_api.md
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# List all media in a room
|
||||||
|
|
||||||
|
This API gets a list of known media in a room.
|
||||||
|
|
||||||
|
The API is:
|
||||||
|
```
|
||||||
|
GET /_matrix/client/r0/admin/room/<room_id>/media
|
||||||
|
```
|
||||||
|
including an `access_token` of a server admin.
|
||||||
|
|
||||||
|
It returns a JSON body like the following:
|
||||||
|
```
|
||||||
|
{
|
||||||
|
"local": [
|
||||||
|
"mxc://localhost/xwvutsrqponmlkjihgfedcba",
|
||||||
|
"mxc://localhost/abcdefghijklmnopqrstuvwx"
|
||||||
|
],
|
||||||
|
"remote": [
|
||||||
|
"mxc://matrix.org/xwvutsrqponmlkjihgfedcba",
|
||||||
|
"mxc://matrix.org/abcdefghijklmnopqrstuvwx"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
|
@ -289,6 +289,27 @@ class QuarantineMediaInRoom(ClientV1RestServlet):
|
||||||
defer.returnValue((200, {"num_quarantined": num_quarantined}))
|
defer.returnValue((200, {"num_quarantined": num_quarantined}))
|
||||||
|
|
||||||
|
|
||||||
|
class ListMediaInRoom(ClientV1RestServlet):
|
||||||
|
"""Lists all of the media in a given room.
|
||||||
|
"""
|
||||||
|
PATTERNS = client_path_patterns("/admin/room/(?P<room_id>[^/]+)/media")
|
||||||
|
|
||||||
|
def __init__(self, hs):
|
||||||
|
super(ListMediaInRoom, self).__init__(hs)
|
||||||
|
self.store = hs.get_datastore()
|
||||||
|
|
||||||
|
@defer.inlineCallbacks
|
||||||
|
def on_GET(self, request, room_id):
|
||||||
|
requester = yield self.auth.get_user_by_req(request)
|
||||||
|
is_admin = yield self.auth.is_server_admin(requester.user)
|
||||||
|
if not is_admin:
|
||||||
|
raise AuthError(403, "You are not a server admin")
|
||||||
|
|
||||||
|
local_mxcs, remote_mxcs = yield self.store.get_media_mxcs_in_room(room_id)
|
||||||
|
|
||||||
|
defer.returnValue((200, {"local": local_mxcs, "remote": remote_mxcs}))
|
||||||
|
|
||||||
|
|
||||||
class ResetPasswordRestServlet(ClientV1RestServlet):
|
class ResetPasswordRestServlet(ClientV1RestServlet):
|
||||||
"""Post request to allow an administrator reset password for a user.
|
"""Post request to allow an administrator reset password for a user.
|
||||||
This needs user to have administrator access in Synapse.
|
This needs user to have administrator access in Synapse.
|
||||||
|
@ -487,3 +508,4 @@ def register_servlets(hs, http_server):
|
||||||
SearchUsersRestServlet(hs).register(http_server)
|
SearchUsersRestServlet(hs).register(http_server)
|
||||||
ShutdownRoomRestServlet(hs).register(http_server)
|
ShutdownRoomRestServlet(hs).register(http_server)
|
||||||
QuarantineMediaInRoom(hs).register(http_server)
|
QuarantineMediaInRoom(hs).register(http_server)
|
||||||
|
ListMediaInRoom(hs).register(http_server)
|
||||||
|
|
|
@ -533,16 +533,84 @@ class RoomStore(SQLBaseStore):
|
||||||
)
|
)
|
||||||
self.is_room_blocked.invalidate((room_id,))
|
self.is_room_blocked.invalidate((room_id,))
|
||||||
|
|
||||||
|
def get_media_mxcs_in_room(self, room_id):
|
||||||
|
"""Retrieves all the local and remote media MXC URIs in a given room
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room_id (str)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The local and remote media as a lists of tuples where the key is
|
||||||
|
the hostname and the value is the media ID.
|
||||||
|
"""
|
||||||
|
def _get_media_mxcs_in_room_txn(txn):
|
||||||
|
local_mxcs, remote_mxcs = self._get_media_mxcs_in_room_txn(txn, room_id)
|
||||||
|
local_media_mxcs = []
|
||||||
|
remote_media_mxcs = []
|
||||||
|
|
||||||
|
# Convert the IDs to MXC URIs
|
||||||
|
for media_id in local_mxcs:
|
||||||
|
local_media_mxcs.append("mxc://%s/%s" % (self.hostname, media_id))
|
||||||
|
for hostname, media_id in remote_mxcs:
|
||||||
|
remote_media_mxcs.append("mxc://%s/%s" % (hostname, media_id))
|
||||||
|
|
||||||
|
return local_media_mxcs, remote_media_mxcs
|
||||||
|
return self.runInteraction("get_media_ids_in_room", _get_media_mxcs_in_room_txn)
|
||||||
|
|
||||||
def quarantine_media_ids_in_room(self, room_id, quarantined_by):
|
def quarantine_media_ids_in_room(self, room_id, quarantined_by):
|
||||||
"""For a room loops through all events with media and quarantines
|
"""For a room loops through all events with media and quarantines
|
||||||
the associated media
|
the associated media
|
||||||
"""
|
"""
|
||||||
def _get_media_ids_in_room(txn):
|
def _quarantine_media_in_room_txn(txn):
|
||||||
|
local_mxcs, remote_mxcs = self._get_media_mxcs_in_room_txn(txn, room_id)
|
||||||
|
total_media_quarantined = 0
|
||||||
|
|
||||||
|
# Now update all the tables to set the quarantined_by flag
|
||||||
|
|
||||||
|
txn.executemany("""
|
||||||
|
UPDATE local_media_repository
|
||||||
|
SET quarantined_by = ?
|
||||||
|
WHERE media_id = ?
|
||||||
|
""", ((quarantined_by, media_id) for media_id in local_mxcs))
|
||||||
|
|
||||||
|
txn.executemany(
|
||||||
|
"""
|
||||||
|
UPDATE remote_media_cache
|
||||||
|
SET quarantined_by = ?
|
||||||
|
WHERE media_origin = ? AND media_id = ?
|
||||||
|
""",
|
||||||
|
(
|
||||||
|
(quarantined_by, origin, media_id)
|
||||||
|
for origin, media_id in remote_mxcs
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
total_media_quarantined += len(local_mxcs)
|
||||||
|
total_media_quarantined += len(remote_mxcs)
|
||||||
|
|
||||||
|
return total_media_quarantined
|
||||||
|
|
||||||
|
return self.runInteraction(
|
||||||
|
"quarantine_media_in_room",
|
||||||
|
_quarantine_media_in_room_txn,
|
||||||
|
)
|
||||||
|
|
||||||
|
def _get_media_mxcs_in_room_txn(self, txn, room_id):
|
||||||
|
"""Retrieves all the local and remote media MXC URIs in a given room
|
||||||
|
|
||||||
|
Args:
|
||||||
|
txn (cursor)
|
||||||
|
room_id (str)
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
The local and remote media as a lists of tuples where the key is
|
||||||
|
the hostname and the value is the media ID.
|
||||||
|
"""
|
||||||
mxc_re = re.compile("^mxc://([^/]+)/([^/#?]+)")
|
mxc_re = re.compile("^mxc://([^/]+)/([^/#?]+)")
|
||||||
|
|
||||||
next_token = self.get_current_events_token() + 1
|
next_token = self.get_current_events_token() + 1
|
||||||
|
local_media_mxcs = []
|
||||||
total_media_quarantined = 0
|
remote_media_mxcs = []
|
||||||
|
|
||||||
while next_token:
|
while next_token:
|
||||||
sql = """
|
sql = """
|
||||||
|
@ -556,8 +624,6 @@ class RoomStore(SQLBaseStore):
|
||||||
txn.execute(sql, (room_id, next_token, True, False, 100))
|
txn.execute(sql, (room_id, next_token, True, False, 100))
|
||||||
|
|
||||||
next_token = None
|
next_token = None
|
||||||
local_media_mxcs = []
|
|
||||||
remote_media_mxcs = []
|
|
||||||
for stream_ordering, content_json in txn:
|
for stream_ordering, content_json in txn:
|
||||||
next_token = stream_ordering
|
next_token = stream_ordering
|
||||||
content = json.loads(content_json)
|
content = json.loads(content_json)
|
||||||
|
@ -577,29 +643,4 @@ class RoomStore(SQLBaseStore):
|
||||||
else:
|
else:
|
||||||
remote_media_mxcs.append((hostname, media_id))
|
remote_media_mxcs.append((hostname, media_id))
|
||||||
|
|
||||||
# Now update all the tables to set the quarantined_by flag
|
return local_media_mxcs, remote_media_mxcs
|
||||||
|
|
||||||
txn.executemany("""
|
|
||||||
UPDATE local_media_repository
|
|
||||||
SET quarantined_by = ?
|
|
||||||
WHERE media_id = ?
|
|
||||||
""", ((quarantined_by, media_id) for media_id in local_media_mxcs))
|
|
||||||
|
|
||||||
txn.executemany(
|
|
||||||
"""
|
|
||||||
UPDATE remote_media_cache
|
|
||||||
SET quarantined_by = ?
|
|
||||||
WHERE media_origin = ? AND media_id = ?
|
|
||||||
""",
|
|
||||||
(
|
|
||||||
(quarantined_by, origin, media_id)
|
|
||||||
for origin, media_id in remote_media_mxcs
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
total_media_quarantined += len(local_media_mxcs)
|
|
||||||
total_media_quarantined += len(remote_media_mxcs)
|
|
||||||
|
|
||||||
return total_media_quarantined
|
|
||||||
|
|
||||||
return self.runInteraction("get_media_ids_in_room", _get_media_ids_in_room)
|
|
||||||
|
|
Loading…
Reference in a new issue