Skip to content

Commit c9e806c

Browse files
authored
Merge pull request #166 from keboola/Branch_2904ae5d
Lost History - Support internal api auth in client
2 parents 0e321ab + 92ab58e commit c9e806c

File tree

6 files changed

+98
-24
lines changed

6 files changed

+98
-24
lines changed

src/Client.php

Lines changed: 52 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -44,23 +44,52 @@ public function __construct(
4444
LoggerInterface $logger,
4545
ExistingJobFactory $existingJobFactory,
4646
string $internalQueueApiUrl,
47-
string $internalQueueToken,
47+
?string $internalQueueToken,
48+
?string $storageApiToken,
4849
array $options = []
4950
) {
50-
$validator = Validation::createValidator();
51-
$errors = $validator->validate($internalQueueApiUrl, [new Url()]);
52-
$errors->addAll(
53-
$validator->validate($internalQueueToken, [new NotBlank()])
54-
);
51+
$this->validateConfiguration($internalQueueApiUrl, $internalQueueToken, $storageApiToken, $options);
5552
if (!empty($options['backoffMaxTries'])) {
56-
$errors->addAll($validator->validate($options['backoffMaxTries'], [new Range(['min' => 0, 'max' => 100])]));
5753
$options['backoffMaxTries'] = intval($options['backoffMaxTries']);
5854
} else {
5955
$options['backoffMaxTries'] = self::DEFAULT_BACKOFF_RETRIES;
6056
}
6157
if (empty($options['userAgent'])) {
6258
$options['userAgent'] = self::DEFAULT_USER_AGENT;
6359
}
60+
61+
$this->guzzle = $this->initClient($internalQueueApiUrl, $internalQueueToken, $storageApiToken, $options);
62+
$this->existingJobFactory = $existingJobFactory;
63+
$this->logger = $logger;
64+
}
65+
66+
private function validateConfiguration(
67+
string $internalQueueApiUrl,
68+
?string $internalQueueToken,
69+
?string $storageApiToken,
70+
array $options
71+
): void {
72+
$validator = Validation::createValidator();
73+
$errors = $validator->validate($internalQueueApiUrl, [new Url()]);
74+
if ($internalQueueToken === null && $storageApiToken === null) {
75+
throw new ClientException('Both InternalApiToken and StorageAPIToken are empty.');
76+
}
77+
if ($internalQueueToken !== null && $storageApiToken !== null) {
78+
throw new ClientException('Both InternalApiToken and StorageAPIToken are non-empty. Use only one.');
79+
}
80+
if ($internalQueueToken !== null) {
81+
$errors->addAll(
82+
$validator->validate($internalQueueToken, [new NotBlank()])
83+
);
84+
}
85+
if ($storageApiToken !== null) {
86+
$errors->addAll(
87+
$validator->validate($storageApiToken, [new NotBlank()])
88+
);
89+
}
90+
if (!empty($options['backoffMaxTries'])) {
91+
$errors->addAll($validator->validate($options['backoffMaxTries'], [new Range(['min' => 0, 'max' => 100])]));
92+
}
6493
if ($errors->count() !== 0) {
6594
$messages = '';
6695
/** @var ConstraintViolationInterface $error */
@@ -69,9 +98,6 @@ public function __construct(
6998
}
7099
throw new ClientException('Invalid parameters when creating client: ' . $messages);
71100
}
72-
$this->guzzle = $this->initClient($internalQueueApiUrl, $internalQueueToken, $options);
73-
$this->existingJobFactory = $existingJobFactory;
74-
$this->logger = $logger;
75101
}
76102

77103
public function addJobUsage(string $jobId, array $usage): void
@@ -316,8 +342,12 @@ private function createDefaultDecider(int $maxRetries): Closure
316342
};
317343
}
318344

