Skip to content
This repository has been archived by the owner on Apr 26, 2024. It is now read-only.

Add an admin API endpoint to protect media. #9086

Merged
merged 3 commits into from
Jan 15, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions changelog.d/9086.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Add an admin API for protecting local media from quarantine.
24 changes: 24 additions & 0 deletions docs/admin_api/media_admin_api.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* [Quarantining media by ID](#quarantining-media-by-id)
* [Quarantining media in a room](#quarantining-media-in-a-room)
* [Quarantining all media of a user](#quarantining-all-media-of-a-user)
* [Protecting media from being quarantined](#protecting-media-from-being-quarantined)
- [Delete local media](#delete-local-media)
* [Delete a specific local media](#delete-a-specific-local-media)
* [Delete local media by date or size](#delete-local-media-by-date-or-size)
Expand Down Expand Up @@ -123,6 +124,29 @@ The following fields are returned in the JSON response body:

* `num_quarantined`: integer - The number of media items successfully quarantined

## Protecting media from being quarantined

This API protects a single piece of local media from being quarantined using the
above APIs. This is useful for sticker packs and other shared media which you do
not want to get quarantined, especially when
[quarantining media in a room](#quarantining-media-in-a-room).

Request:

```
POST /_synapse/admin/v1/media/protect/<media_id>

{}
```

Where `media_id` is in the form of `abcdefg12345...`.

Response:

```json
{}
```

# Delete local media
This API deletes the *local* media from the disk of your own server.
This includes any local thumbnails and copies of media downloaded from
Expand Down
23 changes: 23 additions & 0 deletions synapse/rest/admin/media.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,28 @@ async def on_POST(self, request, server_name: str, media_id: str):
return 200, {}


class ProtectMediaByID(RestServlet):
"""Protect local media from being quarantined.
"""

PATTERNS = admin_patterns("/media/protect/(?P<media_id>[^/]+)")

def __init__(self, hs):
clokep marked this conversation as resolved.
Show resolved Hide resolved
self.store = hs.get_datastore()
self.auth = hs.get_auth()

async def on_POST(self, request, media_id: str):
requester = await self.auth.get_user_by_req(request)
await assert_user_is_admin(self.auth, requester.user)

logging.info("Protecting local media by ID: %s", media_id)

# Quarantine this media id
await self.store.mark_local_media_as_safe(media_id)

return 200, {}


class ListMediaInRoom(RestServlet):
"""Lists all of the media in a given room.
"""
Expand Down Expand Up @@ -230,6 +252,7 @@ def register_servlets_for_media_repo(hs, http_server):
QuarantineMediaInRoom(hs).register(http_server)
QuarantineMediaByID(hs).register(http_server)
QuarantineMediaByUser(hs).register(http_server)
ProtectMediaByID(hs).register(http_server)
ListMediaInRoom(hs).register(http_server)
DeleteMediaByID(hs).register(http_server)
DeleteMediaByDateSize(hs).register(http_server)
8 changes: 5 additions & 3 deletions tests/rest/admin/test_admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,8 +153,6 @@ class QuarantineMediaTestCase(unittest.HomeserverTestCase):
]

def prepare(self, reactor, clock, hs):
self.store = hs.get_datastore()

# Allow for uploading and downloading to/from the media repo
self.media_repo = hs.get_media_repository_resource()
self.download_resource = self.media_repo.children[b"download"]
Expand Down Expand Up @@ -428,7 +426,11 @@ def test_cannot_quarantine_safe_media(self):

# Mark the second item as safe from quarantine.
_, media_id_2 = server_and_media_id_2.split("/")
self.get_success(self.store.mark_local_media_as_safe(media_id_2))
# Quarantine the media
url = "/_synapse/admin/v1/media/protect/%s" % (urllib.parse.quote(media_id_2),)
channel = self.make_request("POST", url, access_token=admin_user_tok)
self.pump(1.0)
self.assertEqual(200, int(channel.code), msg=channel.result["body"])

# Quarantine all media by this user
url = "/_synapse/admin/v1/user/%s/media/quarantine" % urllib.parse.quote(
Expand Down