Skip to content

Commit

Permalink
Merge pull request #290 from cultuurnet/III-6220-generic-management-t…
Browse files Browse the repository at this point in the history
…oken

III-6220 Refactor ManagementToken as preparation for Keycloak
  • Loading branch information
LucWollants authored Jun 19, 2024
2 parents 53b32ad + 5d869ca commit c2b622b
Show file tree
Hide file tree
Showing 21 changed files with 522 additions and 560 deletions.
6 changes: 3 additions & 3 deletions app/JsonDocumentFetcherProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

namespace CultuurNet\UDB3\SearchService;

use CultuurNet\UDB3\Search\Http\Authentication\Auth0Client;
use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0ManagementTokenGenerator;
use CultuurNet\UDB3\Search\JsonDocument\GuzzleJsonDocumentFetcher;
use CultuurNet\UDB3\Search\JsonDocument\JsonDocumentFetcher;
use GuzzleHttp\Client;
Expand All @@ -24,15 +24,15 @@ public function register(): void
'http_errors' => false,
]),
$this->get('logger.amqp.udb3'),
new Auth0Client(
new Auth0ManagementTokenGenerator(
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')
)
),
)
);
}
Expand Down
32 changes: 19 additions & 13 deletions app/RoutingServiceProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,14 @@

namespace CultuurNet\UDB3\SearchService;

use CultureFeed_DefaultOAuthClient;
use CultureFeed;
use CultuurNet\UDB3\Search\Http\Authentication\Auth0Client;
use CultuurNet\UDB3\Search\Http\Authentication\Auth0TokenFileRepository;
use CultuurNet\UDB3\Search\Http\Authentication\Auth0TokenProvider;
use CultureFeed_DefaultOAuthClient;
use CultuurNet\UDB3\Search\Http\Authentication\Auth0\Auth0ManagementTokenGenerator;
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\ManagementToken\ManagementTokenFileRepository;
use CultuurNet\UDB3\Search\Http\Authentication\ManagementToken\ManagementTokenProvider;
use CultuurNet\UDB3\Search\Http\DefaultQuery\InMemoryDefaultQueryRepository;
use CultuurNet\UDB3\Search\Http\OrganizerSearchController;
use CultuurNet\UDB3\SearchService\Error\LoggerFactory;
Expand Down Expand Up @@ -47,27 +48,32 @@ function (): Router {
);
$oauthClient->setEndpoint($this->parameter('uitid.base_url'));

