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

Prevent expired events from being filtered out when retention is disabled #12611

Merged
merged 16 commits into from
May 23, 2022
Merged
2 changes: 1 addition & 1 deletion synapse/handlers/pagination.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,7 +239,7 @@ async def purge_history_for_rooms_in_range(
# defined in the server's configuration, we can safely assume that's the
# case and use it for this room.
max_lifetime = (
retention_policy["max_lifetime"] or self._retention_default_max_lifetime
retention_policy.max_lifetime or self._retention_default_max_lifetime
)

# Cap the effective max_lifetime to be within the range allowed in the
Expand Down
39 changes: 18 additions & 21 deletions synapse/storage/databases/main/room.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
from synapse.storage.databases.main.cache import CacheInvalidationWorkerStore
from synapse.storage.types import Cursor
from synapse.storage.util.id_generators import IdGenerator
from synapse.types import JsonDict, ThirdPartyInstanceID
from synapse.types import JsonDict, ThirdPartyInstanceID, RetentionPolicy
from synapse.util import json_encoder
from synapse.util.caches.descriptors import cached
from synapse.util.stringutils import MXC_REGEX
Expand Down Expand Up @@ -709,8 +709,8 @@ async def get_retention_policy_for_room(
the 'max_lifetime' if no default policy has been defined in the server's
configuration).

If support for retention policies is disabled, a policy with a 'min_lifetime' and 'max_lifetime'
of None is returned.
If support for retention policies is disabled, a policy with a 'min_lifetime' and
'max_lifetime' of None is returned.

Args:
room_id: The ID of the room to get the retention policy of.
Expand All @@ -722,7 +722,7 @@ async def get_retention_policy_for_room(
# maximum. This prevents incorrectly filtering out events when sending to
# the client.
if not self.config.retention.retention_enabled:
return {"min_lifetime": None, "max_lifetime": None}
return RetentionPolicy()

def get_retention_policy_for_room_txn(
txn: LoggingTransaction,
Expand All @@ -746,10 +746,10 @@ def get_retention_policy_for_room_txn(
# If we don't know this room ID, ret will be None, in this case return the default
# policy.
if not ret:
return {
"min_lifetime": self.config.retention.retention_default_min_lifetime,
"max_lifetime": self.config.retention.retention_default_max_lifetime,
}
return RetentionPolicy(
min_lifetime=self.config.retention.retention_default_min_lifetime,
max_lifetime=self.config.retention.retention_default_max_lifetime,
)

min_lifetime = ret[0]["min_lifetime"]
max_lifetime = ret[0]["max_lifetime"]
Expand All @@ -764,10 +764,10 @@ def get_retention_policy_for_room_txn(
if max_lifetime is None:
max_lifetime = self.config.retention.retention_default_max_lifetime

return {
"min_lifetime": min_lifetime,
"max_lifetime": max_lifetime,
}
return RetentionPolicy(
min_lifetime=min_lifetime,
max_lifetime=max_lifetime,
)

async def get_media_mxcs_in_room(self, room_id: str) -> Tuple[List[str], List[str]]:
"""Retrieves all the local and remote media MXC URIs in a given room
Expand Down Expand Up @@ -1004,7 +1004,7 @@ def _quarantine_media_txn(

async def get_rooms_for_retention_period_in_range(
self, min_ms: Optional[int], max_ms: Optional[int], include_null: bool = False
) -> Dict[str, Dict[str, Optional[int]]]:
) -> Dict[str, RetentionPolicy]:
"""Retrieves all of the rooms within the given retention range.

Optionally includes the rooms which don't have a retention policy.
Expand Down Expand Up @@ -1057,10 +1057,10 @@ def get_rooms_for_retention_period_in_range_txn(
rooms_dict = {}

for row in rows:
rooms_dict[row["room_id"]] = {
"min_lifetime": row["min_lifetime"],
"max_lifetime": row["max_lifetime"],
}
rooms_dict[row["room_id"]] = RetentionPolicy(
min_lifetime=row["min_lifetime"],
max_lifetime=row["max_lifetime"],
)

if include_null:
# If required, do a second query that retrieves all of the rooms we know
Expand All @@ -1075,10 +1075,7 @@ def get_rooms_for_retention_period_in_range_txn(
# policy in its state), add it with a null policy.
for row in rows:
if row["room_id"] not in rooms_dict:
rooms_dict[row["room_id"]] = {
"min_lifetime": None,
"max_lifetime": None,
}
rooms_dict[row["room_id"]] = RetentionPolicy()

return rooms_dict

Expand Down
6 changes: 6 additions & 0 deletions synapse/types.py
Original file line number Diff line number Diff line change
Expand Up @@ -916,3 +916,9 @@ class UserProfile(TypedDict):
user_id: str
display_name: Optional[str]
avatar_url: Optional[str]


@attr.s(auto_attribs=True, frozen=True)
babolivier marked this conversation as resolved.
Show resolved Hide resolved
class RetentionPolicy:
min_lifetime: Optional[int] = None
max_lifetime: Optional[int] = None
6 changes: 3 additions & 3 deletions synapse/visibility.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
from synapse.events.utils import prune_event
from synapse.storage import Storage
from synapse.storage.state import StateFilter
from synapse.types import StateMap, get_domain_from_id
from synapse.types import StateMap, get_domain_from_id, RetentionPolicy

logger = logging.getLogger(__name__)

Expand Down Expand Up @@ -94,7 +94,7 @@ async def filter_events_for_client(

if filter_send_to_client:
room_ids = {e.room_id for e in events}
retention_policies = {}
retention_policies: Dict[str, RetentionPolicy] = {}

for room_id in room_ids:
retention_policies[
Expand Down Expand Up @@ -137,7 +137,7 @@ def allowed(event: EventBase) -> Optional[EventBase]:
# events.
if not event.is_state():
retention_policy = retention_policies[event.room_id]
max_lifetime = retention_policy.get("max_lifetime")
max_lifetime = retention_policy.max_lifetime

if max_lifetime is not None:
oldest_allowed_ts = storage.main.clock.time_msec() - max_lifetime
Expand Down