From 3f3e11c917a687d6ab2665bfc316b5a6f51737a3 Mon Sep 17 00:00:00 2001
From: phenaproxima <phenaproxima@205645.no-reply.drupal.org>
Date: Thu, 9 Dec 2021 21:34:53 +0000
Subject: [PATCH] Issue #3253649 by phenaproxima: Validate
 update_fetch_with_http_fallback setting

---
 automatic_updates.services.yml                |  6 ++
 src/Validator/SettingsValidator.php           | 52 ++++++++++++++
 .../SettingsValidatorTest.php                 | 68 +++++++++++++++++++
 3 files changed, 126 insertions(+)
 create mode 100644 src/Validator/SettingsValidator.php
 create mode 100644 tests/src/Kernel/ReadinessValidation/SettingsValidatorTest.php

diff --git a/automatic_updates.services.yml b/automatic_updates.services.yml
index b54402216e..d648287bc9 100644
--- a/automatic_updates.services.yml
+++ b/automatic_updates.services.yml
@@ -30,6 +30,12 @@ services:
       - '@string_translation'
     tags:
       - { name: event_subscriber }
+  automatic_updates.validator.settings:
+    class: Drupal\automatic_updates\Validator\SettingsValidator
+    arguments:
+      - '@string_translation'
+    tags:
+      - { name: event_subscriber }
   automatic_updates.update_version_validator:
     class: Drupal\automatic_updates\Validator\UpdateVersionValidator
     arguments:
diff --git a/src/Validator/SettingsValidator.php b/src/Validator/SettingsValidator.php
new file mode 100644
index 0000000000..4d09e58df7
--- /dev/null
+++ b/src/Validator/SettingsValidator.php
@@ -0,0 +1,52 @@
+<?php
+
+namespace Drupal\automatic_updates\Validator;
+
+use Drupal\automatic_updates\Event\ReadinessCheckEvent;
+use Drupal\automatic_updates\Updater;
+use Drupal\Core\Site\Settings;
+use Drupal\Core\StringTranslation\StringTranslationTrait;
+use Drupal\Core\StringTranslation\TranslationInterface;
+use Drupal\package_manager\Event\PreCreateEvent;
+use Drupal\package_manager\Event\PreOperationStageEvent;
+use Symfony\Component\EventDispatcher\EventSubscriberInterface;
+
+class SettingsValidator implements EventSubscriberInterface {
+
+  use StringTranslationTrait;
+
+  /**
+   * Constructs a SettingsValidator object.
+   *
+   * @param \Drupal\Core\StringTranslation\TranslationInterface $translation
+   *   The string translation service.
+   */
+  public function __construct(TranslationInterface $translation) {
+    $this->setStringTranslation($translation);
+  }
+
+  /**
+   * Validates site settings before an update starts.
+   *
+   * @param \Drupal\package_manager\Event\PreOperationStageEvent $event
+   *   The event object.
+   */
+  public function checkSettings(PreOperationStageEvent $event): void {
+    if ($event->getStage() instanceof Updater && Settings::get('update_fetch_with_http_fallback')) {
+      $event->addError([
+        $this->t('The <code>update_fetch_with_http_fallback</code> setting must be disabled for automatic updates.'),
+      ]);
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getSubscribedEvents() {
+    return [
+      ReadinessCheckEvent::class => 'checkSettings',
+      PreCreateEvent::class => 'checkSettings',
+    ];
+  }
+
+}
diff --git a/tests/src/Kernel/ReadinessValidation/SettingsValidatorTest.php b/tests/src/Kernel/ReadinessValidation/SettingsValidatorTest.php
new file mode 100644
index 0000000000..90612a6b8b
--- /dev/null
+++ b/tests/src/Kernel/ReadinessValidation/SettingsValidatorTest.php
@@ -0,0 +1,68 @@
+<?php
+
+namespace Drupal\Tests\automatic_updates\Kernel\ReadinessValidation;
+
+use Drupal\package_manager\Exception\StageValidationException;
+use Drupal\package_manager\ValidationResult;
+use Drupal\Tests\automatic_updates\Kernel\AutomaticUpdatesKernelTestBase;
+
+/**
+ * @covers \Drupal\Tests\automatic_updates\Kernel\ReadinessValidation\SettingsValidatorTest
+ *
+ * @group automatic_updates
+ */
+class SettingsValidatorTest extends AutomaticUpdatesKernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = [
+    'automatic_updates',
+    'package_manager',
+    'package_manager_bypass',
+  ];
+
+  /**
+   * Data provider for ::testSettingsValidation().
+   *
+   * @return array[]
+   *   Sets of arguments to pass to the test method.
+   */
+  public function providerSettingsValidation(): array {
+    $result = ValidationResult::createError([
+      'The <code>update_fetch_with_http_fallback</code> setting must be disabled for automatic updates.',
+    ]);
+
+    return [
+      [TRUE, [$result]],
+      [FALSE, []],
+    ];
+  }
+
+  /**
+   * Tests settings validation before starting an update.
+   *
+   * @param bool $setting
+   *   The value of the update_fetch_with_http_fallback setting.
+   * @param \Drupal\package_manager\ValidationResult[] $expected_results
+   *   The expected validation results.
+   *
+   * @dataProvider providerSettingsValidation
+   */
+  public function testSettingsValidation(bool $setting, array $expected_results): void {
+    $this->setSetting('update_fetch_with_http_fallback', $setting);
+
+    $this->assertCheckerResultsFromManager($expected_results, TRUE);
+    try {
+      $this->container->get('automatic_updates.updater')->begin([
+        'drupal' => '9.8.1',
+      ]);
+      // If there was no exception, ensure we're not expecting any errors.
+      $this->assertSame([], $expected_results);
+    }
+    catch (StageValidationException $e) {
+      $this->assertValidationResultsEqual($expected_results, $e->getResults());
+    }
+  }
+
+}
-- 
GitLab