Fix signature validation (#38)
* Add failing test * Fix signature validation * Fix tests to generate correct signatures * StyleCI fix * Ignore route params when validating the signature * Fix tests to add route params next to signature * StyleCI fixes
This commit is contained in:
parent
c1f6ffa51b
commit
83dec0b5f1
|
|
@ -3,6 +3,7 @@
|
|||
namespace BeyondCode\LaravelWebSockets\HttpApi\Controllers;
|
||||
|
||||
use Exception;
|
||||
use Pusher\Pusher;
|
||||
use Illuminate\Http\Request;
|
||||
use GuzzleHttp\Psr7\Response;
|
||||
use Ratchet\ConnectionInterface;
|
||||
|
|
@ -84,18 +85,21 @@ abstract class Controller implements HttpServerInterface
|
|||
|
||||
protected function ensureValidSignature(Request $request)
|
||||
{
|
||||
$signature =
|
||||
"{$request->getMethod()}\n/{$request->path()}\n".
|
||||
"auth_key={$request->get('auth_key')}".
|
||||
"&auth_timestamp={$request->get('auth_timestamp')}".
|
||||
"&auth_version={$request->get('auth_version')}";
|
||||
/*
|
||||
* The `auth_signature` & `body_md5` parameters are not included when calculating the `auth_signature` value.
|
||||
*
|
||||
* The `appId`, `appKey` & `channelName` parameters are actually route paramaters and are never supplied by the client.
|
||||
*/
|
||||
$params = array_except($request->query(), ['auth_signature', 'body_md5', 'appId', 'appKey', 'channelName']);
|
||||
|
||||
if ($request->getContent() !== '') {
|
||||
$bodyMd5 = md5($request->getContent());
|
||||
|
||||
$signature .= "&body_md5={$bodyMd5}";
|
||||
$params['body_md5'] = md5($request->getContent());
|
||||
}
|
||||
|
||||
ksort($params);
|
||||
|
||||
$signature = "{$request->getMethod()}\n/{$request->path()}\n".Pusher::array_implode('=', '&', $params);
|
||||
|
||||
$authSignature = hash_hmac('sha256', $signature, App::findById($request->get('appId'))->secret);
|
||||
|
||||
if ($authSignature !== $request->get('auth_signature')) {
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
||||
|
||||
use Pusher\Pusher;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
|
@ -19,21 +20,15 @@ class FetchChannelTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/my-channel';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'my-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'InvalidSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channels\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'InvalidSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel?appId=1234&channelName=my-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelController::class);
|
||||
|
||||
|
|
@ -48,21 +43,15 @@ class FetchChannelTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/my-channel';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'my-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channel/my-channel\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel?appId=1234&channelName=my-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelController::class);
|
||||
|
||||
|
|
@ -87,21 +76,15 @@ class FetchChannelTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/invalid-channel';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'invalid-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channel/my-channel\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel?appId=1234&channelName=invalid-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelController::class);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
||||
|
||||
use Pusher\Pusher;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Illuminate\Http\JsonResponse;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
|
|
@ -19,21 +20,14 @@ class FetchChannelsTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channels';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'InvalidSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channels\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'InvalidSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channels?appId=1234&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelsController::class);
|
||||
|
||||
|
|
@ -49,21 +43,14 @@ class FetchChannelsTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channels';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channels\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channels?appId=1234&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelsController::class);
|
||||
|
||||
|
|
@ -81,26 +68,59 @@ class FetchChannelsTest extends TestCase
|
|||
], json_decode($response->getContent(), true));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_returns_the_channel_information_for_prefix()
|
||||
{
|
||||
$this->joinPresenceChannel('presence-global.1');
|
||||
$this->joinPresenceChannel('presence-global.1');
|
||||
$this->joinPresenceChannel('presence-global.2');
|
||||
$this->joinPresenceChannel('presence-notglobal.2');
|
||||
|
||||
$connection = new Connection();
|
||||
|
||||
$requestPath = '/apps/1234/channels';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
];
|
||||
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath, [
|
||||
'filter_by_prefix' => 'presence-global',
|
||||
]);
|
||||
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelsController::class);
|
||||
|
||||
$controller->onOpen($connection, $request);
|
||||
|
||||
/** @var JsonResponse $response */
|
||||
$response = array_pop($connection->sentRawData);
|
||||
|
||||
$this->assertSame([
|
||||
'channels' => [
|
||||
'presence-global.1' => [
|
||||
'user_count' => 2,
|
||||
],
|
||||
'presence-global.2' => [
|
||||
'user_count' => 1,
|
||||
],
|
||||
],
|
||||
], json_decode($response->getContent(), true));
|
||||
}
|
||||
|
||||
/** @test */
|
||||
public function it_returns_empty_object_for_no_channels_found()
|
||||
{
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channels';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channels\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channels?appId=1234&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchChannelsController::class);
|
||||
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
namespace BeyondCode\LaravelWebSockets\Tests\HttpApi;
|
||||
|
||||
use Pusher\Pusher;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use BeyondCode\LaravelWebSockets\Tests\TestCase;
|
||||
use BeyondCode\LaravelWebSockets\Tests\Mocks\Connection;
|
||||
|
|
@ -18,21 +19,15 @@ class FetchUsersTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/my-channel';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'my-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'InvalidSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channels\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'InvalidSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel?appId=1234&channelName=my-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchUsersController::class);
|
||||
|
||||
|
|
@ -49,21 +44,15 @@ class FetchUsersTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/my-channel/users';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'my-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channel/my-channel/users\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel/users?appId=1234&channelName=my-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchUsersController::class);
|
||||
|
||||
|
|
@ -80,21 +69,15 @@ class FetchUsersTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/invalid-channel/users';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'invalid-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channel/my-channel/users\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel/users?appId=1234&channelName=invalid-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchUsersController::class);
|
||||
|
||||
|
|
@ -108,21 +91,15 @@ class FetchUsersTest extends TestCase
|
|||
|
||||
$connection = new Connection();
|
||||
|
||||
$auth_key = 'TestKey';
|
||||
$auth_timestamp = time();
|
||||
$auth_version = '1.0';
|
||||
$requestPath = '/apps/1234/channel/presence-channel/users';
|
||||
$routeParams = [
|
||||
'appId' => '1234',
|
||||
'channelName' => 'presence-channel',
|
||||
];
|
||||
|
||||
$queryParameters = http_build_query(compact('auth_key', 'auth_timestamp', 'auth_version'));
|
||||
$queryString = Pusher::build_auth_query_string('TestKey', 'TestSecret', 'GET', $requestPath);
|
||||
|
||||
$signature =
|
||||
"GET\n/apps/1234/channel/my-channel/users\n".
|
||||
"auth_key={$auth_key}".
|
||||
"&auth_timestamp={$auth_timestamp}".
|
||||
"&auth_version={$auth_version}";
|
||||
|
||||
$auth_signature = hash_hmac('sha256', $signature, 'TestSecret');
|
||||
|
||||
$request = new Request('GET', "/apps/1234/channel/my-channel/users?appId=1234&channelName=presence-channel&auth_signature={$auth_signature}&{$queryParameters}");
|
||||
$request = new Request('GET', "{$requestPath}?{$queryString}&".http_build_query($routeParams));
|
||||
|
||||
$controller = app(FetchUsersController::class);
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue