diff options
author | Erik Johnston <erikj@element.io> | 2024-07-05 13:04:27 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-07-05 13:04:27 +0100 |
commit | 8e9e6f1a0a98d132ba4e57c394eabc7750aead84 (patch) | |
tree | 71c727d7ced1b7588df6cee2015d4514c4b95f5b /synapse/api | |
parent | Finish up work to allow per-user feature flags (#17392) (diff) | |
download | synapse-8e9e6f1a0a98d132ba4e57c394eabc7750aead84.tar.xz |
Allow enabling sliding sync per-user (#17393)
Based on #17392
Diffstat (limited to 'synapse/api')
-rw-r--r-- | synapse/api/auth/__init__.py | 18 | ||||
-rw-r--r-- | synapse/api/auth/internal.py | 29 | ||||
-rw-r--r-- | synapse/api/auth/msc3861_delegated.py | 28 |
3 files changed, 74 insertions, 1 deletions
diff --git a/synapse/api/auth/__init__.py b/synapse/api/auth/__init__.py index 234dcf1ca4..d5241afe73 100644 --- a/synapse/api/auth/__init__.py +++ b/synapse/api/auth/__init__.py @@ -18,7 +18,7 @@ # [This file includes modifications made by New Vector Limited] # # -from typing import Optional, Tuple +from typing import TYPE_CHECKING, Optional, Tuple from typing_extensions import Protocol @@ -28,6 +28,9 @@ from synapse.appservice import ApplicationService from synapse.http.site import SynapseRequest from synapse.types import Requester +if TYPE_CHECKING: + from synapse.rest.admin.experimental_features import ExperimentalFeature + # guests always get this device id. GUEST_DEVICE_ID = "guest_device" @@ -87,6 +90,19 @@ class Auth(Protocol): AuthError if access is denied for the user in the access token """ + async def get_user_by_req_experimental_feature( + self, + request: SynapseRequest, + feature: "ExperimentalFeature", + allow_guest: bool = False, + allow_expired: bool = False, + allow_locked: bool = False, + ) -> Requester: + """Like `get_user_by_req`, except also checks if the user has access to + the experimental feature. If they don't returns a 404 unrecognized + request. + """ + async def validate_appservice_can_control_user_id( self, app_service: ApplicationService, user_id: str ) -> None: diff --git a/synapse/api/auth/internal.py b/synapse/api/auth/internal.py index 2878f3e6e9..9fd4db68e1 100644 --- a/synapse/api/auth/internal.py +++ b/synapse/api/auth/internal.py @@ -28,6 +28,7 @@ from synapse.api.errors import ( Codes, InvalidClientTokenError, MissingClientTokenError, + UnrecognizedRequestError, ) from synapse.http.site import SynapseRequest from synapse.logging.opentracing import active_span, force_tracing, start_active_span @@ -38,8 +39,10 @@ from . import GUEST_DEVICE_ID from .base import BaseAuth if TYPE_CHECKING: + from synapse.rest.admin.experimental_features import ExperimentalFeature from synapse.server import HomeServer + logger = logging.getLogger(__name__) @@ -106,6 +109,32 @@ class InternalAuth(BaseAuth): parent_span.set_tag("appservice_id", requester.app_service.id) return requester + async def get_user_by_req_experimental_feature( + self, + request: SynapseRequest, + feature: "ExperimentalFeature", + allow_guest: bool = False, + allow_expired: bool = False, + allow_locked: bool = False, + ) -> Requester: + try: + requester = await self.get_user_by_req( + request, + allow_guest=allow_guest, + allow_expired=allow_expired, + allow_locked=allow_locked, + ) + if await self.store.is_feature_enabled(requester.user.to_string(), feature): + return requester + + raise UnrecognizedRequestError(code=404) + except (AuthError, InvalidClientTokenError): + if feature.is_globally_enabled(self.hs.config): + # If its globally enabled then return the auth error + raise + + raise UnrecognizedRequestError(code=404) + @cancellable async def _wrapped_get_user_by_req( self, diff --git a/synapse/api/auth/msc3861_delegated.py b/synapse/api/auth/msc3861_delegated.py index 3146e1577c..f61b39ded7 100644 --- a/synapse/api/auth/msc3861_delegated.py +++ b/synapse/api/auth/msc3861_delegated.py @@ -40,6 +40,7 @@ from synapse.api.errors import ( OAuthInsufficientScopeError, StoreError, SynapseError, + UnrecognizedRequestError, ) from synapse.http.site import SynapseRequest from synapse.logging.context import make_deferred_yieldable @@ -48,6 +49,7 @@ from synapse.util import json_decoder from synapse.util.caches.cached_call import RetryOnExceptionCachedCall if TYPE_CHECKING: + from synapse.rest.admin.experimental_features import ExperimentalFeature from synapse.server import HomeServer logger = logging.getLogger(__name__) @@ -245,6 +247,32 @@ class MSC3861DelegatedAuth(BaseAuth): return requester + async def get_user_by_req_experimental_feature( + self, + request: SynapseRequest, + feature: "ExperimentalFeature", + allow_guest: bool = False, + allow_expired: bool = False, + allow_locked: bool = False, + ) -> Requester: + try: + requester = await self.get_user_by_req( + request, + allow_guest=allow_guest, + allow_expired=allow_expired, + allow_locked=allow_locked, + ) + if await self.store.is_feature_enabled(requester.user.to_string(), feature): + return requester + + raise UnrecognizedRequestError(code=404) + except (AuthError, InvalidClientTokenError): + if feature.is_globally_enabled(self.hs.config): + # If its globally enabled then return the auth error + raise + + raise UnrecognizedRequestError(code=404) + async def get_user_by_access_token( self, token: str, |