PluginProbe
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce / 3.3.0
CartFlows – Funnel Builder & Checkout Plugin for WooCommerce v3.3.0
3.3.0 3.2.1 3.2.0 3.1.4 3.1.3 3.1.2 3.1.1 3.1.0 3.0.1 trunk 1.0.4 1.1.0 1.1.0.1 1.1.1 1.1.10 1.1.11 1.1.12 1.1.13 1.1.14 1.1.15 1.1.16 1.1.17 1.1.18 1.1.19 1.1.2 All 162 releases
← All changes | admin-core/api/api-base.php +98 -1 3.1.1 → 3.3.0 View file →
@@ -6,8 +6,13 @@
6 6 */
7 7
8 8 namespace CartflowsAdmin\AdminCore\Api;
9 9
10 +use WP_REST_Controller;
11 +use WP_REST_Request;
12 +use WP_REST_Server;
13 +use WP_Error;
14 +
10 15 // Exit if accessed directly.
11 16 if ( ! defined( 'ABSPATH' ) ) {
12 17 exit;
13 18 }
@@ -14,9 +19,9 @@
14 19
15 20 /**
16 21 * Class Admin_Menu.
17 22 */
18 -abstract class ApiBase extends \WP_REST_Controller {
23 +abstract class ApiBase extends WP_REST_Controller {
19 24
20 25 /**
21 26 * Endpoint namespace.
22 27 *
@@ -37,6 +42,98 @@
37 42 */
38 43 public function get_api_namespace() {
39 44
40 45 return $this->namespace;
46 + }
47 +
48 + /**
49 + * Validate the nonce for REST API requests, then apply the
50 + * capability + Pro filter chain via check_permission_for_action().
51 + *
52 + * @param WP_REST_Request<array<string, mixed>> $request The REST request object.
53 + * @return bool|WP_Error True if valid, WP_Error if invalid.
54 + */
55 + public function validate_permission( $request ) {
56 + // Retrieve the nonce from the request header.
57 + $nonce = $request->get_header( 'X-WP-Nonce' );
58 +
59 + // Check if nonce is null or empty.
60 + if ( empty( $nonce ) || ! is_string( $nonce ) ) {
61 + return new WP_Error(
62 + 'cartflows_nonce_verification_failed',
63 + __( 'Nonce is missing.', 'cartflows' ),
64 + array( 'status' => rest_authorization_required_code() )
65 + );
66 + }
67 +
68 + // Verify the nonce.
69 + if ( ! wp_verify_nonce( $nonce, 'wp_rest' ) ) {
70 + return new WP_Error(
71 + 'cartflows_nonce_verification_failed',
72 + __( 'Nonce is invalid.', 'cartflows' ),
73 + array( 'status' => rest_authorization_required_code() )
74 + );
75 + }
76 +
77 + return self::check_permission_for_action( $request );
78 + }
79 +
80 + /**
81 + * Extracted from validate_permission() so the AJAX fallback in
82 + * inc/ajax/save-endpoints.php can enforce the exact same policy
83 + * that Pro plugins layer on top of the REST endpoints via the
84 + * `cartflows_rest_api_permission` and
85 + * `cartflows_rest_api_permission_check` filters. AJAX must not be
86 + * a back door around a Pro licensing or role policy that blocks
87 + * the REST endpoint.
88 + *
89 + * Callers are responsible for verifying request authenticity
90 + * (X-WP-Nonce for REST, `_wpnonce` via check_ajax_referer() for
91 + * AJAX) before invoking this helper.
92 + *
93 + * @param WP_REST_Request<array<string, mixed>> $request The REST request object (or a synthetic request built by the AJAX handler mirroring the equivalent REST route).
94 + * @return bool|WP_Error True on pass, WP_Error on denial.
95 + * @since x.x.x
96 + */
97 + public static function check_permission_for_action( $request ) {
98 + /**
99 + * Filter to allow Pro plugin or extensions to override permission checks.
100 + *
101 + * @since x.x.x
102 + * @param bool|WP_Error $has_permission True to allow access, WP_Error to deny with custom message, false to use default check.
103 + * @param WP_REST_Request $request The REST request object.
104 + */
105 + $has_permission = apply_filters( 'cartflows_rest_api_permission', false, $request );
106 +
107 + if ( is_wp_error( $has_permission ) ) {
108 + return $has_permission;
109 + }
110 +
111 + // If filter didn't handle permission (Pro not active), fall back to admin capability check.
112 + if ( true !== $has_permission ) {
113 + if ( ! current_user_can( 'manage_options' ) ) {
114 + return new WP_Error(
115 + 'cartflows_rest_cannot_access',
116 + __( 'You do not have permission to perform this action.', 'cartflows' ),
117 + array( 'status' => rest_authorization_required_code() )
118 + );
119 + }
120 + }
121 +
122 + /**
123 + * Filter to allow additional permission checks (e.g., license validation).
124 + *
125 + * This runs AFTER the user capability check has passed.
126 + *
127 + * @since x.x.x
128 + * @param bool|WP_Error $permission_status True if permission granted, WP_Error to deny.
129 + * @param WP_REST_Request $request The REST request object.
130 + */
131 + $permission_status = apply_filters( 'cartflows_rest_api_permission_check', true, $request );
132 +
133 + if ( is_wp_error( $permission_status ) ) {
134 + return $permission_status;
135 + }
136 +
137 + return true;
41 138 }
42 139 }