Skip to content

Commit 8e9e6f1

Browse files
authored
Allow enabling sliding sync per-user (#17393)
Based on #17392
1 parent 57538eb commit 8e9e6f1

File tree

7 files changed

+89
-6
lines changed

7 files changed

+89
-6
lines changed

changelog.d/17393.misc

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Allow enabling sliding sync per-user.

docs/admin_api/experimental_features.md

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ This API allows a server administrator to enable or disable some experimental fe
44
basis. The currently supported features are:
55
- [MSC3881](https://github.com/matrix-org/matrix-spec-proposals/pull/3881): enable remotely toggling push notifications
66
for another client
7+
- [MSC3575](https://github.com/matrix-org/matrix-spec-proposals/pull/3575): enable experimental sliding sync support
78

89
To use it, you will need to authenticate by providing an `access_token`
910
for a server admin: see [Admin API](../usage/administration/admin_api/).

synapse/api/auth/__init__.py

+17-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
# [This file includes modifications made by New Vector Limited]
1919
#
2020
#
21-
from typing import Optional, Tuple
21+
from typing import TYPE_CHECKING, Optional, Tuple
2222

2323
from typing_extensions import Protocol
2424

@@ -28,6 +28,9 @@
2828
from synapse.http.site import SynapseRequest
2929
from synapse.types import Requester
3030

31+
if TYPE_CHECKING:
32+
from synapse.rest.admin.experimental_features import ExperimentalFeature
33+
3134
# guests always get this device id.
3235
GUEST_DEVICE_ID = "guest_device"
3336

@@ -87,6 +90,19 @@ async def get_user_by_req(
8790
AuthError if access is denied for the user in the access token
8891
"""
8992

93+
async def get_user_by_req_experimental_feature(
94+
self,
95+
request: SynapseRequest,
96+
feature: "ExperimentalFeature",
97+
allow_guest: bool = False,
98+
allow_expired: bool = False,
99+
allow_locked: bool = False,
100+
) -> Requester:
101+
"""Like `get_user_by_req`, except also checks if the user has access to
102+
the experimental feature. If they don't returns a 404 unrecognized
103+
request.
104+
"""
105+
90106
async def validate_appservice_can_control_user_id(
91107
self, app_service: ApplicationService, user_id: str
92108
) -> None:

synapse/api/auth/internal.py

+29
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
Codes,
2929
InvalidClientTokenError,
3030
MissingClientTokenError,
31+
UnrecognizedRequestError,
3132
)
3233
from synapse.http.site import SynapseRequest
3334
from synapse.logging.opentracing import active_span, force_tracing, start_active_span
@@ -38,8 +39,10 @@
3839
from .base import BaseAuth
3940

4041
if TYPE_CHECKING:
42+
from synapse.rest.admin.experimental_features import ExperimentalFeature
4143
from synapse.server import HomeServer
4244

45+
4346
logger = logging.getLogger(__name__)
4447

4548

@@ -106,6 +109,32 @@ async def get_user_by_req(
106109
parent_span.set_tag("appservice_id", requester.app_service.id)
107110
return requester
108111

112+
async def get_user_by_req_experimental_feature(
113+
self,
114+
request: SynapseRequest,
115+
feature: "ExperimentalFeature",
116+
allow_guest: bool = False,
117+
allow_expired: bool = False,
118+
allow_locked: bool = False,
119+
) -> Requester:
120+
try:
121+
requester = await self.get_user_by_req(
122+
request,
123+
allow_guest=allow_guest,
124+
allow_expired=allow_expired,
125+
allow_locked=allow_locked,
126+
)
127+
if await self.store.is_feature_enabled(requester.user.to_string(), feature):
128+
return requester
129+
130+
raise UnrecognizedRequestError(code=404)
131+
except (AuthError, InvalidClientTokenError):
132+
if feature.is_globally_enabled(self.hs.config):
133+
# If its globally enabled then return the auth error
134+
raise
135+
136+
raise UnrecognizedRequestError(code=404)
137+
109138
@cancellable
110139
async def _wrapped_get_user_by_req(
111140
self,

synapse/api/auth/msc3861_delegated.py

+28
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
OAuthInsufficientScopeError,
4141
StoreError,
4242
SynapseError,
43+
UnrecognizedRequestError,
4344
)
4445
from synapse.http.site import SynapseRequest
4546
from synapse.logging.context import make_deferred_yieldable
@@ -48,6 +49,7 @@
4849
from synapse.util.caches.cached_call import RetryOnExceptionCachedCall
4950

5051
if TYPE_CHECKING:
52+
from synapse.rest.admin.experimental_features import ExperimentalFeature
5153
from synapse.server import HomeServer
5254

5355
logger = logging.getLogger(__name__)
@@ -245,6 +247,32 @@ async def get_user_by_req(
245247

246248
return requester
247249

250+
async def get_user_by_req_experimental_feature(
251+
self,
252+
request: SynapseRequest,
253+
feature: "ExperimentalFeature",
254+
allow_guest: bool = False,
255+
allow_expired: bool = False,
256+
allow_locked: bool = False,
257+
) -> Requester:
258+
try:
259+
requester = await self.get_user_by_req(
260+
request,
261+
allow_guest=allow_guest,
262+
allow_expired=allow_expired,
263+
allow_locked=allow_locked,
264+
)
265+
if await self.store.is_feature_enabled(requester.user.to_string(), feature):
266+
return requester
267+
268+
raise UnrecognizedRequestError(code=404)
269+
except (AuthError, InvalidClientTokenError):
270+
if feature.is_globally_enabled(self.hs.config):
271+
# If its globally enabled then return the auth error
272+
raise
273+
274+
raise UnrecognizedRequestError(code=404)
275+
248276
async def get_user_by_access_token(
249277
self,
250278
token: str,

synapse/rest/admin/experimental_features.py

+3
Original file line numberDiff line numberDiff line change
@@ -42,10 +42,13 @@ class ExperimentalFeature(str, Enum):
4242
"""
4343

4444
MSC3881 = "msc3881"
45+
MSC3575 = "msc3575"
4546

4647
def is_globally_enabled(self, config: "HomeServerConfig") -> bool:
4748
if self is ExperimentalFeature.MSC3881:
4849
return config.experimental.msc3881_enabled
50+
if self is ExperimentalFeature.MSC3575:
51+
return config.experimental.msc3575_enabled
4952

5053
assert_never(self)
5154

synapse/rest/client/sync.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
)
5454
from synapse.http.site import SynapseRequest
5555
from synapse.logging.opentracing import trace_with_opname
56+
from synapse.rest.admin.experimental_features import ExperimentalFeature
5657
from synapse.types import JsonDict, Requester, StreamToken
5758
from synapse.types.rest.client import SlidingSyncBody
5859
from synapse.util import json_decoder
@@ -673,7 +674,9 @@ def __init__(self, hs: "HomeServer"):
673674
)
674675

675676
async def on_GET(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
676-
requester = await self.auth.get_user_by_req(request, allow_guest=True)
677+
requester = await self.auth.get_user_by_req_experimental_feature(
678+
request, allow_guest=True, feature=ExperimentalFeature.MSC3575
679+
)
677680
user = requester.user
678681
device_id = requester.device_id
679682

@@ -873,7 +876,10 @@ def __init__(self, hs: "HomeServer"):
873876
self.event_serializer = hs.get_event_client_serializer()
874877

875878
async def on_POST(self, request: SynapseRequest) -> Tuple[int, JsonDict]:
876-
requester = await self.auth.get_user_by_req(request, allow_guest=True)
879+
requester = await self.auth.get_user_by_req_experimental_feature(
880+
request, allow_guest=True, feature=ExperimentalFeature.MSC3575
881+
)
882+
877883
user = requester.user
878884
device_id = requester.device_id
879885

@@ -1051,6 +1057,5 @@ async def encode_rooms(
10511057
def register_servlets(hs: "HomeServer", http_server: HttpServer) -> None:
10521058
SyncRestServlet(hs).register(http_server)
10531059

1054-
if hs.config.experimental.msc3575_enabled:
1055-
SlidingSyncRestServlet(hs).register(http_server)
1056-
SlidingSyncE2eeRestServlet(hs).register(http_server)
1060+
SlidingSyncRestServlet(hs).register(http_server)
1061+
SlidingSyncE2eeRestServlet(hs).register(http_server)

0 commit comments

Comments
 (0)