config_preview_deploy-1.0.0-alpha3/src/HashVerification.php

src/HashVerification.php
<?php

declare(strict_types=1);

namespace Drupal\config_preview_deploy;

use Drupal\Core\Site\Settings;
use Drupal\Core\Url;

/**
 * Provides hash generation and verification for secure communication.
 *
 * This service centralizes all hash-based verification logic using a
 * production-host + time-based approach to ensure secure communication
 * between preview and production environments.
 */
class HashVerification {

  /**
   * The settings service.
   *
   * @var \Drupal\Core\Site\Settings
   */
  protected Settings $settings;

  /**
   * Constructs a HashVerification object.
   *
   * @param \Drupal\Core\Site\Settings $settings
   *   The settings service.
   */
  public function __construct(Settings $settings) {
    $this->settings = $settings;
  }

  /**
   * Generates a verification hash for secure communication.
   *
   * @param string $productionHost
   *   The production host to bind the hash to.
   * @param int $timestamp
   *   The timestamp for the hash.
   *
   * @return string
   *   The generated verification hash.
   */
  public function generateVerificationHash(string $productionHost, int $timestamp): string {
    return hash('sha256', $productionHost . $timestamp . $this->getHashSalt());
  }

  /**
   * Verifies a provided hash against expected values.
   *
   * @param string $providedHash
   *   The hash to verify.
   * @param int $timestamp
   *   The timestamp to verify.
   * @param string|null $productionHost
   *   (optional) The production host to verify against. If not provided,
   *   extracts the host from Drupal's base URL.
   *
   * @return bool
   *   TRUE if the hash is valid, FALSE otherwise.
   */
  public function verifyHash(string $providedHash, int $timestamp, ?string $productionHost = NULL): bool {
    // Check timestamp age to prevent replay attacks (fixed 300 seconds).
    if (abs(time() - $timestamp) > 300) {
      return FALSE;
    }

    // If production host not provided, extract from Drupal's base URL.
    if ($productionHost === NULL) {
      // Get current site's base URL using admin path to avoid frontend domain
      // overrides.
      $currentUrl = Url::fromRoute('system.admin', [], ['absolute' => TRUE])->toString();
      $productionHost = parse_url($currentUrl, PHP_URL_HOST);
    }

    $expectedHash = $this->generateVerificationHash($productionHost, $timestamp);
    return hash_equals($expectedHash, $providedHash);
  }

  /**
   * Gets the hash salt from Drupal settings.
   *
   * @return string
   *   The hash salt.
   */
  protected function getHashSalt(): string {
    return $this->settings->getHashSalt();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc