Skip to content

Commit

Permalink
Add v2 lookup support to sytest identity server (#679)
Browse files Browse the repository at this point in the history
Adds the `/v2/hash_details` and `/v2/lookup` endpoints to the built-in sytest identity server.

Synapse PR: matrix-org/synapse#5897
  • Loading branch information
anoadragon453 committed Aug 28, 2019
1 parent 2bf1318 commit 8e34332
Showing 1 changed file with 86 additions and 1 deletion.
87 changes: 86 additions & 1 deletion lib/SyTest/Identity/Server.pm
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@ use base qw( Net::Async::HTTP::Server );
use Crypt::NaCl::Sodium;
use List::Util qw( any );
use Protocol::Matrix qw( encode_base64_unpadded sign_json );
use MIME::Base64 qw ( encode_base64url );
use SyTest::HTTPServer::Request;
use HTTP::Response;
use Digest::SHA qw( sha256 );

my $crypto_sign = Crypt::NaCl::Sodium->sign;

Expand All @@ -28,6 +30,9 @@ sub _init
$self->{bindings} = {};
$self->{invites} = {};

# String for peppering hashed lookup requests
$self->{lookup_pepper} = "matrixrocks";

# Use 'on_request' as a configured parameter rather than a subclass method
# so that the '$CLIENT_LOG' logic in run-tests.pl can properly put
# debug-printing wrapping logic around it.
Expand Down Expand Up @@ -91,6 +96,80 @@ sub on_request
}
$req->respond_json( \%resp );
}
elsif( $path eq "/_matrix/identity/v2/hash_details" ) {
$resp{lookup_pepper} = $self->{lookup_pepper};
@resp{algorithms} = [ "none", "sha256" ];
$req->respond_json( \%resp );
}
elsif( $path eq "/_matrix/identity/v2/lookup" ) {
my ( $req ) = @_;

# Parse request parameters
my $body = $req->body_from_json;
my $addresses = $body->{addresses};
my $pepper = $body->{pepper};
my $algorithm = $body->{algorithm};
if ( !$addresses or !$pepper or !$algorithm ) {
$req->respond( HTTP::Response->new( 400, "Bad Request", [ Content_Length => 0 ] ) );
return;
}

if ( "none" eq $algorithm ) {
foreach my $address ( @$addresses ) {
my @address_medium = split ' ', $address;

# Check the medium and address are in the right format
if ( scalar( @address_medium ) ne 2 ) {
$resp{error} = "Address is not two strings separated by a space: ${address}";
$resp{errcode} = "M_UNKNOWN";

$req->respond_json( \%resp, code => 400 );
return;
}

# Parse the medium and address from the string
my $user_address = $address_medium[0];
my $user_medium = $address_medium[1];

# Extract the MXID for this address/medium combo from the bindings hash
# We need to swap around medium and address here as it's stored $medium, $address
# locally, not $address, $medium
my $mxid = $self->{bindings}{ join "\0", $user_medium, $user_address };

$resp{mappings}{$address} = $mxid;
}

# Return the mappings
$req->respond_json( \%resp );
}
elsif ( "sha256" eq $algorithm ) {
# Check that the user provided the correct pepper
if ( $self->{lookup_pepper} ne $pepper ) {
# Return an error message
$resp{error} = "Incorrect value for lookup_pepper";
$resp{errcode} = "M_INVALID_PEPPER";
$resp{algorithm} = "sha256";
$resp{lookup_pepper} = $self->{lookup_pepper};

$req->respond_json( \%resp, code => 400 );
return;
}

# Attempt to find the hash of each entry and return the corresponding mxid
foreach my $hash ( @$addresses ) {
$resp{mappings}{$hash} = $self->{hashes}{$hash};
}

$req->respond_json( \%resp );
}
else {
# Unknown algorithm provided
$resp{error} = "Unknown algorithm";
$resp{errcode} = "M_INVALID_PARAM";

$req->respond_json( \%resp, code => 400 );
}
}
elsif( $path eq "/_matrix/identity/api/v1/store-invite" ) {
my $body = $req->body_from_json;
my $medium = $body->{medium};
Expand Down Expand Up @@ -208,7 +287,7 @@ sub bind_identity
my ( $hs_uribase, $medium, $address, $user, $before_resp ) = @_;

# Correctly handle $user being either the scalar "user_id" or a ref of a User
# object. (We can't use is_User becuase it hasn't been defined yet).
# object. (We can't use is_User because it hasn't been defined yet).
my $user_id;
if ( ref( $user ) ne "" ) {
$user_id = $user->user_id;
Expand All @@ -218,6 +297,12 @@ sub bind_identity

$self->{bindings}{ join "\0", $medium, $address } = $user_id;

# Hash the medium, address and pepper and store it for later lookup requests
my $str_to_hash = $address . " " . $medium . " " . $self->{lookup_pepper};
my $hash = sha256( $str_to_hash );
$hash = encode_base64url( $hash );
$self->{hashes}{$hash} = $user_id;

if( !defined $hs_uribase ) {
return Future->done( 1 );
}
Expand Down

0 comments on commit 8e34332

Please sign in to comment.