docusign_signature-1.0.x-dev/src/Services/HmacSecurity.php

src/Services/HmacSecurity.php
<?php

declare(strict_types=1);

namespace Drupal\docusign_signature\Services;

use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\ImmutableConfig;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;

/**
 * Manage HMAC security.
 *
 * @package Drupal\docusign_signature\Services
 */
class HmacSecurity {

  /**
   * The DocuSign signature key prefix.
   * A same request may contain serveral header with an iterated suffix.
   *
   * @var string
   */
  const SIGNATURE_KEY_PREFIX = 'XDocusignSignature';

  /**
   * DocuSign module configuration.
   *
   * @var \Drupal\Core\Config\ImmutableConfig
   */
  private ImmutableConfig $config;

  /**
   * Current request.
   *
   * @var \Symfony\Component\HttpFoundation\Request
   */
  private Request $request;

  /**
   * Constructs a new HMAC security object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory.
   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
   *   The request stack.
   */
  public function __construct(ConfigFactoryInterface $config_factory, RequestStack $request_stack) {
    $this->config = $config_factory->get('docusign_signature.settings');
    $this->request = $request_stack->getCurrentRequest();
  }

  /**
   * Check HMAC Security in request headers.
   *
   * @param string $payload
   *   The request payload.
   *
   * @return bool
   *   Return "true" if header is present and HMAC is valid.
   */
  public function checkRequestHeaders(string $payload): bool {
    foreach ($this->request->headers->all() as $key => $value) {
      if (
        strstr($key, self::SIGNATURE_KEY_PREFIX) &&
        $this->isValidSignature($value, $payload)
      ) {
        return TRUE;
      }
    }

    return FALSE;
  }

  /**
   * Compute hash from request payload.
   *
   * @param string $payload
   *   The request payload.
   *
   * @return string
   *   The expected computed hash.
   */
  private function computeHash(string $payload): string {
    $hexHash = hash_hmac(
      'sha256',
      $payload,
      $this->config->get('hash.secret')
    );

    return base64_encode(hex2bin($hexHash));
  }

  /**
   * Check if signature is valid.
   *
   * @param string $signature
   *   The request header signature.
   * @param string $payload
   *   The request payload.
   *
   * @return bool
   *   Return "true" if HMAC is valid.
   */
  private function isValidSignature(string $signature, string $payload): bool {
    return hash_equals($signature, $this->computeHash($payload));
  }

}

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

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