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

Commit 57c2254

Browse files
committed
Don't load the media repo when configured to use an external media repo (#5754)
2 parents 2a21117 + 0b6fbb2 commit 57c2254

File tree

10 files changed

+188
-91
lines changed

10 files changed

+188
-91
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ _trial_temp*/
1616
/*.log
1717
/*.log.config
1818
/*.pid
19+
/.python-version
1920
/*.signing.key
2021
/env/
2122
/homeserver*.yaml

changelog.d/5754.feature

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Synapse will no longer serve any media repo admin endpoints when `enable_media_repo` is set to False in the configuration. If a media repo worker is used, the admin APIs relating to the media repo will be served from it instead.

docs/sample_config.yaml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -646,6 +646,13 @@ log_config: "CONFDIR/SERVERNAME.log.config"
646646

647647

648648

649+
## Media Store ##
650+
651+
# Enable the media store service in the Synapse master. Uncomment the
652+
# following if you are using a separate media store worker.
653+
#
654+
#enable_media_repo: false
655+
649656
# Directory where uploaded images and attachments are stored.
650657
#
651658
media_store_path: "DATADIR/media_store"

docs/workers.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -206,6 +206,13 @@ Handles the media repository. It can handle all endpoints starting with::
206206

207207
/_matrix/media/
208208

209+
And the following regular expressions matching media-specific administration
210+
APIs::
211+
212+
^/_synapse/admin/v1/purge_media_cache$
213+
^/_synapse/admin/v1/room/.*/media$
214+
^/_synapse/admin/v1/quarantine_media/.*$
215+
209216
You should also set ``enable_media_repo: False`` in the shared configuration
210217
file to stop the main synapse running background jobs related to managing the
211218
media repository.

synapse/app/media_repository.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
from synapse.config._base import ConfigError
2727
from synapse.config.homeserver import HomeServerConfig
2828
from synapse.config.logger import setup_logging
29+
from synapse.http.server import JsonResource
2930
from synapse.http.site import SynapseSite
3031
from synapse.logging.context import LoggingContext
3132
from synapse.metrics import METRICS_PREFIX, MetricsResource, RegistryProxy
@@ -35,6 +36,7 @@
3536
from synapse.replication.slave.storage.registration import SlavedRegistrationStore
3637
from synapse.replication.slave.storage.transactions import SlavedTransactionStore
3738
from synapse.replication.tcp.client import ReplicationClientHandler
39+
from synapse.rest.admin import register_servlets_for_media_repo
3840
from synapse.rest.media.v0.content_repository import ContentRepoResource
3941
from synapse.server import HomeServer
4042
from synapse.storage.engines import create_engine
@@ -71,13 +73,20 @@ def _listen_http(self, listener_config):
7173
resources[METRICS_PREFIX] = MetricsResource(RegistryProxy)
7274
elif name == "media":
7375
media_repo = self.get_media_repository_resource()
76+
77+
# We need to serve the admin servlets for media on the
78+
# worker.
79+
admin_resource = JsonResource(self, canonical_json=False)
80+
register_servlets_for_media_repo(self, admin_resource)
81+
7482
resources.update(
7583
{
7684
MEDIA_PREFIX: media_repo,
7785
LEGACY_MEDIA_PREFIX: media_repo,
7886
CONTENT_REPO_PREFIX: ContentRepoResource(
7987
self, self.config.uploads_path
8088
),
89+
"/_synapse/admin": admin_resource,
8190
}
8291
)
8392

synapse/config/repository.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15+
1516
import os
1617
from collections import namedtuple
1718

@@ -87,6 +88,18 @@ def parse_thumbnail_requirements(thumbnail_sizes):
8788

8889
class ContentRepositoryConfig(Config):
8990
def read_config(self, config, **kwargs):
91+
92+
# Only enable the media repo if either the media repo is enabled or the
93+
# current worker app is the media repo.
94+
if (
95+
self.enable_media_repo is False
96+
and config.worker_app != "synapse.app.media_repository"
97+
):
98+
self.can_load_media_repo = False
99+
return
100+
else:
101+
self.can_load_media_repo = True
102+
90103
self.max_upload_size = self.parse_size(config.get("max_upload_size", "10M"))
91104
self.max_image_pixels = self.parse_size(config.get("max_image_pixels", "32M"))
92105
self.max_spider_size = self.parse_size(config.get("max_spider_size", "10M"))
@@ -208,6 +221,13 @@ def generate_config_section(self, data_dir_path, **kwargs):
208221

209222
return (
210223
r"""
224+
## Media Store ##
225+
226+
# Enable the media store service in the Synapse master. Uncomment the
227+
# following if you are using a separate media store worker.
228+
#
229+
#enable_media_repo: false
230+
211231
# Directory where uploaded images and attachments are stored.
212232
#
213233
media_store_path: "%(media_store)s"

synapse/rest/admin/__init__.py

Lines changed: 12 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727

2828
import synapse
2929
from synapse.api.constants import Membership, UserTypes
30-
from synapse.api.errors import AuthError, Codes, NotFoundError, SynapseError
30+
from synapse.api.errors import Codes, NotFoundError, SynapseError
3131
from synapse.http.server import JsonResource
3232
from synapse.http.servlet import (
3333
RestServlet,
@@ -36,36 +36,19 @@
3636
parse_json_object_from_request,
3737
parse_string,
3838
)
39-
from synapse.rest.admin._base import assert_requester_is_admin, assert_user_is_admin
39+
from synapse.rest.admin._base import (
40+
assert_requester_is_admin,
41+
assert_user_is_admin,
42+
historical_admin_path_patterns,
43+
)
44+
from synapse.rest.admin.media import register_servlets_for_media_repo
4045
from synapse.rest.admin.server_notice_servlet import SendServerNoticeServlet
4146
from synapse.types import UserID, create_requester
4247
from synapse.util.versionstring import get_version_string
4348

4449
logger = logging.getLogger(__name__)
4550

4651

47-
def historical_admin_path_patterns(path_regex):
48-
"""Returns the list of patterns for an admin endpoint, including historical ones
49-
50-
This is a backwards-compatibility hack. Previously, the Admin API was exposed at
51-
various paths under /_matrix/client. This function returns a list of patterns
52-
matching those paths (as well as the new one), so that existing scripts which rely
53-
on the endpoints being available there are not broken.
54-
55-
Note that this should only be used for existing endpoints: new ones should just
56-
register for the /_synapse/admin path.
57-
"""
58-
return list(
59-
re.compile(prefix + path_regex)
60-
for prefix in (
61-
"^/_synapse/admin/v1",
62-
"^/_matrix/client/api/v1/admin",
63-
"^/_matrix/client/unstable/admin",
64-
"^/_matrix/client/r0/admin",
65-
)
66-
)
67-
68-
6952
class UsersRestServlet(RestServlet):
7053
PATTERNS = historical_admin_path_patterns("/users/(?P<user_id>[^/]*)")
7154

@@ -255,25 +238,6 @@ def on_GET(self, request, user_id):
255238
return (200, ret)
256239

257240

258-
class PurgeMediaCacheRestServlet(RestServlet):
259-
PATTERNS = historical_admin_path_patterns("/purge_media_cache")
260-
261-
def __init__(self, hs):
262-
self.media_repository = hs.get_media_repository()
263-
self.auth = hs.get_auth()
264-
265-
@defer.inlineCallbacks
266-
def on_POST(self, request):
267-
yield assert_requester_is_admin(self.auth, request)
268-
269-
before_ts = parse_integer(request, "before_ts", required=True)
270-
logger.info("before_ts: %r", before_ts)
271-
272-
ret = yield self.media_repository.delete_old_remote_media(before_ts)
273-
274-
return (200, ret)
275-
276-
277241
class PurgeHistoryRestServlet(RestServlet):
278242
PATTERNS = historical_admin_path_patterns(
279243
"/purge_history/(?P<room_id>[^/]*)(/(?P<event_id>[^/]+))?"
@@ -542,50 +506,6 @@ def on_POST(self, request, room_id):
542506
)
543507

544508

545-
class QuarantineMediaInRoom(RestServlet):
546-
"""Quarantines all media in a room so that no one can download it via
547-
this server.
548-
"""
549-
550-
PATTERNS = historical_admin_path_patterns("/quarantine_media/(?P<room_id>[^/]+)")
551-
552-
def __init__(self, hs):
553-
self.store = hs.get_datastore()
554-
self.auth = hs.get_auth()
555-
556-
@defer.inlineCallbacks
557-
def on_POST(self, request, room_id):
558-
requester = yield self.auth.get_user_by_req(request)
559-
yield assert_user_is_admin(self.auth, requester.user)
560-
561-
num_quarantined = yield self.store.quarantine_media_ids_in_room(
562-
room_id, requester.user.to_string()
563-
)
564-
565-
return (200, {"num_quarantined": num_quarantined})
566-
567-
568-
class ListMediaInRoom(RestServlet):
569-
"""Lists all of the media in a given room.
570-
"""
571-
572-
PATTERNS = historical_admin_path_patterns("/room/(?P<room_id>[^/]+)/media")
573-
574-
def __init__(self, hs):
575-
self.store = hs.get_datastore()
576-
577-
@defer.inlineCallbacks
578-
def on_GET(self, request, room_id):
579-
requester = yield self.auth.get_user_by_req(request)
580-
is_admin = yield self.auth.is_server_admin(requester.user)
581-
if not is_admin:
582-
raise AuthError(403, "You are not a server admin")
583-
584-
local_mxcs, remote_mxcs = yield self.store.get_media_mxcs_in_room(room_id)
585-
586-
return (200, {"local": local_mxcs, "remote": remote_mxcs})
587-
588-
589509
class ResetPasswordRestServlet(RestServlet):
590510
"""Post request to allow an administrator reset password for a user.
591511
This needs user to have administrator access in Synapse.
@@ -825,7 +745,6 @@ def register_servlets(hs, http_server):
825745
def register_servlets_for_client_rest_resource(hs, http_server):
826746
"""Register only the servlets which need to be exposed on /_matrix/client/xxx"""
827747
WhoisRestServlet(hs).register(http_server)
828-
PurgeMediaCacheRestServlet(hs).register(http_server)
829748
PurgeHistoryStatusRestServlet(hs).register(http_server)
830749
DeactivateAccountRestServlet(hs).register(http_server)
831750
PurgeHistoryRestServlet(hs).register(http_server)
@@ -834,10 +753,13 @@ def register_servlets_for_client_rest_resource(hs, http_server):
834753
GetUsersPaginatedRestServlet(hs).register(http_server)
835754
SearchUsersRestServlet(hs).register(http_server)
836755
ShutdownRoomRestServlet(hs).register(http_server)
837-
QuarantineMediaInRoom(hs).register(http_server)
838-
ListMediaInRoom(hs).register(http_server)
839756
UserRegisterServlet(hs).register(http_server)
840757
DeleteGroupAdminRestServlet(hs).register(http_server)
841758
AccountValidityRenewServlet(hs).register(http_server)
759+
760+
# Load the media repo ones if we're using them.
761+
if hs.config.can_load_media_repo:
762+
register_servlets_for_media_repo(hs, http_server)
763+
842764
# don't add more things here: new servlets should only be exposed on
843765
# /_synapse/admin so should not go here. Instead register them in AdminRestResource.

synapse/rest/admin/_base.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,36 @@
1212
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1313
# See the License for the specific language governing permissions and
1414
# limitations under the License.
15+
16+
import re
17+
1518
from twisted.internet import defer
1619

1720
from synapse.api.errors import AuthError
1821

1922

23+
def historical_admin_path_patterns(path_regex):
24+
"""Returns the list of patterns for an admin endpoint, including historical ones
25+
26+
This is a backwards-compatibility hack. Previously, the Admin API was exposed at
27+
various paths under /_matrix/client. This function returns a list of patterns
28+
matching those paths (as well as the new one), so that existing scripts which rely
29+
on the endpoints being available there are not broken.
30+
31+
Note that this should only be used for existing endpoints: new ones should just
32+
register for the /_synapse/admin path.
33+
"""
34+
return list(
35+
re.compile(prefix + path_regex)
36+
for prefix in (
37+
"^/_synapse/admin/v1",
38+
"^/_matrix/client/api/v1/admin",
39+
"^/_matrix/client/unstable/admin",
40+
"^/_matrix/client/r0/admin",
41+
)
42+
)
43+
44+
2045
@defer.inlineCallbacks
2146
def assert_requester_is_admin(auth, request):
2247
"""Verify that the requester is an admin user

0 commit comments

Comments
 (0)