$auth0Client = new Auth0Client(
$auth0Client = new Auth0MetadataGenerator(
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/'
$this->parameter('auth0.domain')
);

$auth0TokenProvider = new Auth0TokenProvider(
new Auth0TokenFileRepository(__DIR__ . '/../cache/auth0-token-cache.json'),
$auth0Client
$managementTokenProvider = new ManagementTokenProvider(
new Auth0ManagementTokenGenerator(
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 ManagementTokenFileRepository(__DIR__ . '/../cache/auth0-management-token-cache.json'),
);

$pemFile = $this->parameter('keycloak.enabled') ?
$this->parameter('keycloak.pem_file') : $this->parameter('auth0.pem_file');
$authenticateRequest = new AuthenticateRequest(
$this->getLeagueContainer(),
new CultureFeed($oauthClient),
$auth0TokenProvider,
$managementTokenProvider,
$auth0Client,
new InMemoryDefaultQueryRepository(
file_exists(__DIR__ . '/../default_queries.php') ? require __DIR__ . '/../default_queries.php' : []
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Authentication;
namespace CultuurNet\UDB3\Search\Http\Authentication\Auth0;

use CultuurNet\UDB3\Search\Http\Authentication\ManagementToken\ManagementToken;
use CultuurNet\UDB3\Search\Http\Authentication\ManagementToken\ManagementTokenGenerator;
use CultuurNet\UDB3\Search\Json;
use DateTimeImmutable;
use GuzzleHttp\Client;
Expand All @@ -13,7 +15,7 @@
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;

final class Auth0Client implements LoggerAwareInterface
final class Auth0ManagementTokenGenerator implements ManagementTokenGenerator, LoggerAwareInterface
{
use LoggerAwareTrait;

Expand Down Expand Up @@ -42,7 +44,7 @@ public function __construct(
$this->logger = new NullLogger();
}

public function getToken(): ?Auth0Token
public function newToken(): ManagementToken
{
$response = $this->client->post(
'https://' . $this->domain . '/oauth/token',
Expand All @@ -69,42 +71,13 @@ public function getToken(): ?Auth0Token
}

$this->logger->info($message);
return null;
}

$res = Json::decodeAssociatively($response->getBody()->getContents());
return new Auth0Token(
return new ManagementToken(
$res['access_token'],
new DateTimeImmutable(),
$res['expires_in']
);
}

public function getMetadata(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'] ?? [];
}
}
60 changes: 60 additions & 0 deletions src/Http/Authentication/Auth0/Auth0MetadataGenerator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Authentication\Auth0;

use CultuurNet\UDB3\Search\Http\Authentication\MetadataGenerator;
use CultuurNet\UDB3\Search\Json;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Psr7\Request;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerAwareTrait;
use Psr\Log\NullLogger;

final class Auth0MetadataGenerator implements MetadataGenerator, LoggerAwareInterface
{
use LoggerAwareTrait;

private Client $client;

private string $domain;

public function __construct(
Client $client,
string $domain
) {
$this->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'] ?? [];
}
}
37 changes: 0 additions & 37 deletions src/Http/Authentication/Auth0TokenProvider.php

This file was deleted.

12 changes: 0 additions & 12 deletions src/Http/Authentication/Auth0TokenRepository.php

This file was deleted.

20 changes: 12 additions & 8 deletions src/Http/Authentication/AuthenticateRequest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@
namespace CultuurNet\UDB3\Search\Http\Authentication;

use CultureFeed_Consumer;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\BlockedApiKey;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\InvalidApiKey;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\InvalidClientId;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\InvalidToken;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\MissingCredentials;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\BlockedApiKey;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\NotAllowedToUseSapi;
use CultuurNet\UDB3\Search\Http\Authentication\ApiProblems\RemovedApiKey;
use CultuurNet\UDB3\Search\Http\Authentication\ManagementToken\ManagementTokenProvider;
use CultuurNet\UDB3\Search\Http\DefaultQuery\DefaultQueryRepository;
use Exception;
use GuzzleHttp\Exception\ConnectException;
Expand All @@ -36,9 +37,9 @@ final class AuthenticateRequest implements MiddlewareInterface, LoggerAwareInter

private ICultureFeed $cultureFeed;

private Auth0TokenProvider $auth0TokenProvider;
private ManagementTokenProvider $managementTokenProvider;

private Auth0Client $auth0Client;
private MetadataGenerator $metadataGenerator;

private DefaultQueryRepository $defaultQueryRepository;

Expand All @@ -47,15 +48,15 @@ final class AuthenticateRequest implements MiddlewareInterface, LoggerAwareInter
public function __construct(
Container $container,
ICultureFeed $cultureFeed,
Auth0TokenProvider $auth0TokenProvider,
Auth0Client $auth0Client,
ManagementTokenProvider $managementTokenProvider,
MetadataGenerator $metadataGenerator,
DefaultQueryRepository $defaultQueryRepository,
string $pemFile
) {
$this->container = $container;
$this->cultureFeed = $cultureFeed;
$this->auth0TokenProvider = $auth0TokenProvider;
$this->auth0Client = $auth0Client;
$this->managementTokenProvider = $managementTokenProvider;
$this->metadataGenerator = $metadataGenerator;
$this->defaultQueryRepository = $defaultQueryRepository;
$this->pemFile = $pemFile;
$this->setLogger(new NullLogger());
Expand Down Expand Up @@ -94,7 +95,10 @@ private function handleClientId(ServerRequestInterface $request, RequestHandlerI
$metadata = [];

try {
$metadata = $this->auth0Client->getMetadata($clientId, $this->auth0TokenProvider->get()->getToken());
$metadata = $this->metadataGenerator->get(
$clientId,
$this->managementTokenProvider->token()
);

if ($metadata === null) {
return (new InvalidClientId($clientId))->toResponse();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Authentication;
namespace CultuurNet\UDB3\Search\Http\Authentication\ManagementToken;

use DateTimeImmutable;

final class Auth0Token
final class ManagementToken
{
private string $token;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Authentication;
namespace CultuurNet\UDB3\Search\Http\Authentication\ManagementToken;

use CultuurNet\UDB3\Search\Json;
use DateTimeImmutable;

final class Auth0TokenFileRepository implements Auth0TokenRepository
final class ManagementTokenFileRepository implements ManagementTokenRepository
{
private string $fullFilePath;

Expand All @@ -16,22 +16,22 @@ public function __construct(string $fullFilePath)
$this->fullFilePath = $fullFilePath;
}

public function get(): ?Auth0Token
public function get(): ?ManagementToken
{
if (!file_exists($this->fullFilePath)) {
return null;
}

$tokenAsArray = Json::decodeAssociatively(file_get_contents($this->fullFilePath));

return new Auth0Token(
return new ManagementToken(
$tokenAsArray['token'],
new DateTimeImmutable($tokenAsArray['issuesAt']),
$tokenAsArray['expiresIn']
);
}

public function set(Auth0Token $token): void
public function set(ManagementToken $token): void
{
$tokenAsJson = Json::encode([
'token' => $token->getToken(),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<?php

declare(strict_types=1);

namespace CultuurNet\UDB3\Search\Http\Authentication\ManagementToken;

interface ManagementTokenGenerator
{
public function newToken(): ManagementToken;
}
Loading

0 comments on commit c2b622b

Please sign in to comment.