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

Commit

Permalink
Remove the deprecated BaseHandler. (#11005)
Browse files Browse the repository at this point in the history
The shared ratelimit function was replaced with a dedicated
RequestRatelimiter class (accessible from the HomeServer
object).

Other properties were copied to each sub-class that inherited
from BaseHandler.
  • Loading branch information
clokep committed Oct 8, 2021
1 parent 49a683d commit eb9ddc8
Show file tree
Hide file tree
Showing 24 changed files with 166 additions and 215 deletions.
1 change: 1 addition & 0 deletions changelog.d/11005.misc
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Remove the deprecated `BaseHandler` object.
86 changes: 86 additions & 0 deletions synapse/api/ratelimiting.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
from typing import Hashable, Optional, Tuple

from synapse.api.errors import LimitExceededError
from synapse.config.ratelimiting import RateLimitConfig
from synapse.storage.databases.main import DataStore
from synapse.types import Requester
from synapse.util import Clock
Expand Down Expand Up @@ -233,3 +234,88 @@ async def ratelimit(
raise LimitExceededError(
retry_after_ms=int(1000 * (time_allowed - time_now_s))
)


class RequestRatelimiter:
def __init__(
self,
store: DataStore,
clock: Clock,
rc_message: RateLimitConfig,
rc_admin_redaction: Optional[RateLimitConfig],
):
self.store = store
self.clock = clock

# The rate_hz and burst_count are overridden on a per-user basis
self.request_ratelimiter = Ratelimiter(
store=self.store, clock=self.clock, rate_hz=0, burst_count=0
)
self._rc_message = rc_message

# Check whether ratelimiting room admin message redaction is enabled
# by the presence of rate limits in the config
if rc_admin_redaction:
self.admin_redaction_ratelimiter: Optional[Ratelimiter] = Ratelimiter(
store=self.store,
clock=self.clock,
rate_hz=rc_admin_redaction.per_second,
burst_count=rc_admin_redaction.burst_count,
)
else:
self.admin_redaction_ratelimiter = None

async def ratelimit(
self,
requester: Requester,
update: bool = True,
is_admin_redaction: bool = False,
) -> None:
"""Ratelimits requests.
Args:
requester
update: Whether to record that a request is being processed.
Set to False when doing multiple checks for one request (e.g.
to check up front if we would reject the request), and set to
True for the last call for a given request.
is_admin_redaction: Whether this is a room admin/moderator
redacting an event. If so then we may apply different
ratelimits depending on config.
Raises:
LimitExceededError if the request should be ratelimited
"""
user_id = requester.user.to_string()

# The AS user itself is never rate limited.
app_service = self.store.get_app_service_by_user_id(user_id)
if app_service is not None:
return # do not ratelimit app service senders

messages_per_second = self._rc_message.per_second
burst_count = self._rc_message.burst_count

# Check if there is a per user override in the DB.
override = await self.store.get_ratelimit_for_user(user_id)
if override:
# If overridden with a null Hz then ratelimiting has been entirely
# disabled for the user
if not override.messages_per_second:
return

messages_per_second = override.messages_per_second
burst_count = override.burst_count

if is_admin_redaction and self.admin_redaction_ratelimiter:
# If we have separate config for admin redactions, use a separate
# ratelimiter as to not have user_ids clash
await self.admin_redaction_ratelimiter.ratelimit(requester, update=update)
else:
# Override rate and burst count per-user
await self.request_ratelimiter.ratelimit(
requester,
rate_hz=messages_per_second,
burst_count=burst_count,
update=update,
)
120 changes: 0 additions & 120 deletions synapse/handlers/_base.py

This file was deleted.

7 changes: 2 additions & 5 deletions synapse/handlers/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,15 @@
from synapse.types import JsonDict, RoomStreamToken, StateMap, UserID
from synapse.visibility import filter_events_for_client

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

logger = logging.getLogger(__name__)


class AdminHandler(BaseHandler):
class AdminHandler:
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.store = hs.get_datastore()
self.storage = hs.get_storage()
self.state_store = self.storage.state

Expand Down
8 changes: 4 additions & 4 deletions synapse/handlers/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,6 @@
UserDeactivatedError,
)
from synapse.api.ratelimiting import Ratelimiter
from synapse.handlers._base import BaseHandler
from synapse.handlers.ui_auth import (
INTERACTIVE_AUTH_CHECKERS,
UIAuthSessionDataConstants,
Expand Down Expand Up @@ -186,12 +185,13 @@ class LoginTokenAttributes:
auth_provider_id = attr.ib(type=str)


class AuthHandler(BaseHandler):
class AuthHandler:
SESSION_EXPIRE_MS = 48 * 60 * 60 * 1000

def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.store = hs.get_datastore()
self.auth = hs.get_auth()
self.clock = hs.get_clock()
self.checkers: Dict[str, UserInteractiveAuthChecker] = {}
for auth_checker_class in INTERACTIVE_AUTH_CHECKERS:
inst = auth_checker_class(hs)
Expand Down
6 changes: 2 additions & 4 deletions synapse/handlers/deactivate_account.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,19 +19,17 @@
from synapse.metrics.background_process_metrics import run_as_background_process
from synapse.types import Requester, UserID, create_requester

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

logger = logging.getLogger(__name__)


class DeactivateAccountHandler(BaseHandler):
class DeactivateAccountHandler:
"""Handler which deals with deactivating user accounts."""

def __init__(self, hs: "HomeServer"):
super().__init__(hs)
self.store = hs.get_datastore()
self.hs = hs
self._auth_handler = hs.get_auth_handler()
self._device_handler = hs.get_device_handler()
Expand Down
10 changes: 5 additions & 5 deletions synapse/handlers/device.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,6 @@
from synapse.util.metrics import measure_func
from synapse.util.retryutils import NotRetryingDestination

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

Expand All @@ -50,14 +48,16 @@
MAX_DEVICE_DISPLAY_NAME_LEN = 100


class DeviceWorkerHandler(BaseHandler):
class DeviceWorkerHandler:
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.clock = hs.get_clock()
self.hs = hs
self.store = hs.get_datastore()
self.notifier = hs.get_notifier()
self.state = hs.get_state_handler()
self.state_store = hs.get_storage().state
self._auth_handler = hs.get_auth_handler()
self.server_name = hs.hostname

@trace
async def get_devices_by_user(self, user_id: str) -> List[JsonDict]:
Expand Down
9 changes: 4 additions & 5 deletions synapse/handlers/directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,16 @@
from synapse.storage.databases.main.directory import RoomAliasMapping
from synapse.types import JsonDict, Requester, RoomAlias, UserID, get_domain_from_id

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer

logger = logging.getLogger(__name__)


class DirectoryHandler(BaseHandler):
class DirectoryHandler:
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.auth = hs.get_auth()
self.hs = hs
self.state = hs.get_state_handler()
self.appservice_handler = hs.get_application_service_handler()
self.event_creation_handler = hs.get_event_creation_handler()
Expand All @@ -51,6 +49,7 @@ def __init__(self, hs: "HomeServer"):
self.enable_room_list_search = hs.config.roomdirectory.enable_room_list_search
self.require_membership = hs.config.server.require_membership_for_aliases
self.third_party_event_rules = hs.get_third_party_event_rules()
self.server_name = hs.hostname

self.federation = hs.get_federation_client()
hs.get_federation_registry().register_query_handler(
Expand Down
12 changes: 5 additions & 7 deletions synapse/handlers/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,20 +25,18 @@
from synapse.types import JsonDict, UserID
from synapse.visibility import filter_events_for_client

from ._base import BaseHandler

if TYPE_CHECKING:
from synapse.server import HomeServer


logger = logging.getLogger(__name__)


class EventStreamHandler(BaseHandler):
class EventStreamHandler:
def __init__(self, hs: "HomeServer"):
super().__init__(hs)

self.store = hs.get_datastore()
self.clock = hs.get_clock()
self.hs = hs

self.notifier = hs.get_notifier()
self.state = hs.get_state_handler()
Expand Down Expand Up @@ -138,9 +136,9 @@ async def get_stream(
return chunk


class EventHandler(BaseHandler):
class EventHandler:
def __init__(self, hs: "HomeServer"):
super().__init__(hs)
self.store = hs.get_datastore()
self.storage = hs.get_storage()

async def get_event(
Expand Down
Loading

0 comments on commit eb9ddc8

Please sign in to comment.