16
16
17
17
import jsonschema
18
18
19
- from synapse .api .constants import MAX_ALIAS_LENGTH , EventTypes , Membership
19
+ from synapse .api .constants import (
20
+ MAX_ALIAS_LENGTH ,
21
+ EventContentFields ,
22
+ EventTypes ,
23
+ Membership ,
24
+ )
20
25
from synapse .api .errors import Codes , SynapseError
21
26
from synapse .api .room_versions import EventFormatVersions
22
27
from synapse .config .homeserver import HomeServerConfig
@@ -88,27 +93,27 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
88
93
Codes .INVALID_PARAM ,
89
94
)
90
95
91
- if event .type == EventTypes .Retention :
96
+ elif event .type == EventTypes .Retention :
92
97
self ._validate_retention (event )
93
98
94
- if event .type == EventTypes .ServerACL :
99
+ elif event .type == EventTypes .ServerACL :
95
100
if not server_matches_acl_event (config .server .server_name , event ):
96
101
raise SynapseError (
97
102
400 , "Can't create an ACL event that denies the local server"
98
103
)
99
104
100
- if event .type == EventTypes .PowerLevels :
105
+ elif event .type == EventTypes .PowerLevels :
101
106
try :
102
107
jsonschema .validate (
103
108
instance = event .content ,
104
109
schema = POWER_LEVELS_SCHEMA ,
105
- cls = plValidator ,
110
+ cls = POWER_LEVELS_VALIDATOR ,
106
111
)
107
112
except jsonschema .ValidationError as e :
108
113
if e .path :
109
114
# example: "users_default": '0' is not of type 'integer'
110
115
# cast safety: path entries can be integers, if we fail to validate
111
- # items in an array. However the POWER_LEVELS_SCHEMA doesn't expect
116
+ # items in an array. However, the POWER_LEVELS_SCHEMA doesn't expect
112
117
# to see any arrays.
113
118
message = (
114
119
'"' + cast (str , e .path [- 1 ]) + '": ' + e .message # noqa: B306
@@ -125,6 +130,19 @@ def validate_new(self, event: EventBase, config: HomeServerConfig) -> None:
125
130
errcode = Codes .BAD_JSON ,
126
131
)
127
132
133
+ # If the event contains a mentions key, validate it.
134
+ if (
135
+ EventContentFields .MSC3952_MENTIONS in event .content
136
+ and config .experimental .msc3952_intentional_mentions
137
+ ):
138
+ mentions = event .content [EventContentFields .MSC3952_MENTIONS ]
139
+ try :
140
+ jsonschema .validate (
141
+ instance = mentions , schema = MENTIONS_SCHEMA , cls = MENTIONS_VALIDATOR
142
+ )
143
+ except jsonschema .ValidationError as e :
144
+ raise SynapseError (400 , e .message )
145
+
128
146
def _validate_retention (self , event : EventBase ) -> None :
129
147
"""Checks that an event that defines the retention policy for a room respects the
130
148
format enforced by the spec.
@@ -252,11 +270,26 @@ def _ensure_state_event(self, event: Union[EventBase, EventBuilder]) -> None:
252
270
},
253
271
}
254
272
273
+ MENTIONS_SCHEMA = {
274
+ "type" : "object" ,
275
+ "properties" : {
276
+ "user_ids" : {
277
+ "type" : "array" ,
278
+ "items" : {
279
+ "type" : "string" ,
280
+ },
281
+ },
282
+ "room" : {
283
+ "type" : "boolean" ,
284
+ },
285
+ },
286
+ }
287
+
255
288
256
289
# This could return something newer than Draft 7, but that's the current "latest"
257
290
# validator.
258
- def _create_power_level_validator ( ) -> Type [jsonschema .Draft7Validator ]:
259
- validator = jsonschema .validators .validator_for (POWER_LEVELS_SCHEMA )
291
+ def _create_validator ( schema : JsonDict ) -> Type [jsonschema .Draft7Validator ]:
292
+ validator = jsonschema .validators .validator_for (schema )
260
293
261
294
# by default jsonschema does not consider a frozendict to be an object so
262
295
# we need to use a custom type checker
@@ -268,4 +301,5 @@ def _create_power_level_validator() -> Type[jsonschema.Draft7Validator]:
268
301
return jsonschema .validators .extend (validator , type_checker = type_checker )
269
302
270
303
271
- plValidator = _create_power_level_validator ()
304
+ POWER_LEVELS_VALIDATOR = _create_validator (POWER_LEVELS_SCHEMA )
305
+ MENTIONS_VALIDATOR = _create_validator (MENTIONS_SCHEMA )
0 commit comments