From 8d3678a9816d09ccb4faf46a8838c37a0f3f5406 Mon Sep 17 00:00:00 2001 From: Konstantin Babushkin Date: Mon, 5 Feb 2024 08:55:40 +0100 Subject: [PATCH 1/4] add errorVerbosity --- doc/setup.rst | 32 +++++++++--- src/Common/Auth/IdentityService.php | 2 +- src/Common/Error/Builder.php | 55 ++++++++++++-------- src/Common/Service/Builder.php | 39 +++----------- src/Common/Transport/HandlerStack.php | 3 ++ src/Common/Transport/HandlerStackFactory.php | 38 ++++++++++++++ src/Common/Transport/Middleware.php | 10 ++-- src/Identity/v3/Service.php | 2 +- src/OpenStack.php | 13 ++--- tests/sample/Identity/v3/TokenTest.php | 34 ++++++++++++ tests/unit/Common/Error/BuilderTest.php | 23 ++++++-- tests/unit/Identity/v3/ServiceTest.php | 1 - 12 files changed, 170 insertions(+), 82 deletions(-) diff --git a/doc/setup.rst b/doc/setup.rst index 96fa29571..503a0c740 100644 --- a/doc/setup.rst +++ b/doc/setup.rst @@ -13,31 +13,47 @@ Only the ``authUrl`` is mandatory to create the client. But you will have to pro credentials to each service you create. So it is recommended to provide them when creating the client which would propagate these options to each service. +Authenticate +------------ + There are different ways to provide the authentication credentials. See the :doc:`services/identity/v3/tokens` section for the full list of options. You should provide credentials to the ``OpenStack`` constructor as an array the same way you provide options to ``generateToken`` method of the ``Identity`` service. -Authenticate with username --------------------------- +By username +~~~~~~~~~~~ The most common way to authenticate is using the username and password of the user. You should also provide the Domain ID as usernames will not be unique across an entire OpenStack installation .. sample:: Setup/username.php -Authenticate with user ID -------------------------- +By user ID +~~~~~~~~~~ .. sample:: Setup/user_id.php -Authenticate application credential ID --------------------------------------- +By application credential ID +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .. sample:: Setup/application_credential_id.php -Authenticate using token ID ---------------------------- +By token ID +~~~~~~~~~~~ If you already have a valid token, you can use it to authenticate. .. sample:: Setup/token_id.php + +Other options +------------- + +For production environments it is recommended to decrease error reporting not to expose sensitive information. It can be done +by setting the ``errorVerbosity`` key to ``0`` in the options array. It is set to 2 by default. + +.. code-block:: php + + $openstack = new OpenStack\OpenStack([ + 'errorVerbosity' => 0, + // other options + ]); \ No newline at end of file diff --git a/src/Common/Auth/IdentityService.php b/src/Common/Auth/IdentityService.php index 949b11035..c9f86849a 100644 --- a/src/Common/Auth/IdentityService.php +++ b/src/Common/Auth/IdentityService.php @@ -9,7 +9,7 @@ interface IdentityService /** * Authenticates and retrieves back a token and catalog. * - * @return array The FIRST key is {@see Token} instance, the SECOND key is a {@see Catalog} instance + * @return array{0: \OpenStack\Common\Auth\Token, 1: string} The FIRST key is {@see Token} instance, the SECOND key is a URL of the service */ public function authenticate(array $options): array; } diff --git a/src/Common/Error/Builder.php b/src/Common/Error/Builder.php index 796415a29..3e1996cf3 100644 --- a/src/Common/Error/Builder.php +++ b/src/Common/Error/Builder.php @@ -54,7 +54,7 @@ private function header(string $name): string */ private function linkIsValid(string $link): bool { - $link = $this->docDomain.$link; + $link = $this->docDomain . $link; try { return $this->client->request('HEAD', $link)->getStatusCode() < 400; @@ -66,39 +66,50 @@ private function linkIsValid(string $link): bool /** * @codeCoverageIgnore */ - public function str(MessageInterface $message): string + public function str(MessageInterface $message, int $verbosity = 0): string { if ($message instanceof RequestInterface) { - $msg = trim($message->getMethod().' ' - .$message->getRequestTarget()) - .' HTTP/'.$message->getProtocolVersion(); + $msg = trim($message->getMethod() . ' ' . $message->getRequestTarget()); + $msg .= ' HTTP/' . $message->getProtocolVersion(); if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: ".$message->getUri()->getHost(); + $msg .= "\r\nHost: " . $message->getUri()->getHost(); } - } elseif ($message instanceof ResponseInterface) { - $msg = 'HTTP/'.$message->getProtocolVersion().' ' - .$message->getStatusCode().' ' - .$message->getReasonPhrase(); + } else { + if ($message instanceof ResponseInterface) { + $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' + . $message->getStatusCode() . ' ' + . $message->getReasonPhrase(); + } else { + throw new \InvalidArgumentException('Unknown message type'); + } + } + + if ($verbosity < 1) { + return $msg; } foreach ($message->getHeaders() as $name => $values) { - $msg .= "\r\n{$name}: ".implode(', ', $values); + $msg .= "\r\n{$name}: " . implode(', ', $values); + } + + if ($verbosity < 2) { + return $msg; } if (ini_get('memory_limit') < 0 || $message->getBody()->getSize() < ini_get('memory_limit')) { - $msg .= "\r\n\r\n".$message->getBody(); + $msg .= "\r\n\r\n" . $message->getBody(); } - return $msg; + return trim($msg); } /** * Helper method responsible for constructing and returning {@see BadResponseError} exceptions. * - * @param RequestInterface $request The faulty request + * @param RequestInterface $request The faulty request * @param ResponseInterface $response The error-filled response */ - public function httpError(RequestInterface $request, ResponseInterface $response): BadResponseError + public function httpError(RequestInterface $request, ResponseInterface $response, int $verbosity = 0): BadResponseError { $message = $this->header('HTTP Error'); @@ -109,16 +120,16 @@ public function httpError(RequestInterface $request, ResponseInterface $response ); $message .= $this->header('Request'); - $message .= trim($this->str($request)).PHP_EOL.PHP_EOL; + $message .= $this->str($request, $verbosity) . PHP_EOL . PHP_EOL; $message .= $this->header('Response'); - $message .= trim($this->str($response)).PHP_EOL.PHP_EOL; + $message .= $this->str($response, $verbosity) . PHP_EOL . PHP_EOL; $message .= $this->header('Further information'); $message .= $this->getStatusCodeMessage($response->getStatusCode()); $message .= 'Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging ' - .'HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.'; + . 'HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.'; $e = new BadResponseError($message); $e->setRequest($request); @@ -142,9 +153,9 @@ private function getStatusCodeMessage(int $statusCode): string /** * Helper method responsible for constructing and returning {@see UserInputError} exceptions. * - * @param string $expectedType The type that was expected from the user - * @param mixed $userValue The incorrect value the user actually provided - * @param string|null $furtherLink a link to further information if necessary (optional) + * @param string $expectedType The type that was expected from the user + * @param mixed $userValue The incorrect value the user actually provided + * @param string|null $furtherLink a link to further information if necessary (optional) */ public function userInputError(string $expectedType, $userValue, string $furtherLink = null): UserInputError { @@ -159,7 +170,7 @@ public function userInputError(string $expectedType, $userValue, string $further $message .= 'Please ensure that the value adheres to the expectation above. '; if ($furtherLink && $this->linkIsValid($furtherLink)) { - $message .= sprintf('Visit %s for more information about input arguments. ', $this->docDomain.$furtherLink); + $message .= sprintf('Visit %s for more information about input arguments. ', $this->docDomain . $furtherLink); } $message .= 'If you run into trouble, please open a support issue on https://github.com/php-opencloud/openstack/issues.'; diff --git a/src/Common/Service/Builder.php b/src/Common/Service/Builder.php index e9cb25598..f8c162a56 100644 --- a/src/Common/Service/Builder.php +++ b/src/Common/Service/Builder.php @@ -37,7 +37,7 @@ class Builder private $defaults = ['urlType' => 'publicURL']; /** - * @param array $globalOptions options that will be applied to every service created by this builder. + * @param array $globalOptions options that will be applied to every service created by this builder. * Eventually they will be merged (and if necessary overridden) by the * service-specific options passed in * @param string $rootNamespace API classes' root namespace @@ -50,8 +50,8 @@ public function __construct(array $globalOptions = [], $rootNamespace = 'OpenSta private function getClasses($namespace) { - $namespace = $this->rootNamespace.'\\'.$namespace; - $classes = [$namespace.'\\Api', $namespace.'\\Service']; + $namespace = $this->rootNamespace . '\\' . $namespace; + $classes = [$namespace . '\\Api', $namespace . '\\Service']; foreach ($classes as $class) { if (!class_exists($class)) { @@ -68,8 +68,8 @@ private function getClasses($namespace) * directly - this setup includes the configuration of the HTTP client's base URL, and the * attachment of an authentication handler. * - * @param string $namespace The namespace of the service - * @param array $serviceOptions The service-specific options to use + * @param string $namespace The namespace of the service + * @param array $serviceOptions The service-specific options to use */ public function createService(string $namespace, array $serviceOptions = []): ServiceInterface { @@ -88,33 +88,18 @@ private function stockHttpClient(array &$options, string $serviceName): void if (!isset($options['httpClient']) || !($options['httpClient'] instanceof ClientInterface)) { if (false !== stripos($serviceName, 'identity')) { $baseUrl = $options['authUrl']; - $stack = $this->getStack($options['authHandler']); + $token = null; } else { - [$token, $baseUrl] = $options['identityService']->authenticate($options); - $stack = $this->getStack($options['authHandler'], $token); + [$token, $baseUrl] = $options['identityService']->authenticate($options); } + $stack = HandlerStackFactory::createWithOptions(array_merge($options, ['token' => $token])); $microVersion = $options['microVersion'] ?? null; - $this->addDebugMiddleware($options, $stack); - $options['httpClient'] = $this->httpClient($baseUrl, $stack, $options['catalogType'], $microVersion); } } - /** - * @codeCoverageIgnore - */ - private function addDebugMiddleware(array $options, HandlerStack &$stack): void - { - if (!empty($options['debugLog']) - && !empty($options['logger']) - && !empty($options['messageFormatter']) - ) { - $stack->push(GuzzleMiddleware::log($options['logger'], $options['messageFormatter'])); - } - } - /** * @codeCoverageIgnore */ @@ -127,14 +112,6 @@ private function stockAuthHandler(array &$options): void } } - private function getStack(callable $authHandler, Token $token = null): HandlerStack - { - $stack = HandlerStackFactory::create(); - $stack->push(Middleware::authHandler($authHandler, $token)); - - return $stack; - } - private function httpClient(string $baseUrl, HandlerStack $stack, string $serviceType = null, string $microVersion = null): ClientInterface { $clientOptions = [ diff --git a/src/Common/Transport/HandlerStack.php b/src/Common/Transport/HandlerStack.php index da28157bc..fd500be50 100644 --- a/src/Common/Transport/HandlerStack.php +++ b/src/Common/Transport/HandlerStack.php @@ -7,6 +7,9 @@ */ class HandlerStack { + /** + * @deprecated use \OpenStack\Common\Transport\HandlerStackFactory::createWithOptions instead + */ public static function create(callable $handler = null): \GuzzleHttp\HandlerStack { return HandlerStackFactory::create($handler); diff --git a/src/Common/Transport/HandlerStackFactory.php b/src/Common/Transport/HandlerStackFactory.php index a0579a32d..99cd2aa9a 100644 --- a/src/Common/Transport/HandlerStackFactory.php +++ b/src/Common/Transport/HandlerStackFactory.php @@ -5,10 +5,14 @@ namespace OpenStack\Common\Transport; use GuzzleHttp\HandlerStack; +use GuzzleHttp\Middleware as GuzzleMiddleware; use GuzzleHttp\Utils; class HandlerStackFactory { + /** + * @deprecated use \OpenStack\Common\Transport\HandlerStackFactory::createWithOptions instead + */ public static function create(callable $handler = null): HandlerStack { $stack = new HandlerStack($handler ?: Utils::chooseHandler()); @@ -17,4 +21,38 @@ public static function create(callable $handler = null): HandlerStack return $stack; } + + /** + * Creates a new HandlerStack with the given options + * + * @param array{ + * handler: callable, + * authHandler: callable, + * token: \OpenStack\Common\Auth\Token, + * errorVerbosity: int, + * debugLog: bool, + * logger: \Psr\Log\LoggerInterface, + * messageFormatter: \GuzzleHttp\MessageFormatter + * } $options + */ + public static function createWithOptions(array $options): HandlerStack + { + $stack = new HandlerStack($options['handler'] ?? Utils::chooseHandler()); + $stack->push(Middleware::httpErrors($options['errorVerbosity'] ?? 0), 'http_errors'); + $stack->push(GuzzleMiddleware::prepareBody(), 'prepare_body'); + + if (!empty($options['authHandler'])){ + $stack->push(Middleware::authHandler($options['authHandler'], $options['token'] ?? null)); + } + + if (!empty($options['debugLog']) + && !empty($options['logger']) + && !empty($options['messageFormatter']) + ) { + $logMiddleware = GuzzleMiddleware::log($options['logger'], $options['messageFormatter']); + $stack->push($logMiddleware, 'logger'); + } + + return $stack; + } } diff --git a/src/Common/Transport/Middleware.php b/src/Common/Transport/Middleware.php index 86f701ed9..d11667ef4 100644 --- a/src/Common/Transport/Middleware.php +++ b/src/Common/Transport/Middleware.php @@ -15,16 +15,16 @@ final class Middleware { - public static function httpErrors(): callable + public static function httpErrors(int $verbosity = 0): callable { - return function (callable $handler) { - return function ($request, array $options) use ($handler) { + return function (callable $handler) use ($verbosity) { + return function ($request, array $options) use ($handler, $verbosity) { return $handler($request, $options)->then( - function (ResponseInterface $response) use ($request) { + function (ResponseInterface $response) use ($request, $verbosity) { if ($response->getStatusCode() < 400) { return $response; } - throw (new Builder())->httpError($request, $response); + throw (new Builder())->httpError($request, $response, $verbosity); } ); }; diff --git a/src/Identity/v3/Service.php b/src/Identity/v3/Service.php index 1f67f28bc..5760436fe 100644 --- a/src/Identity/v3/Service.php +++ b/src/Identity/v3/Service.php @@ -45,7 +45,7 @@ public function authenticate(array $options): array $name = $options['catalogName']; $type = $options['catalogType']; $region = $options['region']; - $interface = isset($options['interface']) ? $options['interface'] : Enum::INTERFACE_PUBLIC; + $interface = $options['interface'] ?? Enum::INTERFACE_PUBLIC; if ($baseUrl = $token->catalog->getServiceUrl($name, $type, $region, $interface)) { return [$token, $baseUrl]; diff --git a/src/OpenStack.php b/src/OpenStack.php index 05ba65acb..c92dda0c1 100644 --- a/src/OpenStack.php +++ b/src/OpenStack.php @@ -36,6 +36,9 @@ class OpenStack */ public function __construct(array $options = [], Builder $builder = null) { + $defaults = ['errorVerbosity' => 2]; + $options = array_merge($defaults, $options); + if (!isset($options['identityService'])) { $options['identityService'] = $this->getDefaultIdentityService($options); } @@ -49,15 +52,7 @@ private function getDefaultIdentityService(array $options): Service throw new \InvalidArgumentException("'authUrl' is a required option"); } - $stack = HandlerStackFactory::create(); - - if (!empty($options['debugLog']) - && !empty($options['logger']) - && !empty($options['messageFormatter']) - ) { - $logMiddleware = GuzzleMiddleware::log($options['logger'], $options['messageFormatter']); - $stack->push($logMiddleware, 'logger'); - } + $stack = HandlerStackFactory::createWithOptions(array_merge($options, ['token' => null])); $clientOptions = [ 'base_uri' => Utils::normalizeUrl($options['authUrl']), diff --git a/tests/sample/Identity/v3/TokenTest.php b/tests/sample/Identity/v3/TokenTest.php index 85e8ce8c3..353981128 100644 --- a/tests/sample/Identity/v3/TokenTest.php +++ b/tests/sample/Identity/v3/TokenTest.php @@ -2,7 +2,10 @@ namespace OpenStack\Sample\Identity\v3; +use GuzzleHttp\Exception\ClientException; +use OpenStack\Common\Error\BadResponseError; use OpenStack\Identity\v3\Models\Token; +use OpenStack\OpenStack; class TokenTest extends TestCase { @@ -73,4 +76,35 @@ public function testRevoke(): void $this->assertFalse($token->validate()); } + public function testInvalidPassword() + { + $options = $this->getAuthOpts(); + $password = $options['user']['password'] . $this->randomStr(); + $options['user']['password'] .= $password; + + $openstack = new OpenStack($options); + $this->expectException(BadResponseError::class); + + $openstack->objectStoreV1(); + } + + public function testInvalidPasswordHidesPassword() + { + $options = $this->getAuthOpts(); + $password = $options['user']['password'] . $this->randomStr(); + $options['user']['password'] .= $password; + + $openstack = new OpenStack(array_merge($options, ['errorVerbosity' => 0])); + $this->expectException(BadResponseError::class); + + try { + $openstack->objectStoreV1(); + } catch (BadResponseError $e) { + $this->assertStringNotContainsString($password, $e->getMessage()); + print_r($e->getMessage()); + + throw $e; + } + + } } \ No newline at end of file diff --git a/tests/unit/Common/Error/BuilderTest.php b/tests/unit/Common/Error/BuilderTest.php index 7d44eb829..51ce95fb6 100644 --- a/tests/unit/Common/Error/BuilderTest.php +++ b/tests/unit/Common/Error/BuilderTest.php @@ -27,13 +27,16 @@ public function test_it_injects_client() self::assertInstanceOf(Builder::class, new Builder($this->client->reveal())); } - public function test_it_builds_http_errors() + /** + * @dataProvider verbosityProvider + */ + public function test_it_builds_http_errors(int $verbosity) { $request = new Request('POST', '/servers'); $response = new Response(400, [], Utils::streamFor('Invalid parameters')); - $requestStr = trim($this->builder->str($request)); - $responseStr = trim($this->builder->str($response)); + $requestStr = $this->builder->str($request, $verbosity); + $responseStr = $this->builder->str($response, $verbosity); $errorMessage = <<setRequest($request); $e->setResponse($response); - self::assertEquals($e, $this->builder->httpError($request, $response)); + self::assertEquals($e, $this->builder->httpError($request, $response, $verbosity)); + } + + /** + * Provides different verbosity levels. + */ + public function verbosityProvider(): array + { + return [ + [0], + [1], + [2], + ]; } public function test_it_builds_user_input_errors() diff --git a/tests/unit/Identity/v3/ServiceTest.php b/tests/unit/Identity/v3/ServiceTest.php index 0719838f7..bf82c4607 100644 --- a/tests/unit/Identity/v3/ServiceTest.php +++ b/tests/unit/Identity/v3/ServiceTest.php @@ -10,7 +10,6 @@ use OpenStack\Identity\v3\Service; use OpenStack\Test\TestCase; use Prophecy\Argument; -use Psr\Http\Message\ResponseInterface; class ServiceTest extends TestCase { From 4c3f4d6f1f7b5e975e020af1324a0b1f3d2b5bfe Mon Sep 17 00:00:00 2001 From: k0ka Date: Mon, 5 Feb 2024 07:58:31 +0000 Subject: [PATCH 2/4] Apply php-cs-fixer changes --- src/Common/Error/Builder.php | 34 ++++++++++---------- src/Common/Service/Builder.php | 17 ++++------ src/Common/Transport/HandlerStackFactory.php | 6 ++-- src/OpenStack.php | 3 +- 4 files changed, 28 insertions(+), 32 deletions(-) diff --git a/src/Common/Error/Builder.php b/src/Common/Error/Builder.php index 3e1996cf3..7de837109 100644 --- a/src/Common/Error/Builder.php +++ b/src/Common/Error/Builder.php @@ -54,7 +54,7 @@ private function header(string $name): string */ private function linkIsValid(string $link): bool { - $link = $this->docDomain . $link; + $link = $this->docDomain.$link; try { return $this->client->request('HEAD', $link)->getStatusCode() < 400; @@ -69,16 +69,16 @@ private function linkIsValid(string $link): bool public function str(MessageInterface $message, int $verbosity = 0): string { if ($message instanceof RequestInterface) { - $msg = trim($message->getMethod() . ' ' . $message->getRequestTarget()); - $msg .= ' HTTP/' . $message->getProtocolVersion(); + $msg = trim($message->getMethod().' '.$message->getRequestTarget()); + $msg .= ' HTTP/'.$message->getProtocolVersion(); if (!$message->hasHeader('host')) { - $msg .= "\r\nHost: " . $message->getUri()->getHost(); + $msg .= "\r\nHost: ".$message->getUri()->getHost(); } } else { if ($message instanceof ResponseInterface) { - $msg = 'HTTP/' . $message->getProtocolVersion() . ' ' - . $message->getStatusCode() . ' ' - . $message->getReasonPhrase(); + $msg = 'HTTP/'.$message->getProtocolVersion().' ' + .$message->getStatusCode().' ' + .$message->getReasonPhrase(); } else { throw new \InvalidArgumentException('Unknown message type'); } @@ -89,7 +89,7 @@ public function str(MessageInterface $message, int $verbosity = 0): string } foreach ($message->getHeaders() as $name => $values) { - $msg .= "\r\n{$name}: " . implode(', ', $values); + $msg .= "\r\n{$name}: ".implode(', ', $values); } if ($verbosity < 2) { @@ -97,7 +97,7 @@ public function str(MessageInterface $message, int $verbosity = 0): string } if (ini_get('memory_limit') < 0 || $message->getBody()->getSize() < ini_get('memory_limit')) { - $msg .= "\r\n\r\n" . $message->getBody(); + $msg .= "\r\n\r\n".$message->getBody(); } return trim($msg); @@ -106,7 +106,7 @@ public function str(MessageInterface $message, int $verbosity = 0): string /** * Helper method responsible for constructing and returning {@see BadResponseError} exceptions. * - * @param RequestInterface $request The faulty request + * @param RequestInterface $request The faulty request * @param ResponseInterface $response The error-filled response */ public function httpError(RequestInterface $request, ResponseInterface $response, int $verbosity = 0): BadResponseError @@ -120,16 +120,16 @@ public function httpError(RequestInterface $request, ResponseInterface $response ); $message .= $this->header('Request'); - $message .= $this->str($request, $verbosity) . PHP_EOL . PHP_EOL; + $message .= $this->str($request, $verbosity).PHP_EOL.PHP_EOL; $message .= $this->header('Response'); - $message .= $this->str($response, $verbosity) . PHP_EOL . PHP_EOL; + $message .= $this->str($response, $verbosity).PHP_EOL.PHP_EOL; $message .= $this->header('Further information'); $message .= $this->getStatusCodeMessage($response->getStatusCode()); $message .= 'Visit http://docs.php-opencloud.com/en/latest/http-codes for more information about debugging ' - . 'HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.'; + .'HTTP status codes, or file a support issue on https://github.com/php-opencloud/openstack/issues.'; $e = new BadResponseError($message); $e->setRequest($request); @@ -153,9 +153,9 @@ private function getStatusCodeMessage(int $statusCode): string /** * Helper method responsible for constructing and returning {@see UserInputError} exceptions. * - * @param string $expectedType The type that was expected from the user - * @param mixed $userValue The incorrect value the user actually provided - * @param string|null $furtherLink a link to further information if necessary (optional) + * @param string $expectedType The type that was expected from the user + * @param mixed $userValue The incorrect value the user actually provided + * @param string|null $furtherLink a link to further information if necessary (optional) */ public function userInputError(string $expectedType, $userValue, string $furtherLink = null): UserInputError { @@ -170,7 +170,7 @@ public function userInputError(string $expectedType, $userValue, string $further $message .= 'Please ensure that the value adheres to the expectation above. '; if ($furtherLink && $this->linkIsValid($furtherLink)) { - $message .= sprintf('Visit %s for more information about input arguments. ', $this->docDomain . $furtherLink); + $message .= sprintf('Visit %s for more information about input arguments. ', $this->docDomain.$furtherLink); } $message .= 'If you run into trouble, please open a support issue on https://github.com/php-opencloud/openstack/issues.'; diff --git a/src/Common/Service/Builder.php b/src/Common/Service/Builder.php index f8c162a56..f63eefc18 100644 --- a/src/Common/Service/Builder.php +++ b/src/Common/Service/Builder.php @@ -7,11 +7,8 @@ use GuzzleHttp\Client; use GuzzleHttp\ClientInterface; use GuzzleHttp\HandlerStack; -use GuzzleHttp\Middleware as GuzzleMiddleware; use OpenStack\Common\Auth\IdentityService; -use OpenStack\Common\Auth\Token; use OpenStack\Common\Transport\HandlerStackFactory; -use OpenStack\Common\Transport\Middleware; use OpenStack\Common\Transport\Utils; /** @@ -37,7 +34,7 @@ class Builder private $defaults = ['urlType' => 'publicURL']; /** - * @param array $globalOptions options that will be applied to every service created by this builder. + * @param array $globalOptions options that will be applied to every service created by this builder. * Eventually they will be merged (and if necessary overridden) by the * service-specific options passed in * @param string $rootNamespace API classes' root namespace @@ -50,8 +47,8 @@ public function __construct(array $globalOptions = [], $rootNamespace = 'OpenSta private function getClasses($namespace) { - $namespace = $this->rootNamespace . '\\' . $namespace; - $classes = [$namespace . '\\Api', $namespace . '\\Service']; + $namespace = $this->rootNamespace.'\\'.$namespace; + $classes = [$namespace.'\\Api', $namespace.'\\Service']; foreach ($classes as $class) { if (!class_exists($class)) { @@ -68,8 +65,8 @@ private function getClasses($namespace) * directly - this setup includes the configuration of the HTTP client's base URL, and the * attachment of an authentication handler. * - * @param string $namespace The namespace of the service - * @param array $serviceOptions The service-specific options to use + * @param string $namespace The namespace of the service + * @param array $serviceOptions The service-specific options to use */ public function createService(string $namespace, array $serviceOptions = []): ServiceInterface { @@ -88,12 +85,12 @@ private function stockHttpClient(array &$options, string $serviceName): void if (!isset($options['httpClient']) || !($options['httpClient'] instanceof ClientInterface)) { if (false !== stripos($serviceName, 'identity')) { $baseUrl = $options['authUrl']; - $token = null; + $token = null; } else { [$token, $baseUrl] = $options['identityService']->authenticate($options); } - $stack = HandlerStackFactory::createWithOptions(array_merge($options, ['token' => $token])); + $stack = HandlerStackFactory::createWithOptions(array_merge($options, ['token' => $token])); $microVersion = $options['microVersion'] ?? null; $options['httpClient'] = $this->httpClient($baseUrl, $stack, $options['catalogType'], $microVersion); diff --git a/src/Common/Transport/HandlerStackFactory.php b/src/Common/Transport/HandlerStackFactory.php index 99cd2aa9a..a2324d581 100644 --- a/src/Common/Transport/HandlerStackFactory.php +++ b/src/Common/Transport/HandlerStackFactory.php @@ -23,7 +23,7 @@ public static function create(callable $handler = null): HandlerStack } /** - * Creates a new HandlerStack with the given options + * Creates a new HandlerStack with the given options. * * @param array{ * handler: callable, @@ -37,11 +37,11 @@ public static function create(callable $handler = null): HandlerStack */ public static function createWithOptions(array $options): HandlerStack { - $stack = new HandlerStack($options['handler'] ?? Utils::chooseHandler()); + $stack = new HandlerStack($options['handler'] ?? Utils::chooseHandler()); $stack->push(Middleware::httpErrors($options['errorVerbosity'] ?? 0), 'http_errors'); $stack->push(GuzzleMiddleware::prepareBody(), 'prepare_body'); - if (!empty($options['authHandler'])){ + if (!empty($options['authHandler'])) { $stack->push(Middleware::authHandler($options['authHandler'], $options['token'] ?? null)); } diff --git a/src/OpenStack.php b/src/OpenStack.php index c92dda0c1..4eecd642a 100644 --- a/src/OpenStack.php +++ b/src/OpenStack.php @@ -5,7 +5,6 @@ namespace OpenStack; use GuzzleHttp\Client; -use GuzzleHttp\Middleware as GuzzleMiddleware; use OpenStack\Common\Service\Builder; use OpenStack\Common\Transport\HandlerStackFactory; use OpenStack\Common\Transport\Utils; @@ -37,7 +36,7 @@ class OpenStack public function __construct(array $options = [], Builder $builder = null) { $defaults = ['errorVerbosity' => 2]; - $options = array_merge($defaults, $options); + $options = array_merge($defaults, $options); if (!isset($options['identityService'])) { $options['identityService'] = $this->getDefaultIdentityService($options); From 46f99c4cd4e2bde6f6c692c6c2678d9ecf1aeeb6 Mon Sep 17 00:00:00 2001 From: Konstantin Babushkin Date: Mon, 5 Feb 2024 09:42:59 +0100 Subject: [PATCH 3/4] fix tests --- tests/sample/Identity/v3/TokenTest.php | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/sample/Identity/v3/TokenTest.php b/tests/sample/Identity/v3/TokenTest.php index 353981128..692dc5422 100644 --- a/tests/sample/Identity/v3/TokenTest.php +++ b/tests/sample/Identity/v3/TokenTest.php @@ -80,7 +80,8 @@ public function testInvalidPassword() { $options = $this->getAuthOpts(); $password = $options['user']['password'] . $this->randomStr(); - $options['user']['password'] .= $password; + $options['user']['id'] = $password; + $options['user']['password'] = $password; $openstack = new OpenStack($options); $this->expectException(BadResponseError::class); @@ -91,8 +92,10 @@ public function testInvalidPassword() public function testInvalidPasswordHidesPassword() { $options = $this->getAuthOpts(); + $password = $options['user']['password'] . $this->randomStr(); - $options['user']['password'] .= $password; + $options['user']['id'] = $password; + $options['user']['password'] = $password; $openstack = new OpenStack(array_merge($options, ['errorVerbosity' => 0])); $this->expectException(BadResponseError::class); @@ -101,7 +104,6 @@ public function testInvalidPasswordHidesPassword() $openstack->objectStoreV1(); } catch (BadResponseError $e) { $this->assertStringNotContainsString($password, $e->getMessage()); - print_r($e->getMessage()); throw $e; } From fec562f563417a92ee99562b01a77b0eb71adcc8 Mon Sep 17 00:00:00 2001 From: Konstantin Babushkin Date: Mon, 5 Feb 2024 10:07:27 +0100 Subject: [PATCH 4/4] increase create server timeout --- tests/sample/Compute/v2/TestCase.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/sample/Compute/v2/TestCase.php b/tests/sample/Compute/v2/TestCase.php index ee57ecaa9..8f186918d 100644 --- a/tests/sample/Compute/v2/TestCase.php +++ b/tests/sample/Compute/v2/TestCase.php @@ -68,7 +68,7 @@ protected function createServer(): Server ] ); - $server->waitUntilActive(120); + $server->waitUntilActive(300); $this->assertEquals('ACTIVE', $server->status); return $server;