turnstile

Drupal paywall plugin
Log | Files | Refs | README | LICENSE

commit 4e5bebc04690427cc5bdb064b9771dc39aee045e
parent a54d890e6fe1e2338a7b7823fb1f928699130618
Author: Christian Grothoff <christian@grothoff.org>
Date:   Thu,  9 Oct 2025 14:02:27 +0200

improve logging, handle 403

Diffstat:
Mturnstile.module | 75++++++++++++++++++++++++++++++++++++++++++---------------------------------
1 file changed, 42 insertions(+), 33 deletions(-)

diff --git a/turnstile.module b/turnstile.module @@ -53,6 +53,7 @@ function turnstile_entity_bundle_field_info_alter(&$fields, EntityTypeInterface * Implements hook_entity_view_alter(). */ function turnstile_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) { + $log_verbose = FALSE; if (!$entity instanceof NodeInterface) { // Turnstile only processes nodes. return; @@ -79,11 +80,15 @@ function turnstile_entity_view_alter(array &$build, EntityInterface $entity, Ent // Get the original body content. if (!$node->hasField('body')) { - \Drupal::logger('turnstile')->debug('Note has no body, skipping payment.'); + if ($log_verbose) { + \Drupal::logger('turnstile')->debug('Node has no body, skipping payment.'); + } return; } if ($node->get('body')->isEmpty()) { - \Drupal::logger('turnstile')->debug('Note has empty body, skipping payment.'); + if ($log_verbose) { + \Drupal::logger('turnstile')->debug('Node has empty body, skipping payment.'); + } return; } $body_value = $node->get('body')->value; @@ -95,7 +100,7 @@ function turnstile_entity_view_alter(array &$build, EntityInterface $entity, Ent \Drupal::logger('turnstile')->debug('Checking for payment...'); // Check if user has already paid for a non-expired subscription. - if (time() < $_SESSION['turnstile_subscriber'] ?? 0) { + if (time() < ($_SESSION['turnstile_subscriber'] ?? 0)) { \Drupal::logger('turnstile')->debug('Subscriber cookie detected, granting access.'); return; } @@ -332,7 +337,9 @@ function turnstile_check_order_status($order_id) { case 200: // Success, handled below break; - // FIXME: also handle unauthorized! + case 403: + \Drupal::logger('turnstile')->warning('Access denied by the merchant backend. Did your credentials change or expire? Check your Turnstile configuration!'); + return FALSE; case 404: // Order unknown or instance unknown $ec = $result['code'] ?? 0; @@ -486,36 +493,38 @@ function turnstile_create_order(NodeInterface $node) { $result = json_decode($body, TRUE); switch ($http_status) { - case 200: - case 201: /* 201 is not in-spec, but tolerated for now */ - if (! isset($result['order_id'])) { - \Drupal::logger('turnstile')->error('Failed to create order: HTTP success response unexpectedly lacks "order_id" field.'); + case 200: + case 201: /* 201 is not in-spec, but tolerated for now */ + if (! isset($result['order_id'])) { + \Drupal::logger('turnstile')->error('Failed to create order: HTTP success response unexpectedly lacks "order_id" field.'); + return FALSE; + } + /* Success, handled below */ + break; + case 403: + \Drupal::logger('turnstile')->warning('Access denied by the merchant backend. Did your credentials change or expire? Check your Turnstile configuration!'); return FALSE; - } - /* Success, handled below */ - break; - // FIXME: also handle unauthorized! - case 404: - // FIXME: go into details on why we could get 404 here... - $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - \Drupal::logger('turnstile')->error('Failed to create order: @hint (@ec): @body', ['@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); - return FALSE; - case 409: - case 410: - /* 409: We didn't specify an order, so this should be "wrong currency", which again Turnstile tries to prevent. So this shouldn't be possible. */ - /* 410: We didn't specify a product, so out-of-stock should also be impossible for Turnstile */ - $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - \Drupal::logger('turnstile')->error('Unexpected HTTP status code @status trying to create order: @hint (@detail, #@ec): @body', ['@status' => $http_status, '@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@detail' => $result['detail'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); - return FALSE; - case 451: - /* KYC required, can happen, warn */ - \Drupal::logger('turnstile')->warning('Failed to create order as legitimization is required first. Please check legitimization status in your merchant backend.'); - return FALSE; - default: - $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); - \Drupal::logger('turnstile')->error('Unexpected HTTP status code @status trying to create order: @hint (@detail, #@ec): @body', ['@status' => $http_status, '@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@detail' => $result['detail'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); - return FALSE; - } + case 404: + // FIXME: go into details on why we could get 404 here... + $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + \Drupal::logger('turnstile')->error('Failed to create order: @hint (@ec): @body', ['@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); + return FALSE; + case 409: + case 410: + /* 409: We didn't specify an order, so this should be "wrong currency", which again Turnstile tries to prevent. So this shouldn't be possible. */ + /* 410: We didn't specify a product, so out-of-stock should also be impossible for Turnstile */ + $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + \Drupal::logger('turnstile')->error('Unexpected HTTP status code @status trying to create order: @hint (@detail, #@ec): @body', ['@status' => $http_status, '@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@detail' => $result['detail'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); + return FALSE; + case 451: + /* KYC required, can happen, warn */ + \Drupal::logger('turnstile')->warning('Failed to create order as legitimization is required first. Please check legitimization status in your merchant backend.'); + return FALSE; + default: + $body_log = json_encode($result, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); + \Drupal::logger('turnstile')->error('Unexpected HTTP status code @status trying to create order: @hint (@detail, #@ec): @body', ['@status' => $http_status, '@hint' => $result['hint'] ?? 'N/A', '@ec' => $result['code'] ?? 'N/A', '@detail' => $result['detail'] ?? 'N/A', '@body' => $body_log ?? 'N/A']); + return FALSE; + } // end switch on HTTP status $order_id = $result['order_id']; return [