Skip to content

Commit 7b81908

Browse files
feat: update tests to pass with room v11
1 parent 1be04cc commit 7b81908

7 files changed

Lines changed: 87 additions & 26 deletions

File tree

.github/workflows/pipeline.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ jobs:
8383
if [[ -z "$BRANCH_NAME" || $BRANCH_NAME =~ ^refs/pull/.* ]]; then
8484
continue
8585
fi
86-
(wget -O - "https://github.com/element-hq/synapse/archive/$BRANCH_NAME.tar.gz" \
86+
(wget -O - "https://github.com/famedly/synapse/archive/$BRANCH_NAME.tar.gz" \
8787
| tar -xz --strip-components=1 -C /src/) \
8888
&& echo "Successfully downloaded and extracted $BRANCH_NAME.tar.gz" \
8989
&& break

lib/Protocol/Matrix.pm

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -266,18 +266,46 @@ my %ALLOWED_CONTENT_BY_TYPE = (
266266

267267
sub redact_event
268268
{
269-
my ( $event ) = @_;
269+
my ( $event, $room_version ) = @_;
270+
$room_version //= 1;
270271

271272
defined( my $type = $event->{type} ) or
272273
croak "Event requires a 'type'";
273274

275+
delete $event->{redacts};
274276
my $old_content = delete $event->{content};
275277
my $old_unsigned = delete $event->{unsigned};
276278

277279
$ALLOWED_KEYS{$_} or delete $event->{$_} for keys %$event;
278280

279281
my $new_content = $event->{content} = {};
280282

283+
# Room version 11+ uses updated redaction rules:
284+
# - m.room.create: entire content property is preserved
285+
# - m.room.power_levels: 'invite' is also preserved
286+
# - m.room.member: 'third_party_invite.signed' is also preserved
287+
# - m.room.redaction: 'redacts' is also preserved
288+
if( defined $room_version and $room_version =~ /\A[0-9]+\z/ and $room_version >= 11 ) {
289+
if( $type eq 'm.room.create' ) {
290+
%$new_content = %{ $old_content // {} };
291+
$event->{unsigned}{age_ts} = $old_unsigned->{age_ts} if exists $old_unsigned->{age_ts};
292+
return;
293+
}
294+
if( $type eq 'm.room.power_levels' ) {
295+
exists $old_content->{invite} and $new_content->{invite} = $old_content->{invite};
296+
}
297+
if( $type eq 'm.room.member' ) {
298+
my $tpi = $old_content->{third_party_invite};
299+
if( ref $tpi eq 'HASH' && exists $tpi->{signed} ) {
300+
$new_content->{third_party_invite} = { signed => $tpi->{signed} };
301+
}
302+
}
303+
if( $type eq 'm.room.redaction' ) {
304+
# In v11, 'redacts' moved into content; preserve content.redacts
305+
exists $old_content->{redacts} and $new_content->{redacts} = $old_content->{redacts};
306+
}
307+
}
308+
281309
if( my $allowed_content_keys = $ALLOWED_CONTENT_BY_TYPE{$type} ) {
282310
exists $old_content->{$_} and $new_content->{$_} = $old_content->{$_} for
283311
@$allowed_content_keys;
@@ -288,8 +316,8 @@ sub redact_event
288316

289317
sub redacted_event
290318
{
291-
my ( $event ) = @_;
292-
redact_event( $event = { %$event } );
319+
my ( $event, $room_version ) = @_;
320+
redact_event( $event = { %$event }, $room_version );
293321
return $event;
294322
}
295323

@@ -309,6 +337,7 @@ sub sign_event_json
309337

310338
my $origin = $args{origin} or croak "Require an 'origin'";
311339
my $key_id = $args{key_id} or croak "Require a 'key_id'";
340+
my $room_version = delete $args{room_version};
312341

313342
# 'hashes' records the original unredacted version
314343
{
@@ -319,7 +348,7 @@ sub sign_event_json
319348
}
320349

321350
# Signature is of redacted version
322-
sign_json( my $signed = redacted_event( $event ), %args );
351+
sign_json( my $signed = redacted_event( $event, $room_version ), %args );
323352

324353
$event->{signatures} = $signed->{signatures};
325354
}
@@ -349,9 +378,10 @@ sub signed_event_json
349378

350379
sub verify_event_json_signature
351380
{
352-
my ( $event, @args ) = @_;
381+
my ( $event, %args ) = @_;
353382

354-
verify_json_signature( redacted_event( $event ), @args );
383+
my $room_version = delete $args{room_version};
384+
verify_json_signature( redacted_event( $event, $room_version ), %args );
355385
}
356386

357387
=head1 AUTHOR

lib/SyTest/Federation/AuthChecks.pm

Lines changed: 26 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,12 @@ sub auth_check_event
4848
$accepted_events, $event->{auth_events}, "m.room.create"
4949
);
5050

51+
my $room_creator = _creator_for_create_event( $create_event );
52+
return 0 unless defined $room_creator;
53+
5154
{
5255
users => {
53-
$create_event->{content}{creator} => 100,
56+
$room_creator => 100,
5457
},
5558
users_default => 0,
5659

@@ -86,6 +89,24 @@ sub auth_check_event
8689
return 1;
8790
}
8891

92+
sub _creator_for_create_event
93+
{
94+
my ( $create_event ) = @_;
95+
96+
$create_event or
97+
return undef;
98+
99+
my $room_version = $create_event->{content}{room_version};
100+
101+
# For room version 11+, 'creator' is absent from content, we use sender.
102+
if( defined $room_version and $room_version =~ /\A[0-9]+\z/ and $room_version >= 11 ) {
103+
return $create_event->{sender};
104+
}
105+
106+
# For older room versions, 'creator' must be present explicitly.
107+
return $create_event->{content}{creator};
108+
}
109+
89110
sub auth_check_event_m_room_create
90111
{
91112
my $self = shift;
@@ -96,7 +117,8 @@ sub auth_check_event_m_room_create
96117
return 0;
97118

98119
# Any m.room.create event is acceptable, provided that the creator matches
99-
return $event->{sender} eq $event->{content}{creator};
120+
my $creator = _creator_for_create_event( $event );
121+
return defined( $creator ) and $event->{sender} eq $creator;
100122
}
101123

102124
sub auth_check_event_m_room_member
@@ -117,7 +139,8 @@ sub auth_check_event_m_room_member
117139
$accepted_events, $event->{auth_events}, "m.room.create"
118140
);
119141

120-
if( $create_event and $event->{state_key} eq $create_event->{content}{creator} ) {
142+
my $creator = _creator_for_create_event( $create_event );
143+
if( $creator and $event->{state_key} eq $creator ) {
121144
return 1;
122145
}
123146

lib/SyTest/Federation/Datastore.pm

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,13 @@ the C<signatures> key.
7777
sub sign_event
7878
{
7979
my $self = shift;
80-
my ( $event ) = @_;
80+
my ( $event, %args ) = @_;
8181

8282
sign_event_json( $event,
83-
secret_key => $self->secret_key,
84-
origin => $self->server_name,
85-
key_id => $self->key_id,
83+
secret_key => $self->secret_key,
84+
origin => $self->server_name,
85+
key_id => $self->key_id,
86+
room_version => $args{room_version},
8687
);
8788
}
8889

@@ -204,12 +205,12 @@ sub create_event
204205
$event_id = $self->next_event_id( $event_id_suffix );
205206
$event->{event_id} = $event_id;
206207
}
207-
$self->sign_event( $event );
208+
$self->sign_event( $event, room_version => $room_version );
208209
} else {
209210
die "event with explicit event_id in room v$room_version"
210211
if defined $event_id;
211212

212-
$self->sign_event( $event );
213+
$self->sign_event( $event, room_version => $room_version );
213214
$event_id = id_for_event( $event, $room_version );
214215
}
215216

lib/SyTest/Federation/Protocol.pm

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,10 @@ Calculates the reference hash of an event.
4444

4545
sub hash_event
4646
{
47-
my ( $event ) = @_;
47+
my ( $event, $room_version ) = @_;
48+
$room_version //= 1;
4849
croak "Require an event" unless ref $event eq 'HASH';
49-
my $redacted = redacted_event( $event );
50+
my $redacted = redacted_event( $event, $room_version );
5051
delete $redacted->{signatures};
5152
delete $redacted->{age_ts};
5253
delete $redacted->{unsigned};
@@ -76,7 +77,7 @@ sub id_for_event
7677
return $event_id;
7778
}
7879

79-
my $event_hash = hash_event( $event );
80+
my $event_hash = hash_event( $event, $room_version );
8081

8182
# room v3 uses the unpadded-base64-encoded hash
8283
if( $room_version eq '3' ) {

lib/SyTest/Federation/Room.pm

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -180,13 +180,16 @@ sub create_initial_events
180180
$self->room_version eq "1" ? undef : $self->room_version
181181
);
182182

183+
# For room version 11+, 'creator' is absent from content, we use sender.
184+
my $create_content = {
185+
defined( $room_version ) ? ( room_version => $room_version ) : (),
186+
};
187+
$create_content->{creator} = $creator if !defined( $room_version ) || $room_version < 11;
188+
183189
$self->create_and_insert_event(
184190
type => "m.room.create",
185191

186-
content => {
187-
creator => $creator,
188-
defined( $room_version ) ? ( room_version => $room_version ) : (),
189-
},
192+
content => $create_content,
190193
sender => $creator,
191194
state_key => "",
192195
);

tests/30rooms/01state.pl

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,12 @@
3232
$event->{sender} eq $user->user_id or
3333
die "Expected user_id to be ${\$user->user_id}";
3434

35-
assert_json_keys( my $content = $event->{content}, qw( creator ));
36-
$content->{creator} eq $user->user_id or
37-
die "Expected creator to be ${\$user->user_id}";
35+
my $content = $event->{content};
36+
# For room version 11+, 'creator' is absent from content, we use sender.
37+
if( exists $content->{creator} ) {
38+
$content->{creator} eq $user->user_id or
39+
die "Expected creator to be ${\$user->user_id}";
40+
}
3841

3942
return 1;
4043
});

0 commit comments

Comments
 (0)