From 774265852710bb21ac14c13e73d88c2339393e7d Mon Sep 17 00:00:00 2001 From: Marcel Pociot Date: Thu, 17 Jun 2021 10:59:33 +0200 Subject: [PATCH] Add site details api route --- app/Server/Factory.php | 2 + .../Admin/GetSiteDetailsController.php | 50 +++++++++++++++++++ .../Controllers/ControlMessageController.php | 4 +- config/expose.php | 4 ++ tests/Feature/Server/ApiTest.php | 47 +++++++++++++++++ 5 files changed, 105 insertions(+), 2 deletions(-) create mode 100644 app/Server/Http/Controllers/Admin/GetSiteDetailsController.php diff --git a/app/Server/Factory.php b/app/Server/Factory.php index 27e03a5..313190d 100644 --- a/app/Server/Factory.php +++ b/app/Server/Factory.php @@ -19,6 +19,7 @@ use App\Server\Http\Controllers\Admin\DisconnectSiteController; use App\Server\Http\Controllers\Admin\DisconnectTcpConnectionController; use App\Server\Http\Controllers\Admin\GetSettingsController; use App\Server\Http\Controllers\Admin\GetSitesController; +use App\Server\Http\Controllers\Admin\GetSiteDetailsController; use App\Server\Http\Controllers\Admin\GetStatisticsController; use App\Server\Http\Controllers\Admin\GetTcpConnectionsController; use App\Server\Http\Controllers\Admin\GetUserDetailsController; @@ -149,6 +150,7 @@ class Factory $this->router->delete('/api/subdomains/{subdomain}', DeleteSubdomainController::class, $adminCondition); $this->router->delete('/api/users/{id}', DeleteUsersController::class, $adminCondition); $this->router->get('/api/sites', GetSitesController::class, $adminCondition); + $this->router->get('/api/sites/{site}', GetSiteDetailsController::class, $adminCondition); $this->router->delete('/api/sites/{id}', DisconnectSiteController::class, $adminCondition); $this->router->get('/api/tcp', GetTcpConnectionsController::class, $adminCondition); $this->router->delete('/api/tcp/{id}', DisconnectTcpConnectionController::class, $adminCondition); diff --git a/app/Server/Http/Controllers/Admin/GetSiteDetailsController.php b/app/Server/Http/Controllers/Admin/GetSiteDetailsController.php new file mode 100644 index 0000000..40e18bb --- /dev/null +++ b/app/Server/Http/Controllers/Admin/GetSiteDetailsController.php @@ -0,0 +1,50 @@ +connectionManager = $connectionManager; + } + + public function handle(Request $request, ConnectionInterface $httpConnection) + { + $domain = $request->get('site'); + + $connectedSite = collect($this->connectionManager->getConnections()) + ->filter(function ($connection) { + return get_class($connection) === ControlConnection::class; + }) + ->first(function (ControlConnection $site) use ($domain) { + return "{$site->subdomain}.{$site->serverHost}" === $domain; + }); + + if (is_null($connectedSite)) { + $httpConnection->send( + Message::toString(new Response(404)) + ); + return; + } + + $httpConnection->send( + respond_json($connectedSite->toArray()) + ); + } +} diff --git a/app/Server/Http/Controllers/ControlMessageController.php b/app/Server/Http/Controllers/ControlMessageController.php index caf11ab..8f426b6 100644 --- a/app/Server/Http/Controllers/ControlMessageController.php +++ b/app/Server/Http/Controllers/ControlMessageController.php @@ -156,7 +156,7 @@ class ControlMessageController implements MessageComponentInterface ->then(function () use ($connection, $data, $user) { return $this->hasValidSubdomain($connection, $data->subdomain, $user, $data->server_host); }) - ->then(function ($subdomain) use ($data, $connection) { + ->then(function ($subdomain) use ($data, $connection, $user) { if ($subdomain === false) { return; } @@ -170,7 +170,7 @@ class ControlMessageController implements MessageComponentInterface $connection->send(json_encode([ 'event' => 'authenticated', 'data' => [ - 'message' => config('expose.admin.messages.message_of_the_day'), + 'message' => config('expose.admin.messages.resolve_connection_message')($connectionInfo, $user), 'subdomain' => $connectionInfo->subdomain, 'server_host' => $connectionInfo->serverHost, 'client_id' => $connectionInfo->client_id, diff --git a/config/expose.php b/config/expose.php index 0014b81..1af51d2 100644 --- a/config/expose.php +++ b/config/expose.php @@ -313,6 +313,10 @@ return [ | */ 'messages' => [ + 'resolve_connection_message' => function ($connectionInfo, $user) { + return config('expose.admin.messages.message_of_the_day'); + }, + 'message_of_the_day' => 'Thank you for using expose.', 'invalid_auth_token' => 'Authentication failed. Please check your authentication token and try again.', diff --git a/tests/Feature/Server/ApiTest.php b/tests/Feature/Server/ApiTest.php index b53111a..4bb5e09 100644 --- a/tests/Feature/Server/ApiTest.php +++ b/tests/Feature/Server/ApiTest.php @@ -497,6 +497,53 @@ class ApiTest extends TestCase $this->assertSame('fixed-subdomain', $sites[0]->subdomain); } + /** @test */ + public function it_can_return_site_details() + { + /** @var ConnectionManager $connectionManager */ + $connectionManager = app(ConnectionManager::class); + + $connection = \Mockery::mock(IoConnection::class); + $connection->httpRequest = new Request('GET', '/?authToken=some-token'); + + $connectionManager->storeConnection('some-host.test', 'fixed-subdomain', 'localhost', $connection); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/sites/fixed-subdomain.localhost', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + + $site = json_decode($response->getBody()->getContents()); + + $this->assertSame('some-host.test', $site->host); + $this->assertSame('some-token', $site->auth_token); + $this->assertSame('fixed-subdomain', $site->subdomain); + } + + /** @test */ + public function it_returns_404_for_invalid_site_details() + { + /** @var ConnectionManager $connectionManager */ + $connectionManager = app(ConnectionManager::class); + + $connection = \Mockery::mock(IoConnection::class); + $connection->httpRequest = new Request('GET', '/?authToken=some-token'); + + $connectionManager->storeConnection('some-host.test', 'fixed-subdomain', 'localhost', $connection); + + $this->expectException(ResponseException::class); + $this->expectExceptionMessage('HTTP status code 404 (Not Found)'); + + /** @var Response $response */ + $response = $this->await($this->browser->get('http://127.0.0.1:8080/api/sites/invalid-subdomain.localhost', [ + 'Host' => 'expose.localhost', + 'Authorization' => base64_encode('username:secret'), + 'Content-Type' => 'application/json', + ])); + } + /** @test */ public function it_can_list_all_currently_connected_sites_without_auth_tokens() {