Loading acquia_connector.install +20 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ use Drupal\acquia_connector\Controller\TestStatusController; use Drupal\acquia_connector\Helper\Storage; use Drupal\acquia_connector\Subscription; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Url; /** Loading @@ -34,6 +35,25 @@ function acquia_connector_requirements($phase) { $state_site_name = \Drupal::state()->get('spi.site_name'); $state_site_machine_name = \Drupal::state()->get('spi.site_machine_name'); // After Tue Nov 15 2022. $time = \Drupal::time(); $eol_warning_date = new DrupalDateTime('Tue Nov 15 2022'); $current_date = DrupalDateTime::createFromTimestamp($time->getRequestTime()); if ($current_date >= $eol_warning_date) { $requirements['acquia_3_x_eol'] = [ 'title' => t('Acquia 3.x EOL'), 'value' => t('Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.'), 'description' => t('Please upgrade to 4.x before March 1st 2023, after that the 3.x version of the module will no longer work.'), 'severity' => REQUIREMENT_WARNING, ]; // After Wed Mar 01 2023. $eol_date = new DrupalDateTime('Wed Mar 01 2023'); if ($current_date >= $eol_date) { $requirements['acquia_3_x_eol']['severity'] = REQUIREMENT_ERROR; } } // Inform users on subscription status. Either we know they are active, // or we know they have credentials but not active (not set up yet) or // we have credentials but an inactive subscription (either bad Loading acquia_connector.post_update.php +7 −0 Original line number Diff line number Diff line Loading @@ -57,3 +57,10 @@ function acquia_connector_post_update_disable_connector_cron() { } $config->save(); } /** * Ensure service container rebuilt after changing client constructor. */ function acquia_connector_post_update_client_arguments_changed() { // Empty post-update hook. } acquia_connector.services.yml +1 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ services: - {name: event_subscriber} acquia_connector.client: class: Drupal\acquia_connector\Client arguments: ['@config.factory', '@state'] arguments: ['@config.factory', '@state', '@datetime.time'] acquia_connector.spi: class: Drupal\acquia_connector\Controller\SpiController arguments: ['@acquia_connector.client', '@config.factory', '@path_alias.manager'] src/Client.php +25 −2 Original line number Diff line number Diff line Loading @@ -3,9 +3,11 @@ namespace Drupal\acquia_connector; use Drupal\acquia_connector\Helper\Storage; use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Crypt; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Logger\LoggerChannelTrait; use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\State\StateInterface; Loading Loading @@ -65,6 +67,13 @@ class Client { */ protected $state; /** * The time. * * @var \Drupal\Component\Datetime\TimeInterface */ protected $time; /** * Client constructor. * Loading @@ -72,12 +81,15 @@ class Client { * Config Factory Interface. * @param \Drupal\Core\State\StateInterface $state * The state service. * @param \Drupal\Component\Datetime\TimeInterface $time * The time. */ public function __construct(ConfigFactoryInterface $configFactory, StateInterface $state) { public function __construct(ConfigFactoryInterface $configFactory, StateInterface $state, TimeInterface $time) { $this->configFactory = $configFactory; $this->config = $configFactory->get('acquia_connector.settings'); $this->server = $this->config->get('spi.server'); $this->state = $state; $this->time = $time; $this->headers = [ 'Content-Type' => 'application/json', Loading Loading @@ -427,6 +439,16 @@ class Client { * @throws ConnectorException */ public function nspiCall($method, array $params, $key = NULL) { // This has reached EOL after Wed Mar 01 2023. $eol_date = new DrupalDateTime('Wed Mar 01 2023'); $current_date = DrupalDateTime::createFromTimestamp($this->time->getRequestTime()); if ($current_date >= $eol_date) { throw new ConnectorException( 'Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.', 500 ); } if (empty($key)) { $storage = new Storage(); $key = $storage->getKey(); Loading @@ -437,12 +459,13 @@ class Client { $host = \Drupal::request()->server->get('HTTP_HOST', ''); $ssl = \Drupal::request()->isSecure(); $data = [ 'authenticator' => $this->buildAuthenticator($key, \Drupal::time()->getRequestTime(), $params), 'authenticator' => $this->buildAuthenticator($key, $this->time->getRequestTime(), $params), 'ip' => $ip, 'host' => $host, 'ssl' => $ssl, 'body' => $params, ]; $data['result'] = $this->request('POST', $method, $data); return $data; } Loading tests/src/Unit/EndOfLifeTest.php 0 → 100644 +151 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Tests\acquia_connector\Unit; use Drupal\acquia_connector\Client; use Drupal\acquia_connector\ConnectorException; use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Serialization\Json; use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Http\ClientFactory; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Utility\UnroutedUrlAssemblerInterface; use Drupal\Tests\UnitTestCase; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; /** * @group acquia_connector */ final class EndOfLifeTest extends UnitTestCase { /** * Tests severity in status report. */ public function testRequirements(): void { $container = new ContainerBuilder(); $config_factory = $this->createMock(ConfigFactoryInterface::class); $time = $this->createMock(TimeInterface::class); $time ->method('getRequestTime') ->willReturn( strtotime('Oct 12 2022'), strtotime('Nov 15 2022'), strtotime('Mar 01 2023'), ); $state = $this->createMock(StateInterface::class); $state ->method('get') ->withConsecutive( ['acquia_connector.cron_last', 0], ) ->willReturnOnConsecutiveCalls(time()); $language_manager = $this->createMock(LanguageManagerInterface::class); $language_manager ->method('getCurrentLanguage') ->willReturn(new Language(['id' => 'en'])); $url_generator = $this->createMock(UrlGeneratorInterface::class); $unrouted_url_assembler = $this->createMock(UnroutedUrlAssemblerInterface::class); $module_handler = $this->createMock(ModuleHandlerInterface::class); $container->set('config.factory', $config_factory); $container->set('state', $state); $container->set('datetime.time', $time); $container->set('language_manager', $language_manager); $container->set('cache.default', new MemoryBackend()); $container->set('url_generator', $url_generator); $container->set('unrouted_url_assembler', $unrouted_url_assembler); $container->set('module_handler', $module_handler); \Drupal::setContainer($container); require_once $this->root . '/core/includes/install.inc'; require_once __DIR__ . '/../../../acquia_connector.module'; require_once __DIR__ . '/../../../acquia_connector.install'; $requirements = acquia_connector_requirements('runtime'); self::assertArrayNotHasKey('acquia_3_x_eol', $requirements); $requirements = acquia_connector_requirements('runtime'); self::assertArrayHasKey('acquia_3_x_eol', $requirements); self::assertEquals(REQUIREMENT_WARNING, $requirements['acquia_3_x_eol']['severity']); $requirements = acquia_connector_requirements('runtime'); self::assertArrayHasKey('acquia_3_x_eol', $requirements); self::assertEquals(REQUIREMENT_ERROR, $requirements['acquia_3_x_eol']['severity']); } /** * Tests Client::nspiCall shutoff. */ public function testClientNspiCall(): void { $client = new GuzzleClient([ 'handler' => HandlerStack::create(new MockHandler([ new Response(200, [], Json::encode(['result' => []])), new Response(200, [], Json::encode(['result' => []])), ])), ]); $http_client_factory = $this->createMock(ClientFactory::class); $http_client_factory ->method('fromOptions') ->willReturn($client); $state = $this->createMock(StateInterface::class); $language_manager = $this->createMock(LanguageManagerInterface::class); $language_manager ->method('getCurrentLanguage') ->willReturn(new Language(['id' => 'en'])); $request_stack = new RequestStack(); $request_stack->push(Request::create('/')); $container = new ContainerBuilder(); $container->set('http_client_factory', $http_client_factory); $container->set('language_manager', $language_manager); $container->set('state', $state); $container->set('request_stack', $request_stack); \Drupal::setContainer($container); require_once __DIR__ . '/../../../acquia_connector.module'; $config_factory = $this->createMock(ConfigFactoryInterface::class); $config_factory ->method('get') ->with('acquia_connector.settings') ->willReturn($this->createMock(Config::class)); $time = $this->createMock(TimeInterface::class); $time ->method('getRequestTime') ->willReturn( strtotime('Oct 12 2022'), strtotime('Oct 12 2022'), strtotime('Nov 15 2022'), strtotime('Nov 15 2022'), strtotime('Mar 01 2023'), ); $client = new Client( $config_factory, $state, $time ); $data = $client->nspiCall('/agent-api/subscription', [], 'ABC'); self::assertArrayHasKey('result', $data); self::assertNotFalse($data['result']); $data = $client->nspiCall('/agent-api/subscription', [], 'ABC'); self::assertArrayHasKey('result', $data); self::assertNotFalse($data['result']); $this->expectException(ConnectorException::class); $this->expectExceptionMessage('Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.'); $client->nspiCall('/agent-api/subscription', [], 'ABC'); } } Loading
acquia_connector.install +20 −0 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ use Drupal\acquia_connector\Controller\TestStatusController; use Drupal\acquia_connector\Helper\Storage; use Drupal\acquia_connector\Subscription; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Url; /** Loading @@ -34,6 +35,25 @@ function acquia_connector_requirements($phase) { $state_site_name = \Drupal::state()->get('spi.site_name'); $state_site_machine_name = \Drupal::state()->get('spi.site_machine_name'); // After Tue Nov 15 2022. $time = \Drupal::time(); $eol_warning_date = new DrupalDateTime('Tue Nov 15 2022'); $current_date = DrupalDateTime::createFromTimestamp($time->getRequestTime()); if ($current_date >= $eol_warning_date) { $requirements['acquia_3_x_eol'] = [ 'title' => t('Acquia 3.x EOL'), 'value' => t('Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.'), 'description' => t('Please upgrade to 4.x before March 1st 2023, after that the 3.x version of the module will no longer work.'), 'severity' => REQUIREMENT_WARNING, ]; // After Wed Mar 01 2023. $eol_date = new DrupalDateTime('Wed Mar 01 2023'); if ($current_date >= $eol_date) { $requirements['acquia_3_x_eol']['severity'] = REQUIREMENT_ERROR; } } // Inform users on subscription status. Either we know they are active, // or we know they have credentials but not active (not set up yet) or // we have credentials but an inactive subscription (either bad Loading
acquia_connector.post_update.php +7 −0 Original line number Diff line number Diff line Loading @@ -57,3 +57,10 @@ function acquia_connector_post_update_disable_connector_cron() { } $config->save(); } /** * Ensure service container rebuilt after changing client constructor. */ function acquia_connector_post_update_client_arguments_changed() { // Empty post-update hook. }
acquia_connector.services.yml +1 −1 Original line number Diff line number Diff line Loading @@ -11,7 +11,7 @@ services: - {name: event_subscriber} acquia_connector.client: class: Drupal\acquia_connector\Client arguments: ['@config.factory', '@state'] arguments: ['@config.factory', '@state', '@datetime.time'] acquia_connector.spi: class: Drupal\acquia_connector\Controller\SpiController arguments: ['@acquia_connector.client', '@config.factory', '@path_alias.manager']
src/Client.php +25 −2 Original line number Diff line number Diff line Loading @@ -3,9 +3,11 @@ namespace Drupal\acquia_connector; use Drupal\acquia_connector\Helper\Storage; use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Serialization\Json; use Drupal\Component\Utility\Crypt; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\Datetime\DrupalDateTime; use Drupal\Core\Logger\LoggerChannelTrait; use Drupal\Core\Messenger\MessengerTrait; use Drupal\Core\State\StateInterface; Loading Loading @@ -65,6 +67,13 @@ class Client { */ protected $state; /** * The time. * * @var \Drupal\Component\Datetime\TimeInterface */ protected $time; /** * Client constructor. * Loading @@ -72,12 +81,15 @@ class Client { * Config Factory Interface. * @param \Drupal\Core\State\StateInterface $state * The state service. * @param \Drupal\Component\Datetime\TimeInterface $time * The time. */ public function __construct(ConfigFactoryInterface $configFactory, StateInterface $state) { public function __construct(ConfigFactoryInterface $configFactory, StateInterface $state, TimeInterface $time) { $this->configFactory = $configFactory; $this->config = $configFactory->get('acquia_connector.settings'); $this->server = $this->config->get('spi.server'); $this->state = $state; $this->time = $time; $this->headers = [ 'Content-Type' => 'application/json', Loading Loading @@ -427,6 +439,16 @@ class Client { * @throws ConnectorException */ public function nspiCall($method, array $params, $key = NULL) { // This has reached EOL after Wed Mar 01 2023. $eol_date = new DrupalDateTime('Wed Mar 01 2023'); $current_date = DrupalDateTime::createFromTimestamp($this->time->getRequestTime()); if ($current_date >= $eol_date) { throw new ConnectorException( 'Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.', 500 ); } if (empty($key)) { $storage = new Storage(); $key = $storage->getKey(); Loading @@ -437,12 +459,13 @@ class Client { $host = \Drupal::request()->server->get('HTTP_HOST', ''); $ssl = \Drupal::request()->isSecure(); $data = [ 'authenticator' => $this->buildAuthenticator($key, \Drupal::time()->getRequestTime(), $params), 'authenticator' => $this->buildAuthenticator($key, $this->time->getRequestTime(), $params), 'ip' => $ip, 'host' => $host, 'ssl' => $ssl, 'body' => $params, ]; $data['result'] = $this->request('POST', $method, $data); return $data; } Loading
tests/src/Unit/EndOfLifeTest.php 0 → 100644 +151 −0 Original line number Diff line number Diff line <?php declare(strict_types=1); namespace Drupal\Tests\acquia_connector\Unit; use Drupal\acquia_connector\Client; use Drupal\acquia_connector\ConnectorException; use Drupal\Component\Datetime\TimeInterface; use Drupal\Component\Serialization\Json; use Drupal\Core\Cache\MemoryBackend; use Drupal\Core\Config\Config; use Drupal\Core\Config\ConfigFactoryInterface; use Drupal\Core\DependencyInjection\ContainerBuilder; use Drupal\Core\Extension\ModuleHandlerInterface; use Drupal\Core\Http\ClientFactory; use Drupal\Core\Language\Language; use Drupal\Core\Language\LanguageManagerInterface; use Drupal\Core\Routing\UrlGeneratorInterface; use Drupal\Core\State\StateInterface; use Drupal\Core\Utility\UnroutedUrlAssemblerInterface; use Drupal\Tests\UnitTestCase; use GuzzleHttp\Client as GuzzleClient; use GuzzleHttp\Handler\MockHandler; use GuzzleHttp\HandlerStack; use GuzzleHttp\Psr7\Response; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\RequestStack; /** * @group acquia_connector */ final class EndOfLifeTest extends UnitTestCase { /** * Tests severity in status report. */ public function testRequirements(): void { $container = new ContainerBuilder(); $config_factory = $this->createMock(ConfigFactoryInterface::class); $time = $this->createMock(TimeInterface::class); $time ->method('getRequestTime') ->willReturn( strtotime('Oct 12 2022'), strtotime('Nov 15 2022'), strtotime('Mar 01 2023'), ); $state = $this->createMock(StateInterface::class); $state ->method('get') ->withConsecutive( ['acquia_connector.cron_last', 0], ) ->willReturnOnConsecutiveCalls(time()); $language_manager = $this->createMock(LanguageManagerInterface::class); $language_manager ->method('getCurrentLanguage') ->willReturn(new Language(['id' => 'en'])); $url_generator = $this->createMock(UrlGeneratorInterface::class); $unrouted_url_assembler = $this->createMock(UnroutedUrlAssemblerInterface::class); $module_handler = $this->createMock(ModuleHandlerInterface::class); $container->set('config.factory', $config_factory); $container->set('state', $state); $container->set('datetime.time', $time); $container->set('language_manager', $language_manager); $container->set('cache.default', new MemoryBackend()); $container->set('url_generator', $url_generator); $container->set('unrouted_url_assembler', $unrouted_url_assembler); $container->set('module_handler', $module_handler); \Drupal::setContainer($container); require_once $this->root . '/core/includes/install.inc'; require_once __DIR__ . '/../../../acquia_connector.module'; require_once __DIR__ . '/../../../acquia_connector.install'; $requirements = acquia_connector_requirements('runtime'); self::assertArrayNotHasKey('acquia_3_x_eol', $requirements); $requirements = acquia_connector_requirements('runtime'); self::assertArrayHasKey('acquia_3_x_eol', $requirements); self::assertEquals(REQUIREMENT_WARNING, $requirements['acquia_3_x_eol']['severity']); $requirements = acquia_connector_requirements('runtime'); self::assertArrayHasKey('acquia_3_x_eol', $requirements); self::assertEquals(REQUIREMENT_ERROR, $requirements['acquia_3_x_eol']['severity']); } /** * Tests Client::nspiCall shutoff. */ public function testClientNspiCall(): void { $client = new GuzzleClient([ 'handler' => HandlerStack::create(new MockHandler([ new Response(200, [], Json::encode(['result' => []])), new Response(200, [], Json::encode(['result' => []])), ])), ]); $http_client_factory = $this->createMock(ClientFactory::class); $http_client_factory ->method('fromOptions') ->willReturn($client); $state = $this->createMock(StateInterface::class); $language_manager = $this->createMock(LanguageManagerInterface::class); $language_manager ->method('getCurrentLanguage') ->willReturn(new Language(['id' => 'en'])); $request_stack = new RequestStack(); $request_stack->push(Request::create('/')); $container = new ContainerBuilder(); $container->set('http_client_factory', $http_client_factory); $container->set('language_manager', $language_manager); $container->set('state', $state); $container->set('request_stack', $request_stack); \Drupal::setContainer($container); require_once __DIR__ . '/../../../acquia_connector.module'; $config_factory = $this->createMock(ConfigFactoryInterface::class); $config_factory ->method('get') ->with('acquia_connector.settings') ->willReturn($this->createMock(Config::class)); $time = $this->createMock(TimeInterface::class); $time ->method('getRequestTime') ->willReturn( strtotime('Oct 12 2022'), strtotime('Oct 12 2022'), strtotime('Nov 15 2022'), strtotime('Nov 15 2022'), strtotime('Mar 01 2023'), ); $client = new Client( $config_factory, $state, $time ); $data = $client->nspiCall('/agent-api/subscription', [], 'ABC'); self::assertArrayHasKey('result', $data); self::assertNotFalse($data['result']); $data = $client->nspiCall('/agent-api/subscription', [], 'ABC'); self::assertArrayHasKey('result', $data); self::assertNotFalse($data['result']); $this->expectException(ConnectorException::class); $this->expectExceptionMessage('Acquia Connector 3.x has reached end of life, please upgrade to 4.x to continue using it.'); $client->nspiCall('/agent-api/subscription', [], 'ABC'); } }