Skip to content

Commit 61fa87f

Browse files
committed
cooldown for failed lookups/responses
1 parent 46d2367 commit 61fa87f

3 files changed

Lines changed: 62 additions & 12 deletions

File tree

src/TrustBoundaryTrait.php

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,6 @@ private function getTrustBoundary(
6767
return null;
6868
}
6969

70-
if (!array_key_exists('encodedLocations', $trustBoundary)) {
71-
throw new \LogicException('Trust boundary lookup failed to return \'encodedLocations\'');
72-
}
73-
7470
// Save to cache
7571
$tbLifetime = 6 * 60 * 60; // 6-hour cache TTL
7672
$this->setCachedValue($this->getCacheKey() . ':trustboundary', $trustBoundary, $tbLifetime);
@@ -156,13 +152,35 @@ private function lookupTrustBoundary(
156152
$request = $request->withHeader('authorization', $authHeader);
157153
try {
158154
$response = $httpHandler($request);
159-
return json_decode((string) $response->getBody(), true);
160155
} catch (RequestException $e) {
161-
// We swallow all errors here - a failed trust boundary lookup
156+
// An HTTP error occurred while requesting the trust boundary lookup
157+
// We swallow all errors here as a failed trust boundary lookup
158+
// should not disrupt client authentication.
159+
//@TODO Add debug logging
160+
$this->initiateCooldown();
161+
return null;
162+
}
163+
164+
$trustBoundary = json_decode((string) $response->getBody(), true);
165+
if (null === $trustBoundary) {
166+
// An error occurred during the JSON parsing of the request body
167+
// We swallow all errors here as a failed trust boundary lookup
162168
// should not disrupt client authentication.
169+
//@TODO Add debug logging
163170
$this->initiateCooldown();
171+
return null;
164172
}
165-
return null;
173+
174+
if (!array_key_exists('encodedLocations', $trustBoundary)) {
175+
// The JSON response did not contain expected "allowLocations"
176+
// We swallow all errors here as a failed trust boundary lookup
177+
// should not disrupt client authentication.
178+
//@TODO Add debug logging
179+
$this->initiateCooldown();
180+
return null;
181+
}
182+
183+
return $trustBoundary;
166184
}
167185

168186
private function initiateCooldown(): void

tests/ApplicationDefaultCredentialsTest.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -908,10 +908,7 @@ public function testUniverseDomainInGceCredentials()
908908
public function testTrustBoundaryLookupIntegration()
909909
{
910910
if ('true' !== getenv('RUN_TRUST_BOUNDARY_TESTS')) {
911-
$this->markTestSkipped(
912-
'This test requires RUN_TRUST_BOUNDARY_TESTS=true and a set of credentials with ' .
913-
'trust boundaries enabled'
914-
);
911+
$this->markTestSkipped('This test requires RUN_TRUST_BOUNDARY_TESTS=true');
915912
}
916913

917914
$creds = ApplicationDefaultCredentials::getCredentials(

tests/TrustBoundaryTraitTest.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ public function provideCooldown()
224224
/**
225225
* @dataProvider provideCooldown
226226
*/
227-
public function testCooldown(int $attempt, int $expectedExpiry)
227+
public function testInitiateCooldown(int $attempt, int $expectedExpiry)
228228
{
229229
$cache = $this->prophesize(CacheItemPoolInterface::class);
230230

@@ -274,6 +274,36 @@ public function testCooldown(int $attempt, int $expectedExpiry)
274274

275275
$this->assertNull($result1);
276276
}
277+
278+
public function provideMalformedResponseFromAllowLocationsLookup()
279+
{
280+
return [
281+
[200, '{"locations": ["us-west1"]}'], // missing allowLocations
282+
[200, '{"locations": ["us-west1"]'], // invalid JSON
283+
[401, ''], // 4xx error
284+
[500, ''], // 5xx error
285+
];
286+
}
287+
288+
/**
289+
* @dataProvider provideMalformedResponseFromAllowLocationsLookup
290+
*/
291+
public function testMalformedResponseFromAllowLocationsLookup(int $statusCode, string $responseBody)
292+
{
293+
$this->impl->setCache(new MemoryCacheItemPool());
294+
$handler = getHandler([
295+
new Response($statusCode, [], $responseBody),
296+
]);
297+
$result = $this->impl->getTrustBoundary(
298+
GetUniverseDomainInterface::DEFAULT_UNIVERSE_DOMAIN,
299+
$handler,
300+
'default',
301+
['authorization' => ['xyz']]
302+
);
303+
304+
$this->assertNull($result);
305+
$this->assertTrue($this->impl->cooldownIsActive());
306+
}
277307
}
278308

279309
class TrustBoundaryTraitImpl
@@ -305,4 +335,9 @@ public function setCache($cache)
305335
{
306336
$this->cache = $cache;
307337
}
338+
339+
public function cooldownIsActive(): bool
340+
{
341+
return (bool) $this->getCachedValue($this->getCacheKey() . ':trustboundary:cooldown');
342+
}
308343
}

0 commit comments

Comments
 (0)