Skip to content

Commit

Permalink
chore: add phpstan level 7 (#392)
Browse files Browse the repository at this point in the history
  • Loading branch information
bshaffer authored Apr 12, 2022
1 parent 321e5b6 commit 3a1a5c5
Show file tree
Hide file tree
Showing 31 changed files with 469 additions and 360 deletions.
15 changes: 15 additions & 0 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,18 @@ jobs:
run: |
composer require friendsofphp/php-cs-fixer:^3.0
vendor/bin/php-cs-fixer fix --dry-run --diff
staticanalysis:
runs-on: ubuntu-latest
name: PHPStan Static Analysis
steps:
- uses: actions/checkout@v2
- name: Install PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
- name: Run Script
run: |
composer install
composer global require phpstan/phpstan
~/.composer/vendor/bin/phpstan analyse
10 changes: 10 additions & 0 deletions phpstan.neon.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
parameters:
treatPhpDocTypesAsCertain: false
level: 7
paths:
- src
featureToggles:
disableRuntimeReflectionProvider: true
excludePaths:
- src/HttpHandler/Guzzle5HttpHandler.php
- src/Cache/Item.php
71 changes: 39 additions & 32 deletions src/AccessToken.php
Original file line number Diff line number Diff line change
Expand Up @@ -82,20 +82,22 @@ public function __construct(
* accepted. By default, the id token must have been issued to this OAuth2 client.
*
* @param string $token The JSON Web Token to be verified.
* @param array $options [optional] Configuration options.
* @param string $options.audience The indended recipient of the token.
* @param string $options.issuer The intended issuer of the token.
* @param string $options.cacheKey The cache key of the cached certs. Defaults to
* @param array<mixed> $options [optional] {
* Configuration options.
* @type string $audience The indended recipient of the token.
* @type string $issuer The intended issuer of the token.
* @type string $cacheKey The cache key of the cached certs. Defaults to
* the sha1 of $certsLocation if provided, otherwise is set to
* "federated_signon_certs_v3".
* @param string $options.certsLocation The location (remote or local) from which
* @type string $certsLocation The location (remote or local) from which
* to retrieve certificates, if not cached. This value should only be
* provided in limited circumstances in which you are sure of the
* behavior.
* @param bool $options.throwException Whether the function should throw an
* @type bool $throwException Whether the function should throw an
* exception if the verification fails. This is useful for
* determining the reason verification failed.
* @return array|bool the token payload, if successful, or false if not.
* }
* @return array<mixed>|false the token payload, if successful, or false if not.
* @throws InvalidArgumentException If certs could not be retrieved from a local file.
* @throws InvalidArgumentException If received certs are in an invalid format.
* @throws InvalidArgumentException If the cert alg is not supported.
Expand Down Expand Up @@ -134,12 +136,10 @@ public function verify($token, array $options = [])
return $this->verifyRs256($token, $certs, $audience, $issuer);
}
return $this->verifyEs256($token, $certs, $audience, $issuer);
} catch (ExpiredException $e) { // firebase/php-jwt 3+
} catch (\ExpiredException $e) { // firebase/php-jwt 2
} catch (SignatureInvalidException $e) { // firebase/php-jwt 3+
} catch (\SignatureInvalidException $e) { // firebase/php-jwt 2
} catch (ExpiredException $e) { // firebase/php-jwt 5+
} catch (SignatureInvalidException $e) { // firebase/php-jwt 5+
} catch (InvalidTokenException $e) { // simplejwt
} catch (DomainException $e) {
} catch (DomainException $e) { // @phpstan-ignore-line
} catch (InvalidArgumentException $e) {
} catch (UnexpectedValueException $e) {
}
Expand All @@ -155,7 +155,7 @@ public function verify($token, array $options = [])
* Identifies the expected algorithm to verify by looking at the "alg" key
* of the provided certs.
*
* @param array $certs Certificate array according to the JWK spec (see
* @param array<mixed> $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @return string The expected algorithm, such as "ES256" or "RS256".
*/
Expand Down Expand Up @@ -183,13 +183,13 @@ private function determineAlg(array $certs)
* Verifies an ES256-signed JWT.
*
* @param string $token The JSON Web Token to be verified.
* @param array $certs Certificate array according to the JWK spec (see
* @param array<mixed> $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @param string|null $audience If set, returns false if the provided
* audience does not match the "aud" claim on the JWT.
* @param string|null $issuer If set, returns false if the provided
* issuer does not match the "iss" claim on the JWT.
* @return array|bool the token payload, if successful, or false if not.
* @return array<mixed> the token payload, if successful, or false if not.
*/
private function verifyEs256($token, array $certs, $audience = null, $issuer = null)
{
Expand Down Expand Up @@ -223,13 +223,13 @@ private function verifyEs256($token, array $certs, $audience = null, $issuer = n
* Verifies an RS256-signed JWT.
*
* @param string $token The JSON Web Token to be verified.
* @param array $certs Certificate array according to the JWK spec (see
* @param array<mixed> $certs Certificate array according to the JWK spec (see
* https://tools.ietf.org/html/rfc7517).
* @param string|null $audience If set, returns false if the provided
* audience does not match the "aud" claim on the JWT.
* @param string|null $issuer If set, returns false if the provided
* issuer does not match the "iss" claim on the JWT.
* @return array|bool the token payload, if successful, or false if not.
* @return array<mixed> the token payload, if successful, or false if not.
*/
private function verifyRs256($token, array $certs, $audience = null, $issuer = null)
{
Expand Down Expand Up @@ -286,8 +286,8 @@ private function verifyRs256($token, array $certs, $audience = null, $issuer = n
* Revoke an OAuth2 access token or refresh token. This method will revoke the current access
* token, if a token isn't provided.
*
* @param string|array $token The token (access token or a refresh token) that should be revoked.
* @param array $options [optional] Configuration options.
* @param string|array<mixed> $token The token (access token or a refresh token) that should be revoked.
* @param array<mixed> $options [optional] Configuration options.
* @return bool Returns True if the revocation was successful, otherwise False.
*/
public function revoke($token, array $options = [])
Expand Down Expand Up @@ -320,14 +320,14 @@ public function revoke($token, array $options = [])
*
* @param string $location The location from which to retrieve certs.
* @param string $cacheKey The key under which to cache the retrieved certs.
* @param array $options [optional] Configuration options.
* @return array
* @param array<mixed> $options [optional] Configuration options.
* @return array<mixed>
* @throws InvalidArgumentException If received certs are in an invalid format.
*/
private function getCerts($location, $cacheKey, array $options = [])
{
$cacheItem = $this->cache->getItem($cacheKey);
$certs = $cacheItem ? $cacheItem->get() : null;
$certs = $cacheItem ? $cacheItem->get() : null; // @phpstan-ignore-line

$gotNewCerts = false;
if (!$certs) {
Expand Down Expand Up @@ -361,9 +361,9 @@ private function getCerts($location, $cacheKey, array $options = [])
/**
* Retrieve and cache a certificates file.
*
* @param $url string location
* @param array $options [optional] Configuration options.
* @return array certificates
* @param string $url location
* @param array<mixed> $options [optional] Configuration options.
* @return array<mixed> certificates
* @throws InvalidArgumentException If certs could not be retrieved from a local file.
* @throws RuntimeException If certs could not be retrieved from a remote location.
*/
Expand All @@ -378,7 +378,7 @@ private function retrieveCertsFromLocation($url, array $options = [])
));
}

return json_decode(file_get_contents($url), true);
return json_decode((string) file_get_contents($url), true);
}

$httpHandler = $this->httpHandler;
Expand All @@ -394,6 +394,9 @@ private function retrieveCertsFromLocation($url, array $options = [])
), $response->getStatusCode());
}

/**
* @return void
*/
private function checkAndInitializePhpsec()
{
// @codeCoverageIgnoreStart
Expand All @@ -405,10 +408,13 @@ private function checkAndInitializePhpsec()
$this->setPhpsecConstants();
}

/**
* @return void
*/
private function checkSimpleJwt()
{
// @codeCoverageIgnoreStart
if (!class_exists('SimpleJWT\JWT')) {
if (!class_exists(SimpleJwt::class)) {
throw new RuntimeException('Please require kelvinmo/simplejwt ^0.2 to use this utility.');
}
// @codeCoverageIgnoreEnd
Expand All @@ -422,6 +428,8 @@ private function checkSimpleJwt()
* @see phpseclib/Math/BigInteger
* @see https://github.com/GoogleCloudPlatform/getting-started-php/issues/85
* @codeCoverageIgnore
*
* @return void
*/
private function setPhpsecConstants()
{
Expand All @@ -439,24 +447,23 @@ private function setPhpsecConstants()
* Provide a hook to mock calls to the JWT static methods.
*
* @param string $method
* @param array $args
* @param array<mixed> $args
* @return mixed
*/
protected function callJwtStatic($method, array $args = [])
{
$class = 'Firebase\JWT\JWT';
return call_user_func_array([$class, $method], $args);
return call_user_func_array([JWT::class, $method], $args); // @phpstan-ignore-line
}

/**
* Provide a hook to mock calls to the JWT static methods.
*
* @param array $args
* @param array<mixed> $args
* @return mixed
*/
protected function callSimpleJwtDecode(array $args = [])
{
return call_user_func_array(['SimpleJWT\JWT', 'decode'], $args);
return call_user_func_array([SimpleJwt::class, 'decode'], $args);
}

/**
Expand Down
38 changes: 25 additions & 13 deletions src/ApplicationDefaultCredentials.php
Original file line number Diff line number Diff line change
Expand Up @@ -70,29 +70,32 @@
class ApplicationDefaultCredentials
{
/**
* @deprecated
*
* Obtains an AuthTokenSubscriber that uses the default FetchAuthTokenInterface
* implementation to use in this environment.
*
* If supplied, $scope is used to in creating the credentials instance if
* this does not fallback to the compute engine defaults.
*
* @param string|array scope the scope of the access request, expressed
* @param string|string[] $scope the scope of the access request, expressed
* either as an Array or as a space-delimited String.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @return AuthTokenSubscriber
* @throws DomainException if no implementation can be obtained.
*/
public static function getSubscriber(
public static function getSubscriber(// @phpstan-ignore-line
$scope = null,
callable $httpHandler = null,
array $cacheConfig = null,
CacheItemPoolInterface $cache = null
) {
$creds = self::getCredentials($scope, $httpHandler, $cacheConfig, $cache);

/** @phpstan-ignore-next-line */
return new AuthTokenSubscriber($creds, $httpHandler);
}

Expand All @@ -103,10 +106,10 @@ public static function getSubscriber(
* If supplied, $scope is used to in creating the credentials instance if
* this does not fallback to the compute engine defaults.
*
* @param string|array scope the scope of the access request, expressed
* @param string|string[] $scope the scope of the access request, expressed
* either as an Array or as a space-delimited String.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @param string $quotaProject specifies a project to bill for access
Expand All @@ -130,19 +133,19 @@ public static function getMiddleware(
* Obtains the default FetchAuthTokenInterface implementation to use
* in this environment.
*
* @param string|array $scope the scope of the access request, expressed
* @param string|string[] $scope the scope of the access request, expressed
* either as an Array or as a space-delimited String.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @param string $quotaProject specifies a project to bill for access
* charges associated with the request.
* @param string|array $defaultScope The default scope to use if no
* @param string|string[] $defaultScope The default scope to use if no
* user-defined scopes exist, expressed either as an Array or as a
* space-delimited string.
*
* @return CredentialsLoader
* @return FetchAuthTokenInterface
* @throws DomainException if no implementation can be obtained.
*/
public static function getCredentials(
Expand Down Expand Up @@ -201,7 +204,7 @@ public static function getCredentials(
*
* @param string $targetAudience The audience for the ID token.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @return AuthTokenMiddleware
Expand All @@ -228,7 +231,7 @@ public static function getIdTokenMiddleware(
*
* @param string $targetAudience The audience for the ID token.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @return ProxyAuthTokenMiddleware
Expand All @@ -252,10 +255,10 @@ public static function getProxyIdTokenMiddleware(
*
* @param string $targetAudience The audience for the ID token.
* @param callable $httpHandler callback which delivers psr7 request
* @param array $cacheConfig configuration for the cache when it's present
* @param array<mixed> $cacheConfig configuration for the cache when it's present
* @param CacheItemPoolInterface $cache A cache implementation, may be
* provided if you have one already available for use.
* @return CredentialsLoader
* @return FetchAuthTokenInterface
* @throws DomainException if no implementation can be obtained.
* @throws InvalidArgumentException if JSON "type" key is invalid
*/
Expand Down Expand Up @@ -305,6 +308,9 @@ public static function getIdTokenCredentials(
return $creds;
}

/**
* @return string
*/
private static function notFound()
{
$msg = 'Could not load the default credentials. Browse to ';
Expand All @@ -315,6 +321,12 @@ private static function notFound()
return $msg;
}

/**
* @param callable $httpHandler
* @param array<mixed> $cacheConfig
* @param CacheItemPoolInterface $cache
* @return bool
*/
private static function onGce(
callable $httpHandler = null,
array $cacheConfig = null,
Expand Down
Loading

0 comments on commit 3a1a5c5

Please sign in to comment.