319-
private function initClient(string $url, string $token, array $options = []): GuzzleClient
320-
{
345+
private function initClient(
346+
string $url,
347+
?string $internalToken,
348+
?string $storageToken,
349+
array $options = []
350+
): GuzzleClient {
321351
// Initialize handlers (start with those supplied in constructor)
322352
if (isset($options['handler']) && is_callable($options['handler'])) {
323353
$handlerStack = HandlerStack::create($options['handler']);
@@ -328,11 +358,16 @@ private function initClient(string $url, string $token, array $options = []): Gu
328358
$handlerStack->push(Middleware::retry($this->createDefaultDecider($options['backoffMaxTries'])));
329359
// Set handler to set default headers
330360
$handlerStack->push(Middleware::mapRequest(
331-
function (RequestInterface $request) use ($token, $options) {
332-
return $request
333-
->withHeader('User-Agent', $options['userAgent'])
334-
->withHeader('X-JobQueue-InternalApi-Token', $token)
335-
->withHeader('Content-type', 'application/json');
361+
function (RequestInterface $request) use ($internalToken, $storageToken, $options) {
362+
$request = $request->withHeader('User-Agent', $options['userAgent'])
363+
->withHeader('Content-type', 'application/json');
364+
if ($internalToken !== null) {
365+
$request = $request->withHeader('X-JobQueue-InternalApi-Token', $internalToken);
366+
}
367+
if ($storageToken !== null) {
368+
$request = $request->withHeader('X-StorageApi-Token', $storageToken);
369+
}
370+
return $request;
336371
}
337372
));
338373
// Set client logger

src/ClientFactory.php

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,21 @@
99
class ClientFactory
1010
{
1111
private string $internalApiUrl;
12-
private string $internalApiToken;
12+
private ?string $internalApiToken;
1313
private ExistingJobFactory $existingJobFactory;
1414
private LoggerInterface $logger;
15+
private ?string $storageApiToken;
1516

1617
public function __construct(
1718
string $internalApiUrl,
18-
string $internalApiToken,
19+
?string $internalApiToken,
1920
ExistingJobFactory $existingJobFactory,
20-
LoggerInterface $logger
21+
LoggerInterface $logger,
22+
?string $storageApiToken = null
2123
) {
2224
$this->internalApiUrl = $internalApiUrl;
2325
$this->internalApiToken = $internalApiToken;
26+
$this->storageApiToken = $storageApiToken;
2427
$this->existingJobFactory = $existingJobFactory;
2528
$this->logger = $logger;
2629
}
@@ -32,6 +35,7 @@ public function getClient(): Client
3235
$this->existingJobFactory,
3336
$this->internalApiUrl,
3437
$this->internalApiToken,
38+
$this->storageApiToken,
3539
[
3640
'backoffMaxTries' => 2,
3741
'userAgent' => 'Public API',

tests/BaseClientFunctionalTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,7 @@ protected function getClient(?string $kmsKeyId = null, ?string $keyVaultUrl = nu
6868
$existingJobFactory,
6969
(string) getenv('TEST_QUEUE_API_URL'),
7070
(string) getenv('TEST_QUEUE_API_TOKEN'),
71+
null,
7172
);
7273
}
7374

tests/ClientExceptionTest.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ private function getClient(array $options): Client
5151
$existingJobFactory,
5252
'http://example.com/',
5353
'testToken',
54+
null,
5455
$options
5556
);
5657
}

tests/ClientFunctionalTest.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
namespace Keboola\JobQueueInternalClient\Tests;
66

77
use DateTimeImmutable;
8+
use Keboola\JobQueueInternalClient\Client;
89
use Keboola\JobQueueInternalClient\Exception\ClientException;
910
use Keboola\JobQueueInternalClient\Exception\StateTargetEqualsCurrentException;
1011
use Keboola\JobQueueInternalClient\JobFactory\Job;
@@ -17,6 +18,7 @@
1718
use Keboola\StorageApi\Client as StorageClient;
1819
use Keboola\StorageApi\Components;
1920
use Keboola\StorageApi\Options\Components\Configuration;
21+
use Psr\Log\NullLogger;
2022

2123
class ClientFunctionalTest extends BaseClientFunctionalTest
2224
{

tests/ClientTest.php

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ private function getClient(array $options, ?LoggerInterface $logger = null): Cli
5959
$jobFactory,
6060
'http://example.com/',
6161
'testToken',
62+
null,
6263
$options
6364
);
6465
}
@@ -74,6 +75,7 @@ public function testCreateClientInvalidBackoff(): void
7475
$this->createMock(ExistingJobFactory::class),
7576
'http://example.com/',
7677
'testToken',
78+
null,
7779
['backoffMaxTries' => 'abc']
7880
);
7981
}
@@ -89,6 +91,7 @@ public function testCreateClientTooLowBackoff(): void
8991
$this->createMock(ExistingJobFactory::class),
9092
'http://example.com/',
9193
'testToken',
94+
null,
9295
['backoffMaxTries' => -1]
9396
);
9497
}
@@ -104,17 +107,45 @@ public function testCreateClientTooHighBackoff(): void
104107
$this->createMock(ExistingJobFactory::class),
105108
'http://example.com/',
106109
'testToken',
110+
null,
107111
['backoffMaxTries' => 101]
108112
);
109113
}
110114

111-
public function testCreateClientInvalidToken(): void
115+
public function testCreateClientInvalidQueueToken(): void
112116
{
113117
$this->expectException(ClientException::class);
114118
$this->expectExceptionMessage(
115119
'Invalid parameters when creating client: Value "" is invalid: This value should not be blank.'
116120
);
117-
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'http://example.com/', '');
121+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'http://example.com/', '', null);
122+
}
123+
124+
public function testCreateClientInvalidStorageToken(): void
125+
{
126+
$this->expectException(ClientException::class);
127+
$this->expectExceptionMessage(
128+
'Invalid parameters when creating client: Value "" is invalid: This value should not be blank.'
129+
);
130+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'http://example.com/', null, '');
131+
}
132+
133+
public function testCreateClientNoToken(): void
134+
{
135+
$this->expectException(ClientException::class);
136+
$this->expectExceptionMessage(
137+
'Both InternalApiToken and StorageAPIToken are empty.'
138+
);
139+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'http://example.com/', null, null);
140+
}
141+
142+
public function testCreateClientBothTokens(): void
143+
{
144+
$this->expectException(ClientException::class);
145+
$this->expectExceptionMessage(
146+
'Both InternalApiToken and StorageAPIToken are non-empty. Use only one.'
147+
);
148+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'http://example.com/', 'a', 'b');
118149
}
119150

120151
public function testCreateClientInvalidUrl(): void
@@ -123,7 +154,7 @@ public function testCreateClientInvalidUrl(): void
123154
$this->expectExceptionMessage(
124155
'Invalid parameters when creating client: Value "invalid url" is invalid: This value is not a valid URL.'
125156
);
126-
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'invalid url', 'testToken');
157+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'invalid url', 'testToken', null);
127158
}
128159

129160
public function testCreateClientMultipleErrors(): void
@@ -133,7 +164,7 @@ public function testCreateClientMultipleErrors(): void
133164
'Invalid parameters when creating client: Value "invalid url" is invalid: This value is not a valid URL.'
134165
. "\n" . 'Value "" is invalid: This value should not be blank.' . "\n"
135166
);
136-
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'invalid url', '');
167+
new Client(new NullLogger(), $this->createMock(ExistingJobFactory::class), 'invalid url', '', null);
137168
}
138169

139170
public function testClientRequestResponse(): void

0 commit comments

Comments
 (0)