Skip to content

Commit

Permalink
fix: explicit token caching issue (#2358)
Browse files Browse the repository at this point in the history
  • Loading branch information
bshaffer authored Oct 16, 2024
1 parent 76c312e commit dc13e5e
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 1 deletion.
10 changes: 9 additions & 1 deletion src/AuthHandler/Guzzle6AuthHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,18 @@ public function attachToken(ClientInterface $http, array $token, array $scopes)
return $token['access_token'];
};

// Derive a cache prefix from the token, to ensure setting a new token
// results in a cache-miss.
// Note: Supplying a custom "prefix" will bust this behavior.
$cacheConfig = $this->cacheConfig;
if (!isset($cacheConfig['prefix']) && isset($token['access_token'])) {
$cacheConfig['prefix'] = substr(sha1($token['access_token']), -10);
}

$middleware = new ScopedAccessTokenMiddleware(
$tokenFunc,
$scopes,
$this->cacheConfig,
$cacheConfig,
$this->cache
);

Expand Down
82 changes: 82 additions & 0 deletions tests/Google/AuthHandler/AuthHandlerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php
/**
* Copyright 2022 Google LLC
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

namespace Google\Tests\AuthHandler;

use Google\AuthHandler\AuthHandlerFactory;
use Google\Auth\Cache\MemoryCacheItemPool;
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Request;
use Google\Tests\BaseTest;

class AuthHandlerTest extends BaseTest
{
public function testSetAccessTokenResultsInAuthCacheMiss()
{
$client = new Client();
$cache = new MemoryCacheItemPool();
$authHandler = AuthHandlerFactory::build($cache);
$scopes = ['scope1', 'scope2'];

// Attach the first token to the HTTP client
$http1 = $authHandler->attachToken(
$client,
['access_token' => '1234'],
$scopes
);

// Call our middleware and verify the token is set
$scopedMiddleware = $this->getGoogleAuthMiddleware($http1);
$request = $scopedMiddleware(new Request('GET', '/'), ['auth' => 'scoped']);
$this->assertEquals(['Bearer 1234'], $request->getHeader('Authorization'));

// Attach a new token to the HTTP client
$http2 = $authHandler->attachToken(
$client,
['access_token' => '5678'],
$scopes
);

// Call our middleware and verify the NEW token is set
$scopedMiddleware = $this->getGoogleAuthMiddleware($http2);
$request = $scopedMiddleware(new Request('GET', '/'), ['auth' => 'scoped']);
$this->assertEquals(['Bearer 5678'], $request->getHeader('Authorization'));
}

private function getGoogleAuthMiddleware(Client $http)
{
// All sorts of horrible reflection to get at our middleware
$handler = $http->getConfig()['handler'];
$reflectionMethod = new \ReflectionMethod($handler, 'findByName');
$reflectionMethod->setAccessible(true);
$authMiddlewareIdx = $reflectionMethod->invoke($handler, 'google_auth');

$reflectionProperty = new \ReflectionProperty($handler, 'stack');
$reflectionProperty->setAccessible(true);
$stack = $reflectionProperty->getValue($handler);

$callable = $stack[$authMiddlewareIdx][0];
return $callable(function ($request) {
return $request;
});
}
}

0 comments on commit dc13e5e

Please sign in to comment.