Skip to content

Commit 8e01699

Browse files
committed
wip
1 parent 20e75ca commit 8e01699

File tree

4 files changed

+65
-12
lines changed

4 files changed

+65
-12
lines changed

src/Pusher/Http/Controllers/ChannelsController.php

+11-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
namespace Laravel\Reverb\Pusher\Http\Controllers;
44

5+
use Illuminate\Support\Str;
56
use Laravel\Reverb\Http\Connection;
67
use Psr\Http\Message\RequestInterface;
78
use Symfony\Component\HttpFoundation\JsonResponse;
@@ -14,7 +15,16 @@ class ChannelsController extends Controller
1415
*/
1516
public function handle(RequestInterface $request, Connection $connection, ...$args): Response
1617
{
17-
$channels = $this->channels->channels()->mapWithKeys(fn ($connections, $name) => [$name => ['user_count' => count($connections)]]);
18+
$channels = $this->channels->channels();
19+
$info = explode(',', $this->query['info'] ?? '');
20+
21+
if (isset($this->query['filter_by_prefix'])) {
22+
$channels = $channels->filter(fn ($connections, $name) => Str::startsWith($name, $this->query['filter_by_prefix']));
23+
}
24+
25+
$channels = $channels->mapWithKeys(function ($connections, $name) use ($info) {
26+
return [$name => array_filter(['user_count' => in_array('user_count', $info) ? count($connections) : null])];
27+
});
1828

1929
return new JsonResponse((object) ['channels' => $channels]);
2030
}

src/Pusher/Http/Controllers/Controller.php

+7-5
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,13 @@ abstract class Controller
2626

2727
protected $body;
2828

29+
protected $query;
30+
2931
public function __invoke(RequestInterface $request, Connection $connection, ...$args)
3032
{
33+
parse_str($request->getUri()->getQuery(), $query);
3134
$this->body = $request->getBody()->getContents();
35+
$this->query = $query;
3236

3337
try {
3438
$this->setApplication($args['appId'] ?? null);
@@ -91,9 +95,7 @@ protected function setChannels()
9195
*/
9296
protected function verifySignature(RequestInterface $request): void
9397
{
94-
parse_str($request->getUri()->getQuery(), $queryParams);
95-
96-
$params = Arr::except($queryParams, [
98+
$params = Arr::except($this->query, [
9799
'auth_signature', 'body_md5', 'appId', 'appKey', 'channelName',
98100
]);
99101

@@ -111,8 +113,8 @@ protected function verifySignature(RequestInterface $request): void
111113

112114
$signature = hash_hmac('sha256', $signature, $this->application->secret());
113115

114-
if ($signature !== $queryParams['auth_signature']) {
115-
// throw new HttpException(401, 'Authentication signature invalid.');
116+
if ($signature !== $this->query['auth_signature']) {
117+
throw new HttpException(401, 'Authentication signature invalid.');
116118
}
117119
}
118120

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
use Laravel\Reverb\Tests\RatchetTestCase;
4+
5+
use function React\Async\await;
6+
7+
uses(RatchetTestCase::class);
8+
9+
it('can return all channel information', function () {
10+
$this->subscribe('test-channel-one');
11+
$this->subscribe('test-channel-two');
12+
13+
$response = await($this->getWithSignature('channels?info=user_count'));
14+
15+
$this->assertSame(200, $response->getStatusCode());
16+
$this->assertSame('{"channels":{"test-channel-one":{"user_count":1},"test-channel-two":{"user_count":1}}}', $response->getBody()->getContents());
17+
});

tests/RatchetTestCase.php

+30-6
Original file line numberDiff line numberDiff line change
@@ -274,6 +274,17 @@ public function triggerEvent(string $channel, string $event, array $data = []):
274274
$this->assertSame('{}', $response->getBody()->getContents());
275275
}
276276

277+
public function request(string $path, string $method = 'GET', mixed $data = '', string $host = '0.0.0.0', string $port = '8080', string $appId = '123456'): PromiseInterface
278+
{
279+
return (new Browser($this->loop))
280+
->request(
281+
$method,
282+
"http://{$host}:{$port}/apps/{$appId}/{$path}",
283+
[],
284+
($data) ? json_encode($data) : ''
285+
);
286+
}
287+
277288
/**
278289
* Post a request to the server.
279290
*/
@@ -284,12 +295,7 @@ public function postToServer(
284295
string $port = '8080',
285296
string $appId = '123456'
286297
): PromiseInterface {
287-
return (new Browser($this->loop))
288-
->post(
289-
"http://{$host}:{$port}/apps/{$appId}/{$path}",
290-
[],
291-
json_encode($data)
292-
);
298+
return $this->request($path, 'POST', $data, $host, $port, $appId);
293299
}
294300

295301
/**
@@ -310,4 +316,22 @@ public function postToServerWithSignature(
310316

311317
return $this->postToServer("{$path}?{$query}&auth_signature={$signature}", $data, $host, $port, $appId);
312318
}
319+
320+
public function getWithSignature(
321+
string $path,
322+
array $data = [],
323+
string $host = '0.0.0.0',
324+
string $port = '8080',
325+
string $appId = '123456'
326+
): PromiseInterface {
327+
$hash = md5(json_encode($data));
328+
$timestamp = time();
329+
$query = "auth_key=pusher-key&auth_timestamp={$timestamp}&auth_version=1.0&body_md5={$hash}";
330+
$string = "POST\n/apps/{$appId}/{$path}\n$query";
331+
$signature = hash_hmac('sha256', $string, 'pusher-secret');
332+
333+
$path = Str::contains($path, '?') ? "{$path}&{$query}" : "{$path}?{$query}";
334+
335+
return $this->request("{$path}&auth_signature={$signature}", 'GET', '', $host, $port, $appId);
336+
}
313337
}

0 commit comments

Comments
 (0)