diff --git a/app/JsonDocumentFetcherProvider.php b/app/JsonDocumentFetcherProvider.php index b2b79228..4a8aaf7c 100644 --- a/app/JsonDocumentFetcherProvider.php +++ b/app/JsonDocumentFetcherProvider.php @@ -4,7 +4,6 @@ namespace CultuurNet\UDB3\SearchService; -use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0TokenGenerator; use CultuurNet\UDB3\Search\Http\Authentication\Keycloak\KeycloakTokenGenerator; use CultuurNet\UDB3\Search\Http\Authentication\Token\TokenGenerator; use CultuurNet\UDB3\Search\JsonDocument\GuzzleJsonDocumentFetcher; @@ -33,24 +32,12 @@ public function register(): void private function getTokenGenerator(): TokenGenerator { - if ($this->parameter('keycloak.enabled')) { - return new KeycloakTokenGenerator( - new Client(), - $this->parameter('keycloak.domain'), - $this->parameter('keycloak.entry_api_client_id'), - $this->parameter('keycloak.entry_api_client_secret'), - $this->parameter('keycloak.entry_api_audience') - ); - } - - return new Auth0TokenGenerator( - new Client([ - 'http_errors' => false, - ]), - $this->parameter('auth0.domain'), - $this->parameter('auth0.entry_api_client_id'), - $this->parameter('auth0.entry_api_client_secret'), - $this->parameter('auth0.entry_api_audience') + return new KeycloakTokenGenerator( + new Client(), + $this->parameter('keycloak.domain'), + $this->parameter('keycloak.entry_api_client_id'), + $this->parameter('keycloak.entry_api_client_secret'), + $this->parameter('keycloak.entry_api_audience') ); } } diff --git a/app/RoutingServiceProvider.php b/app/RoutingServiceProvider.php index 3e0c7ba5..6f6de58d 100644 --- a/app/RoutingServiceProvider.php +++ b/app/RoutingServiceProvider.php @@ -7,8 +7,6 @@ use CultureFeed; use CultureFeed_DefaultOAuthClient; use CultuurNet\UDB3\Search\FileReader; -use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0TokenGenerator; -use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0MetadataGenerator; use CultuurNet\UDB3\Search\Http\Authentication\AuthenticateRequest; use CultuurNet\UDB3\Search\Http\Authentication\Consumer; use CultuurNet\UDB3\Search\Http\Authentication\Keycloak\KeycloakTokenGenerator; @@ -54,8 +52,7 @@ function (): Router { $metadataGenerator = $this->getMetadataGenerator(); - $pemFile = $this->parameter('keycloak.enabled') ? - $this->parameter('keycloak.pem_file') : $this->parameter('auth0.pem_file'); + $pemFile = $this->parameter('keycloak.pem_file'); $authenticateRequest = new AuthenticateRequest( $this->getLeagueContainer(), new CultureFeed($oauthClient), @@ -127,50 +124,26 @@ function (): Router { private function getManagementTokenProvider(): ManagementTokenProvider { - if ($this->parameter('keycloak.enabled')) { - return new ManagementTokenProvider( - new KeycloakTokenGenerator( - new Client(), - $this->parameter('keycloak.domain'), - $this->parameter('keycloak.client_id'), - $this->parameter('keycloak.client_secret'), - $this->parameter('keycloak.domain') . '/api/v2/' - ), - new ManagementTokenFileRepository(__DIR__ . '/../cache/keycloak-management-token-cache.json'), - ); - } - return new ManagementTokenProvider( - new Auth0TokenGenerator( - new Client([ - 'http_errors' => false, - ]), - $this->parameter('auth0.domain'), - $this->parameter('auth0.client_id'), - $this->parameter('auth0.client_secret'), - $this->parameter('auth0.domain') . '/api/v2/' + new KeycloakTokenGenerator( + new Client(), + $this->parameter('keycloak.domain'), + $this->parameter('keycloak.client_id'), + $this->parameter('keycloak.client_secret'), + $this->parameter('keycloak.domain') . '/api/v2/' ), - new ManagementTokenFileRepository(__DIR__ . '/../cache/auth0-management-token-cache.json'), + new ManagementTokenFileRepository(__DIR__ . '/../cache/keycloak-management-token-cache.json'), ); } private function getMetadataGenerator(): MetadataGenerator { - if ($this->parameter('keycloak.enabled')) { - return new KeycloakMetadataGenerator( - new Client([ - 'http_errors' => false, - ]), - $this->parameter('keycloak.domain'), - $this->parameter('keycloak.realm'), - ); - } - - return new Auth0MetadataGenerator( + return new KeycloakMetadataGenerator( new Client([ 'http_errors' => false, ]), - $this->parameter('auth0.domain') + $this->parameter('keycloak.domain'), + $this->parameter('keycloak.realm'), ); } } diff --git a/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php b/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php deleted file mode 100644 index 7f5e0de7..00000000 --- a/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php +++ /dev/null @@ -1,64 +0,0 @@ -domain = $domain; - $this->client = $client; - $this->logger = new NullLogger(); - } - - public function get(string $clientId, string $token): ?array - { - $response = $this->client->get( - 'https://' . $this->domain . '/api/v2/clients/' . $clientId, - [ - 'headers' => ['Authorization' => 'Bearer ' . $token], - ] - ); - - if ($response->getStatusCode() !== 200) { - $message = 'Auth0 error when getting metadata: ' . $response->getStatusCode(); - - if ($response->getStatusCode() >= 500) { - $this->logger->error($message); - throw new ConnectException( - $message, - new Request('GET', 'https://' . $this->domain . '/api/v2/clients/' . $clientId) - ); - } - - $this->logger->info($message); - return null; - } - - $res = Json::decodeAssociatively($response->getBody()->getContents()); - return $res['client_metadata'] ?? []; - } - - public function setLogger(LoggerInterface $logger): void - { - $this->logger = $logger; - } -} diff --git a/src/Http/Authentication/Auth0/Auth0TokenGenerator.php b/src/Http/Authentication/Auth0/Auth0TokenGenerator.php deleted file mode 100644 index 81f42d2a..00000000 --- a/src/Http/Authentication/Auth0/Auth0TokenGenerator.php +++ /dev/null @@ -1,89 +0,0 @@ -domain = $domain; - $this->client = $client; - $this->clientId = $clientId; - $this->clientSecret = $clientSecret; - $this->audience = $audience; - $this->logger = new NullLogger(); - } - - public function managementToken(): Token - { - return $this->fetchToken(); - } - - public function loginToken(): Token - { - return $this->fetchToken(); - } - - private function fetchToken(): Token - { - $response = $this->client->post( - 'https://' . $this->domain . '/oauth/token', - [ - 'headers' => ['content-type' => 'application/json'], - 'json' => [ - 'client_id' => $this->clientId, - 'client_secret' => $this->clientSecret, - 'audience' => 'https://' . $this->audience, - 'grant_type' => 'client_credentials', - ], - ] - ); - - if ($response->getStatusCode() !== 200) { - $message = 'Auth0 error when getting token: ' . $response->getStatusCode(); - - if ($response->getStatusCode() >= 500) { - $this->logger->error($message); - throw new ConnectException( - $message, - new Request('POST', 'https://' . $this->domain . '/oauth/token') - ); - } - - $this->logger->info($message); - } - - $res = Json::decodeAssociatively($response->getBody()->getContents()); - return new Token( - $res['access_token'], - new DateTimeImmutable(), - $res['expires_in'] - ); - } -} diff --git a/src/Http/Authentication/AuthenticateRequest.php b/src/Http/Authentication/AuthenticateRequest.php index 2e6e82c1..118207b6 100644 --- a/src/Http/Authentication/AuthenticateRequest.php +++ b/src/Http/Authentication/AuthenticateRequest.php @@ -92,7 +92,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface private function handleClientId(ServerRequestInterface $request, RequestHandlerInterface $handler, string $clientId): ResponseInterface { - $auth0Down = false; + $oAuthServerDown = false; $metadata = []; try { @@ -106,11 +106,11 @@ private function handleClientId(ServerRequestInterface $request, RequestHandlerI } } catch (ConnectException $connectException) { $this->logger->error('OAuth server was detected as down, this results in disabling authentication'); - $auth0Down = true; + $oAuthServerDown = true; } - // Bypass the sapi access validation when Auth0 is down to make sure sapi requests are still handled. - if (!$auth0Down && !$this->hasSapiAccess($metadata)) { + // Bypass the sapi access validation when the oauth server is down to make sure sapi requests are still handled. + if (!$oAuthServerDown && !$this->hasSapiAccess($metadata)) { return (new NotAllowedToUseSapi($clientId))->toResponse(); } @@ -145,7 +145,7 @@ private function handleAccessToken( } $config = $this->container->get(Config::class); - $jwtUrl = $config->get('keycloak.enabled') ? $config->get('jwt.domain') : null; + $jwtUrl = $config->get('jwt.domain'); if (!$token->isAllowedOnSearchApi($jwtUrl)) { return (new NotAllowedToUseSapi())->toResponse(); } diff --git a/tests/Http/Authentication/AuthenticateRequestTest.php b/tests/Http/Authentication/AuthenticateRequestTest.php index 4759b011..7592c7c9 100644 --- a/tests/Http/Authentication/AuthenticateRequestTest.php +++ b/tests/Http/Authentication/AuthenticateRequestTest.php @@ -13,7 +13,7 @@ use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\MissingCredentials; use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\NotAllowedToUseSapi; use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\RemovedApiKey; -use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0MetadataGenerator; +use CultuurNet\UDB3\Search\Http\Authentication\Keycloak\KeycloakMetadataGenerator; use CultuurNet\UDB3\Search\Http\Authentication\Token\Token; use CultuurNet\UDB3\Search\Http\Authentication\Token\TokenGenerator; use CultuurNet\UDB3\Search\Http\Authentication\Token\ManagementTokenProvider; @@ -70,7 +70,7 @@ protected function setUp(): void $this->pemFile = FileReader::read(__DIR__ . '/samples/public.pem'); $managementToken = new Token( - 'my_auth0_token', + 'my_oauth_token', new DateTimeImmutable(), 86400 ); @@ -301,7 +301,12 @@ public function it_handles_requests_with_client_id_with_missing_sapi_permission_ { $mockHandler = new MockHandler([ new Response(200, [], Json::encode([ - 'client_metadata' => ['publiq-apis' => 'ups entry'], + 0 => [ + 'defaultClientScopes' => [ + 'publiq-api-ups-scope', + 'publiq-api-entry-scope', + ], + ], ])), ]); @@ -309,9 +314,10 @@ public function it_handles_requests_with_client_id_with_missing_sapi_permission_ $this->container, $this->cultureFeed, $this->managementTokenProvider, - new Auth0MetadataGenerator( + new KeycloakMetadataGenerator( new Client(['handler' => $mockHandler]), - 'domain' + 'domain', + 'realm' ), new InMemoryDefaultQueryRepository([]), $this->pemFile @@ -345,9 +351,10 @@ public function it_handles_requests_with_client_id_without_metadata(): void $this->container, $this->cultureFeed, $this->managementTokenProvider, - new Auth0MetadataGenerator( + new KeycloakMetadataGenerator( new Client(['handler' => $mockHandler]), - 'domain' + 'domain', + 'realm' ), new InMemoryDefaultQueryRepository([]), $this->pemFile @@ -371,21 +378,22 @@ public function it_handles_requests_with_client_id_without_metadata(): void /** * @test */ - public function it_allows_all_access_when_auth0_is_down(): void + public function it_allows_all_access_when_oauth_server_is_down(): void { $request = (new ServerRequestFactory()) ->createServerRequest('GET', 'https://search.uitdatabank.be') ->withHeader('x-client-id', 'my_active_client_id'); - $mockHandler = new MockHandler([new ConnectException('No connection with Auth0', $request)]); + $mockHandler = new MockHandler([new ConnectException('No connection with OAuth server', $request)]); $authenticateRequest = new AuthenticateRequest( $this->container, $this->cultureFeed, $this->managementTokenProvider, - new Auth0MetadataGenerator( + new KeycloakMetadataGenerator( new Client(['handler' => $mockHandler]), - 'domain' + 'domain', + 'realm' ), new InMemoryDefaultQueryRepository([]), $this->pemFile @@ -422,7 +430,13 @@ public function it_handles_valid_requests_with_client_id(ServerRequestInterface { $mockHandler = new MockHandler([ new Response(200, [], Json::encode([ - 'client_metadata' => ['publiq-apis' => 'ups entry sapi'], + 0 => [ + 'defaultClientScopes' => [ + 'publiq-api-ups-scope', + 'publiq-api-entry-scope', + 'publiq-api-sapi-scope', + ], + ], ])), ]); @@ -430,9 +444,10 @@ public function it_handles_valid_requests_with_client_id(ServerRequestInterface $this->container, $this->cultureFeed, $this->managementTokenProvider, - new Auth0MetadataGenerator( + new KeycloakMetadataGenerator( new Client(['handler' => $mockHandler]), - 'domain' + 'domain', + 'realm' ), new InMemoryDefaultQueryRepository([]), $this->pemFile