Add webhook simulation

This commit is contained in:
Alex P 2021-09-22 17:13:38 +03:00
parent 0268524261
commit ea2f728cd8
14 changed files with 896 additions and 20 deletions

View file

@ -9,11 +9,15 @@ declare(strict_types=1);
namespace WooCommerce\PayPalCommerce\Webhooks;
use phpDocumentor\Reflection\Types\This;
use WooCommerce\PayPalCommerce\ApiClient\Endpoint\WebhookEndpoint;
use WooCommerce\PayPalCommerce\ApiClient\Entity\Webhook;
use WooCommerce\PayPalCommerce\ApiClient\Entity\WebhookEvent;
use WooCommerce\PayPalCommerce\ApiClient\Exception\RuntimeException;
use WooCommerce\PayPalCommerce\ApiClient\Factory\WebhookEventFactory;
use WooCommerce\PayPalCommerce\Webhooks\Handler\RequestHandler;
use Psr\Log\LoggerInterface;
use WooCommerce\PayPalCommerce\Webhooks\Status\WebhookSimulation;
/**
* Class IncomingWebhookEndpoint
@ -58,28 +62,48 @@ class IncomingWebhookEndpoint {
*/
private $verify_request;
/**
* The webhook event factory.
*
* @var WebhookEventFactory
*/
private $webhook_event_factory;
/**
* The simulation handler.
*
* @var WebhookSimulation
*/
private $simulation;
/**
* IncomingWebhookEndpoint constructor.
*
* @param WebhookEndpoint $webhook_endpoint The webhook endpoint.
* @param Webhook|null $webhook Our registered webhook.
* @param LoggerInterface $logger The logger.
* @param bool $verify_request Whether requests need to be verified or not.
* @param RequestHandler ...$handlers The handlers, which process a request in the end.
* @param WebhookEndpoint $webhook_endpoint The webhook endpoint.
* @param Webhook|null $webhook Our registered webhook.
* @param LoggerInterface $logger The logger.
* @param bool $verify_request Whether requests need to be verified or not.
* @param WebhookEventFactory $webhook_event_factory The webhook event factory.
* @param WebhookSimulation $simulation The simulation handler.
* @param RequestHandler ...$handlers The handlers, which process a request in the end.
*/
public function __construct(
WebhookEndpoint $webhook_endpoint,
?Webhook $webhook,
LoggerInterface $logger,
bool $verify_request,
WebhookEventFactory $webhook_event_factory,
WebhookSimulation $simulation,
RequestHandler ...$handlers
) {
$this->webhook_endpoint = $webhook_endpoint;
$this->webhook = $webhook;
$this->handlers = $handlers;
$this->logger = $logger;
$this->verify_request = $verify_request;
$this->webhook_endpoint = $webhook_endpoint;
$this->webhook = $webhook;
$this->handlers = $handlers;
$this->logger = $logger;
$this->verify_request = $verify_request;
$this->webhook_event_factory = $webhook_event_factory;
$this->simulation = $simulation;
}
/**
@ -110,9 +134,11 @@ class IncomingWebhookEndpoint {
/**
* Verifies the current request.
*
* @param \WP_REST_Request $request The request.
*
* @return bool
*/
public function verify_request(): bool {
public function verify_request( \WP_REST_Request $request ): bool {
if ( ! $this->verify_request ) {
return true;
}
@ -123,6 +149,12 @@ class IncomingWebhookEndpoint {
}
try {
$event = $this->event_from_request( $request );
if ( $this->simulation->is_simulation_event( $event ) ) {
return true;
}
$result = $this->webhook_endpoint->verify_current_request_for_webhook( $this->webhook );
if ( ! $result ) {
$this->logger->error( 'Webhook verification failed.' );
@ -142,6 +174,17 @@ class IncomingWebhookEndpoint {
* @return \WP_REST_Response
*/
public function handle_request( \WP_REST_Request $request ): \WP_REST_Response {
$event = $this->event_from_request( $request );
if ( $this->simulation->is_simulation_event( $event ) ) {
$this->logger->info( 'Received simulated webhook.' );
$this->simulation->receive( $event );
return rest_ensure_response(
array(
'success' => true,
)
);
}
foreach ( $this->handlers as $handler ) {
if ( $handler->responsible_for_request( $request ) ) {
@ -202,4 +245,16 @@ class IncomingWebhookEndpoint {
}
return array_unique( $event_types );
}
/**
* Creates WebhookEvent from request data.
*
* @param \WP_REST_Request $request The request with event data.
*
* @return WebhookEvent
* @throws RuntimeException When failed to create.
*/
private function event_from_request( \WP_REST_Request $request ): WebhookEvent {
return $this->webhook_event_factory->from_array( $request->get_params() );
}
}