This repository was archived by the owner on Apr 26, 2024. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Allow selecting "prejoin" events by state keys #14642
Merged
Merged
Changes from 8 commits
Commits
Show all changes
15 commits
Select commit
Hold shift + click to select a range
f03b305
Declare new config
c801ce7
Parse new config
8ed2d93
Read new config
eb0bbbe
Don't use trial/our TestCase where it's not needed
c6199a3
Helper to upsert to event fields
ddc563c
Use helper when adding invite/knock state
33a559f
Changelog
a5f6178
Merge branch 'develop' into dmr/more-specific-prejoin-state
d4b86c1
Merge remote-tracking branch 'origin/develop' into dmr/more-specific-…
fe30c5d
Move StateFilter tests
1bc0f13
Add extra methods to StateFilter
11124ed
Use StateFilter
af032d2
Ensure test file enforces typed defs; alphabetise
837f6c2
Workaround surprising get_current_state_ids
23ca964
Whoops, fix mypy
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Allow selecting "prejoin" events by state keys in addition to event types. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change | ||||||
---|---|---|---|---|---|---|---|---|
|
@@ -13,7 +13,9 @@ | |||||||
# limitations under the License. | ||||||||
|
||||||||
import logging | ||||||||
from typing import Any, Iterable | ||||||||
from typing import Any, Container, Dict, Iterable, Mapping, Optional, Set, Tuple, Type | ||||||||
|
||||||||
import attr | ||||||||
|
||||||||
from synapse.api.constants import EventTypes | ||||||||
from synapse.config._base import Config, ConfigError | ||||||||
|
@@ -23,19 +25,63 @@ | |||||||
logger = logging.getLogger(__name__) | ||||||||
|
||||||||
|
||||||||
@attr.s(auto_attribs=True) | ||||||||
class StateKeyFilter(Container[str]): | ||||||||
"""A simpler version of StateFilter which ignores event types. | ||||||||
|
||||||||
Represents an optional constraint that state_keys must belong to a given set of | ||||||||
strings called `options`. An empty set of `options` means that there are no | ||||||||
restrictions. | ||||||||
""" | ||||||||
|
||||||||
options: Set[str] | ||||||||
|
||||||||
@classmethod | ||||||||
def any(cls: Type["StateKeyFilter"]) -> "StateKeyFilter": | ||||||||
return cls(set()) | ||||||||
|
||||||||
@classmethod | ||||||||
def only(cls: Type["StateKeyFilter"], state_key: str) -> "StateKeyFilter": | ||||||||
return cls({state_key}) | ||||||||
|
||||||||
def __contains__(self, state_key: object) -> bool: | ||||||||
return not self.options or state_key in self.options | ||||||||
|
||||||||
def add(self, state_key: Optional[str]) -> None: | ||||||||
if state_key is None: | ||||||||
self.options = set() | ||||||||
elif self.options: | ||||||||
self.options.add(state_key) | ||||||||
|
||||||||
|
||||||||
class ApiConfig(Config): | ||||||||
section = "api" | ||||||||
|
||||||||
room_prejoin_state: Mapping[str, StateKeyFilter] | ||||||||
track_puppetted_users_ips: bool | ||||||||
|
||||||||
def read_config(self, config: JsonDict, **kwargs: Any) -> None: | ||||||||
validate_config(_MAIN_SCHEMA, config, ()) | ||||||||
self.room_prejoin_state = list(self._get_prejoin_state_types(config)) | ||||||||
self.room_prejoin_state = self._build_prejoin_state(config) | ||||||||
self.track_puppeted_user_ips = config.get("track_puppeted_user_ips", False) | ||||||||
|
||||||||
def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: | ||||||||
"""Get the event types to include in the prejoin state | ||||||||
|
||||||||
Parses the config and returns an iterable of the event types to be included. | ||||||||
""" | ||||||||
def _build_prejoin_state(self, config: JsonDict) -> Dict[str, StateKeyFilter]: | ||||||||
prejoin_events = {} | ||||||||
for event_type, state_key in self._get_prejoin_state_entries(config): | ||||||||
if event_type not in prejoin_events: | ||||||||
if state_key is None: | ||||||||
filter = StateKeyFilter.any() | ||||||||
else: | ||||||||
filter = StateKeyFilter.only(state_key) | ||||||||
prejoin_events[event_type] = filter | ||||||||
else: | ||||||||
prejoin_events[event_type].add(state_key) | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Yes, if someone specifies an entry consisting only of an event type.
No, it's a valid input that's explicitly handled by Lines 50 to 52 in c801ce7
|
||||||||
return prejoin_events | ||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This wasn't particularly neat, but it gets the job done. |
||||||||
|
||||||||
def _get_prejoin_state_entries( | ||||||||
self, config: JsonDict | ||||||||
) -> Iterable[Tuple[str, Optional[str]]]: | ||||||||
"""Get the event types and state keys to include in the prejoin state.""" | ||||||||
room_prejoin_state_config = config.get("room_prejoin_state") or {} | ||||||||
|
||||||||
# backwards-compatibility support for room_invite_state_types | ||||||||
|
@@ -50,33 +96,39 @@ def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: | |||||||
|
||||||||
logger.warning(_ROOM_INVITE_STATE_TYPES_WARNING) | ||||||||
|
||||||||
yield from config["room_invite_state_types"] | ||||||||
for event_type in config["room_invite_state_types"]: | ||||||||
yield event_type, None | ||||||||
return | ||||||||
|
||||||||
if not room_prejoin_state_config.get("disable_default_event_types"): | ||||||||
yield from _DEFAULT_PREJOIN_STATE_TYPES | ||||||||
yield from _DEFAULT_PREJOIN_STATE_TYPES_AND_STATE_KEYS | ||||||||
|
||||||||
yield from room_prejoin_state_config.get("additional_event_types", []) | ||||||||
for entry in room_prejoin_state_config.get("additional_event_types", []): | ||||||||
if isinstance(entry, str): | ||||||||
yield entry, None | ||||||||
else: | ||||||||
yield entry | ||||||||
|
||||||||
|
||||||||
_ROOM_INVITE_STATE_TYPES_WARNING = """\ | ||||||||
WARNING: The 'room_invite_state_types' configuration setting is now deprecated, | ||||||||
and replaced with 'room_prejoin_state'. New features may not work correctly | ||||||||
unless 'room_invite_state_types' is removed. See the sample configuration file for | ||||||||
details of 'room_prejoin_state'. | ||||||||
unless 'room_invite_state_types' is removed. See the config documentation at | ||||||||
https://matrix-org.github.io/synapse/latest/usage/configuration/config_documentation.html#room_prejoin_state | ||||||||
for details of 'room_prejoin_state'. | ||||||||
-------------------------------------------------------------------------------- | ||||||||
""" | ||||||||
|
||||||||
_DEFAULT_PREJOIN_STATE_TYPES = [ | ||||||||
EventTypes.JoinRules, | ||||||||
EventTypes.CanonicalAlias, | ||||||||
EventTypes.RoomAvatar, | ||||||||
EventTypes.RoomEncryption, | ||||||||
EventTypes.Name, | ||||||||
_DEFAULT_PREJOIN_STATE_TYPES_AND_STATE_KEYS = [ | ||||||||
(EventTypes.JoinRules, ""), | ||||||||
(EventTypes.CanonicalAlias, ""), | ||||||||
(EventTypes.RoomAvatar, ""), | ||||||||
(EventTypes.RoomEncryption, ""), | ||||||||
(EventTypes.Name, ""), | ||||||||
# Per MSC1772. | ||||||||
EventTypes.Create, | ||||||||
(EventTypes.Create, ""), | ||||||||
# Per MSC3173. | ||||||||
EventTypes.Topic, | ||||||||
(EventTypes.Topic, ""), | ||||||||
] | ||||||||
|
||||||||
|
||||||||
|
@@ -90,7 +142,17 @@ def _get_prejoin_state_types(self, config: JsonDict) -> Iterable[str]: | |||||||
"disable_default_event_types": {"type": "boolean"}, | ||||||||
"additional_event_types": { | ||||||||
"type": "array", | ||||||||
"items": {"type": "string"}, | ||||||||
"items": { | ||||||||
"oneOf": [ | ||||||||
{"type": "string"}, | ||||||||
{ | ||||||||
"type": "array", | ||||||||
"items": {"type": "string"}, | ||||||||
"minItems": 2, | ||||||||
"maxItems": 2, | ||||||||
}, | ||||||||
], | ||||||||
}, | ||||||||
}, | ||||||||
}, | ||||||||
}, | ||||||||
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.