diff --git a/lib/SyTest/HTTPClient.pm b/lib/SyTest/HTTPClient.pm index 4079b2acf..ab3c5e069 100644 --- a/lib/SyTest/HTTPClient.pm +++ b/lib/SyTest/HTTPClient.pm @@ -105,7 +105,7 @@ sub do_request my $message = $response->message; $message =~ s/\r?\n?$//; # because HTTP::Response doesn't do this - return Future->fail( "HTTP Request failed ( ${\$response->code} $message $uri )", + return Future->fail( "HTTP Request failed (${\$response->code} $message)", http => $response, $response->request ); } diff --git a/tests/10apidoc/01register.pl b/tests/10apidoc/01register.pl index 9f2f4e131..bbb072f17 100644 --- a/tests/10apidoc/01register.pl +++ b/tests/10apidoc/01register.pl @@ -227,9 +227,10 @@ sub matrix_register_user }); } -shared_secret_tests( "/r0/admin/register", \&matrix_admin_register_user_via_secret); +shared_secret_tests( "/v1/register", \&matrix_v1_register_user_via_secret); +shared_secret_tests( "/r0/register", \&matrix_r0_register_user_via_secret); -sub matrix_admin_register_user_via_secret +sub matrix_v1_register_user_via_secret { my ( $http, $uid, %opts ) = @_; @@ -239,30 +240,23 @@ sub matrix_admin_register_user_via_secret defined $uid or croak "Require UID for matrix_register_user_via_secret"; - $http->do_request_json( - method => "GET", - uri => "/r0/admin/register", - )->then( sub{ - my ( $nonce ) = @_; - - my $mac = hmac_sha1_hex( - join( "\0", $nonce->{nonce}, $uid, $password, $is_admin ? "admin" : "notadmin" ), - "reg_secret" - ); + my $mac = hmac_sha1_hex( + join( "\0", $uid, $password, $is_admin ? "admin" : "notadmin" ), + "reg_secret" + ); - return $http->do_request_json( - method => "POST", - uri => "/r0/admin/register", + $http->do_request_json( + method => "POST", + uri => "/api/v1/register", - content => { - nonce => $nonce->{nonce}, - username => $uid, - password => $password, - admin => $is_admin ? JSON::true : JSON::false, - mac => $mac, - }, - ) - })->then( sub { + content => { + type => "org.matrix.login.shared_secret", + user => $uid, + password => $password, + admin => $is_admin ? JSON::true : JSON::false, + mac => $mac, + }, + )->then( sub { my ( $body ) = @_; assert_json_keys( $body, qw( user_id access_token )); @@ -284,6 +278,58 @@ sub matrix_admin_register_user_via_secret }); } +sub matrix_r0_register_user_via_secret +{ + my ( $http, $uid, %opts ) = @_; + + my $password = $opts{password} // "an0th3r s3kr1t"; + my $is_admin = $opts{is_admin} // 0; + + defined $uid or + croak "Require UID for matrix_register_user_via_secret"; + + # for some reason the /r0/register endpoint only includes the + # uid in the hash. AFAICT it's equally valid, but one has to + # wonder why it is different to the /v1/ endpoint. + # (https://github.com/matrix-org/synapse/issues/2664) + my $mac = hmac_sha1_hex( + $uid, + "reg_secret" + ); + + $http->do_request_json( + method => "POST", + uri => "/r0/register", + + content => { + type => "org.matrix.login.shared_secret", + username => $uid, + password => $password, + admin => $is_admin ? JSON::true : JSON::false, + mac => $mac, + }, + )->then( sub { + my ( $body ) = @_; + + assert_json_keys( $body, qw( user_id access_token device_id )); + + my $uid = $body->{user_id}; + + log_if_fail "Registered new user (via secret) $uid"; + + my $access_token = $body->{access_token}; + + my $user = new_User( + http => $http, + user_id => $uid, + device_id => $body->{device_id}, + password => $password, + access_token => $access_token, + ); + return Future->done( $user ); + }); +} + sub shared_secret_tests { my ( $ep_name, $register_func ) = @_; @@ -382,7 +428,7 @@ sub local_admin_fixture setup => sub { my ( $http, $localpart ) = @_; - matrix_admin_register_user_via_secret( $http, $localpart, is_admin => 1, %args ); + matrix_v1_register_user_via_secret( $http, $localpart, is_admin => 1, %args ); }, ); } diff --git a/tests/10apidoc/34room-messages.pl b/tests/10apidoc/34room-messages.pl index b8092e972..842df745a 100644 --- a/tests/10apidoc/34room-messages.pl +++ b/tests/10apidoc/34room-messages.pl @@ -158,46 +158,6 @@ sub matrix_send_room_text_message }); }; -test "GET /rooms/:room_id/messages lazy loads members correctly", - requires => [ local_user_and_room_fixtures(), - qw( can_send_message )], - - proves => [qw( can_get_messages )], - - check => sub { - my ( $user, $room_id ) = @_; - - matrix_send_room_text_message( $user, $room_id, - body => "Here is the message content", - )->then( sub { - do_request_json_for( $user, - method => "GET", - uri => "/r0/rooms/$room_id/messages", - - # With no params this does "forwards from END"; i.e. nothing useful - params => { - dir => "b", - filter => '{ "lazy_load_members" : true }', - }, - ) - })->then( sub { - my ( $body ) = @_; - - assert_json_keys( $body, qw( start end state chunk )); - assert_json_list( $body->{chunk} ); - assert_json_list( $body->{state} ); - - assert_eq( scalar @{$body->{state}}, 1); - assert_eq( $body->{state}[0]{type}, 'm.room.member'); - assert_eq( $body->{state}[0]{state_key}, $user->user_id); - - scalar @{ $body->{chunk} } > 0 or - die "Expected some messages but got none at all\n"; - - Future->done(1); - }); - }; - push @EXPORT, qw( matrix_get_room_messages matrix_send_room_text_message_synced matrix_send_room_message_synced matrix_send_filler_messages_synced diff --git a/tests/14account/02deactivate.pl b/tests/14account/02deactivate.pl index 98d2dbd8e..4909e7d27 100644 --- a/tests/14account/02deactivate.pl +++ b/tests/14account/02deactivate.pl @@ -1,11 +1,10 @@ use JSON qw( decode_json ); +my $password = "my secure password"; + sub matrix_deactivate_account { - my ( $user, %opts ) = @_; - - # use the user's password unless one was given in opts - my $password = (delete $opts{password}) // $user->password; + my ( $user, $password ) = @_; do_request_json_for( $user, method => "POST", @@ -16,28 +15,26 @@ sub matrix_deactivate_account user => $user->user_id, password => $password, }, - %opts, }, ); } -push our @EXPORT, qw( matrix_deactivate_account ); test "Can deactivate account", - requires => [ local_user_fixture() ], + requires => [ local_user_fixture( password => $password ) ], check => sub { my ( $user ) = @_; - matrix_deactivate_account( $user ); + matrix_deactivate_account( $user, $password ); }; test "Can't deactivate account with wrong password", - requires => [ local_user_fixture() ], + requires => [ local_user_fixture( password => $password ) ], check => sub { my ( $user ) = @_; - matrix_deactivate_account( $user, password=>"wrong password" ) + matrix_deactivate_account( $user, "wrong password" ) ->main::expect_http_401->then( sub { my ( $resp ) = @_; @@ -55,12 +52,12 @@ sub matrix_deactivate_account }; test "After deactivating account, can't log in with password", - requires => [ local_user_fixture() ], + requires => [ local_user_fixture( password => $password ) ], check => sub { my ( $user ) = @_; - matrix_deactivate_account( $user ) + matrix_deactivate_account( $user, $password ) ->then( sub { do_request_json_for( $user, method => "POST", @@ -68,7 +65,7 @@ sub matrix_deactivate_account content => { type => "m.login.password", user => $user->user_id, - password => $user->password, + password => $password, } # We don't mandate the exact failure code here # (that should be done in the login test if diff --git a/tests/30rooms/31forget.pl b/tests/30rooms/31forget.pl index 95980a944..6755075f6 100644 --- a/tests/30rooms/31forget.pl +++ b/tests/30rooms/31forget.pl @@ -123,7 +123,7 @@ })->main::expect_http_4xx; }; -test "Can re-join room if re-invited", +test "Can re-join room if re-invited - history_visibility = shared", requires => [ local_user_fixture(), local_user_fixture() ], do => sub { @@ -183,6 +183,66 @@ }); }; +test "Can re-join room if re-invited - history_visibility joined", + requires => [ local_user_fixture(), local_user_fixture() ], + + do => sub { + my ( $creator, $user ) = @_; + + my ( $room_id ); + + matrix_create_room( $creator, invite => [ $user->user_id ] )->then( sub { + ( $room_id ) = @_; + + log_if_fail "room_id", $room_id; + + matrix_put_room_state( $creator, $room_id, + type => "m.room.join_rules", + state_key => "", + content => { + join_rule => "invite", + } + ) + })->then( sub { + matrix_set_room_history_visibility( $creator, $room_id, "joined"); + })->then( sub { + matrix_join_room( $user, $room_id ); + })->then( sub { + matrix_send_room_text_message( $creator, $room_id, body => "before leave" ); + })->then( sub { + matrix_leave_room( $user, $room_id ); + })->then( sub { + matrix_forget_room( $user, $room_id ); + })->then( sub { + matrix_join_room( $user, $room_id )->main::expect_http_403; + })->then( sub { + matrix_invite_user_to_room( $creator, $user, $room_id ); + })->then( sub { + matrix_join_room( $user, $room_id ); + })->then( sub { + matrix_get_room_messages( $user, $room_id, limit => 100 ); + })->then( sub { + my ( $body ) = @_; + + none { $_->{type} eq "m.room.message" } @{ $body->{chunk} } + or die "Should not have seen any m.room.message events"; + + matrix_send_room_text_message( $creator, $room_id, body => "after rejoin" ); + })->then( sub { + matrix_get_room_messages( $user, $room_id, limit => 1 ); + })->then( sub { + my ( $body ) = @_; + + log_if_fail "body", $body; + + @{ $body->{chunk} } == 1 or die "Expected event"; + $body->{chunk}[0]->{type} eq "m.room.message" && $body->{chunk}[0]->{content}{body} eq "after rejoin" + or die "Got wrong event"; + + Future->done( 1 ); + }); + }; + push our @EXPORT, qw( matrix_forget_room ); sub matrix_forget_room diff --git a/tests/30rooms/32erasure.pl b/tests/30rooms/32erasure.pl deleted file mode 100644 index 8d5e974f9..000000000 --- a/tests/30rooms/32erasure.pl +++ /dev/null @@ -1,74 +0,0 @@ -# Copyright 2018 New Vector Ltd -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -use List::Util qw( first ); - -test "Only original members of the room can see messages from erased users", - requires => [ local_user_and_room_fixtures(), local_user_fixture(), local_user_fixture() ], - - do => sub { - my ( $creator, $room_id, $member, $joiner ) = @_; - - my $message_id; - matrix_join_room_synced( $member, $room_id ) - ->then( sub { - matrix_send_room_text_message( $creator, $room_id, body => "body1" ); - })->then( sub { - ( $message_id ) = @_; - matrix_join_room_synced( $joiner, $room_id ); - })->then( sub { - # now both users should see the message event - matrix_sync( $joiner, limit => 4 ); - })->then( sub { - my ( $body ) = @_; - - my $room = $body->{rooms}{join}{$room_id}; - my $events = $room->{timeline}->{events}; - log_if_fail "messages for joining user before erasure", $events; - - my $e = first { $_->{event_id} eq $message_id } @$events; - assert_eq( $e->{type}, "m.room.message", "event type" ); - assert_eq( $e->{content}->{body}, "body1", "event content body" ); - - matrix_deactivate_account( $creator, erase => JSON::true ); - })->then( sub { - # now the original member should see the message event, but the joiner - # should see a redacted version - matrix_sync( $member ); - })->then( sub { - my ( $body ) = @_; - - my $room = $body->{rooms}{join}{$room_id}; - my $events = $room->{timeline}->{events}; - log_if_fail "messages for original member after erasure", $events; - - my $e = first { $_->{event_id} eq $message_id } @$events; - assert_eq( $e->{type}, "m.room.message", "event type" ); - assert_eq( $e->{content}->{body}, "body1", "event content body" ); - - matrix_sync( $joiner ); - })->then( sub { - my ( $body ) = @_; - - my $room = $body->{rooms}{join}{$room_id}; - my $events = $room->{timeline}->{events}; - log_if_fail "messages for joining user after erasure", $events; - - my $e = first { $_->{event_id} eq $message_id } @$events; - assert_eq( $e->{type}, "m.room.message", "event type" ); - assert_deeply_eq( $e->{content}, {}, "event content" ); - - Future->done(1); - }); - }; diff --git a/tests/50federation/32room-getevent.pl b/tests/50federation/32room-getevent.pl index 1549624cb..af52c1f7e 100644 --- a/tests/50federation/32room-getevent.pl +++ b/tests/50federation/32room-getevent.pl @@ -45,75 +45,3 @@ }); }; - -test "Inbound federation redacts events from erased users", - requires => [ $main::OUTBOUND_CLIENT, $main::HOMESERVER_INFO[0], - local_user_and_room_fixtures(), - federation_user_id_fixture() ], - - do => sub { - my ( $outbound_client, $info, $creator, $room_id, $user_id ) = @_; - my $first_home_server = $info->server_name; - - my $message_id; - - $outbound_client->join_room( - server_name => $first_home_server, - room_id => $room_id, - user_id => $user_id, - )->then( sub { - my ( $room ) = @_; - - # have the creator send a message into the room, which we will try to - # fetch. - matrix_send_room_text_message( $creator, $room_id, body => "body1" ); - })->then( sub { - ( $message_id ) = @_; - - $outbound_client->do_request_json( - method => "GET", - hostname => $first_home_server, - uri => "/event/$message_id/", - ); - })->then( sub { - my ( $body ) = @_; - log_if_fail "Fetched event before erasure", $body; - - assert_json_keys( $body, qw( origin origin_server_ts pdus )); - assert_json_list( my $events = $body->{pdus} ); - - @$events == 1 or - die "Expected 1 event, found " . scalar(@$events); - my ( $event ) = @$events; - - # Check that the content is right - assert_eq( $event->{content}->{body}, "body1" ); - - # now do the erasure - matrix_deactivate_account( $creator, erase => JSON::true ); - })->then( sub { - # re-fetch the event - $outbound_client->do_request_json( - method => "GET", - hostname => $first_home_server, - uri => "/event/$message_id/", - ); - })->then( sub { - my ( $body ) = @_; - log_if_fail "Fetched event after erasure", $body; - - assert_json_keys( $body, qw( origin origin_server_ts pdus )); - assert_json_list( my $events = $body->{pdus} ); - - @$events == 1 or - die "Expected 1 event, found " . scalar(@$events); - my ( $event ) = @$events; - - # Check that the content has been redacted - exists $event->{content}->{body} and - die "Event was not redacted"; - - Future->done(1); - }); - }; -