PluginProbe
Jetpack – WP Security, Backup, Speed, & Growth / 16.2
Jetpack – WP Security, Backup, Speed, & Growth v16.2
16.3-a.5 16.3-a.7 16.3-a.3 16.3-a.1 16.2 16.2-beta 12.0.3 12.1.3 12.2.3 12.3.2 12.4.2 12.5.2 12.6.4 12.7.3 12.8.3 12.9.5 13.0.2 13.1.5 13.2.4 13.3.3 13.4.5 13.5.2 13.6.2 13.7.2 13.8.3 All 506 releases
jetpack / jetpack_vendor / automattic / jetpack-licensing / src / class-endpoints.php

class-endpoints.php in Jetpack – WP Security, Backup, Speed, & Growth 16.2, at jetpack_vendor/automattic/jetpack-licensing/src/class-endpoints.php

432 lines 11.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * A Licensing Endpoints class for Jetpack.
4 *
5 * @package automattic/jetpack-licensing
6 */
7
8 namespace Automattic\Jetpack\Licensing;
9
10 use Automattic\Jetpack\Connection\Client;
11 use Automattic\Jetpack\Licensing;
12 use Automattic\Jetpack\Status\Visitor;
13 use Jetpack_Options;
14 use WP_Error;
15 use WP_REST_Request;
16 use WP_REST_Response;
17
18 /**
19 * Class Endpoints.
20 * Helper class that is responsible for registering and responding to licensing endpoint requests.
21 *
22 * @since 1.7.0
23 */
24 class Endpoints {
25 /**
26 * This property stores the localized "Insufficient Permissions" error message.
27 *
28 * @var string Generic error message when user is not allowed to perform an action.
29 */
30 private static $user_permissions_error_msg;
31
32 /**
33 * Constructor.
34 */
35 public function __construct() {
36 self::$user_permissions_error_msg = esc_html__(
37 'You do not have the correct user permissions to perform this action.
38 Please contact your site admin if you think this is a mistake.',
39 'jetpack-licensing'
40 );
41 }
42
43 /**
44 * Declare the endpoints for the licensing package.
45 *
46 * @since 1.7.0
47 *
48 * @since-jetpack 10.9.0
49 */
50 public function register_endpoints() {
51 /*
52 * Get and update the last licensing error message.
53 */
54 register_rest_route(
55 'jetpack/v4',
56 '/licensing/error',
57 array(
58 array(
59 'methods' => \WP_REST_Server::READABLE,
60 'callback' => __CLASS__ . '::get_licensing_error',
61 'permission_callback' => __CLASS__ . '::can_manage_options_check',
62 ),
63 array(
64 'methods' => \WP_REST_Server::EDITABLE,
65 'callback' => __CLASS__ . '::update_licensing_error',
66 'permission_callback' => __CLASS__ . '::can_manage_options_check',
67 'args' => array(
68 'error' => array(
69 'required' => true,
70 'type' => 'string',
71 'validate_callback' => __CLASS__ . '::validate_string',
72 'sanitize_callback' => 'sanitize_text_field',
73 ),
74 ),
75 ),
76 )
77 );
78
79 /**
80 * Sets a license. This is still used as part of the first pass at licensing done for partners.
81 *
82 * See https://github.com/Automattic/jetpack/pull/23687 for more details.
83 */
84 register_rest_route(
85 'jetpack/v4',
86 '/licensing/set-license',
87 array(
88 'methods' => \WP_REST_Server::EDITABLE,
89 'callback' => __CLASS__ . '::set_jetpack_license',
90 'permission_callback' => __CLASS__ . '::set_jetpack_license_key_permission_check',
91 'args' => array(
92 'license' => array(
93 'required' => true,
94 'type' => 'string',
95 'validate_callback' => __CLASS__ . '::validate_string',
96 'sanitize_callback' => 'sanitize_text_field',
97 ),
98 ),
99 )
100 );
101
102 /**
103 * Get Jetpack user licenses.
104 */
105 register_rest_route(
106 'jetpack/v4',
107 'licensing/user/licenses',
108 array(
109 'methods' => \WP_REST_Server::READABLE,
110 'callback' => __CLASS__ . '::get_user_licenses',
111 'permission_callback' => __CLASS__ . '::can_manage_options_check',
112 )
113 );
114
115 /**
116 * Get Jetpack user license counts.
117 */
118 register_rest_route(
119 'jetpack/v4',
120 'licensing/user/counts',
121 array(
122 'methods' => \WP_REST_Server::READABLE,
123 'callback' => __CLASS__ . '::get_user_license_counts',
124 'permission_callback' => __CLASS__ . '::can_manage_options_check',
125 )
126 );
127
128 /**
129 * Update user-licensing activation notice dismiss info.
130 */
131 register_rest_route(
132 'jetpack/v4',
133 'licensing/user/activation-notice-dismiss',
134 array(
135 'methods' => \WP_REST_Server::EDITABLE,
136 'callback' => __CLASS__ . '::update_licensing_activation_notice_dismiss',
137 'permission_callback' => __CLASS__ . '::can_manage_options_check',
138 'args' => array(
139 'last_detached_count' => array(
140 'required' => true,
141 'type' => 'integer',
142 'validate_callback' => __CLASS__ . '::validate_non_neg_int',
143 ),
144 ),
145 )
146 );
147
148 /**
149 * Attach licenses to user account
150 */
151 register_rest_route(
152 'jetpack/v4',
153 '/licensing/attach-licenses',
154 array(
155 'methods' => \WP_REST_Server::EDITABLE,
156 'callback' => __CLASS__ . '::attach_jetpack_licenses',
157 'permission_callback' => __CLASS__ . '::can_manage_options_check',
158 'args' => array(
159 'licenses' => array(
160 'required' => true,
161 'type' => 'array',
162 'items' => array(
163 'type' => 'string',
164 ),
165 ),
166 ),
167 )
168 );
169 }
170
171 /**
172 * Verify that the user can set a Jetpack license key
173 *
174 * @since 1.7.0
175 *
176 * @since-jetpack 9.5.0
177 *
178 * @return bool|WP_Error True if user is able to set a Jetpack license key
179 */
180 public static function set_jetpack_license_key_permission_check() {
181 if ( Licensing::instance()->is_licensing_input_enabled() ) {
182 return true;
183 }
184
185 return new WP_Error( 'invalid_user_permission_set_jetpack_license_key', self::$user_permissions_error_msg, array( 'status' => rest_authorization_required_code() ) );
186 }
187
188 /**
189 * Verify that user can manage_options
190 *
191 * @since 1.7.0
192 *
193 * @return bool Whether user has the capability 'manage_options'.
194 */
195 public static function can_manage_options_check() {
196 if ( current_user_can( 'manage_options' ) ) {
197 return true;
198 }
199
200 return new WP_Error( 'invalid_user_permission_view_admin', self::$user_permissions_error_msg, array( 'status' => rest_authorization_required_code() ) );
201 }
202
203 /**
204 * Validates that the parameter is a string.
205 *
206 * @since 1.7.0
207 *
208 * @since-jetpack 4.3.0
209 *
210 * @param string $value Value to check.
211 * @param WP_REST_Request $request The request sent to the WP REST API.
212 * @param string $param Name of the parameter passed to endpoint holding $value.
213 *
214 * @return bool|WP_Error
215 */
216 public static function validate_string( $value, $request, $param ) {
217 if ( ! is_string( $value ) ) {
218 /* translators: %s: The literal parameter name. Should not be translated. */
219 return new WP_Error( 'invalid_param', sprintf( esc_html__( '%s must be a string.', 'jetpack-licensing' ), $param ) );
220 }
221 return true;
222 }
223
224 /**
225 * Validates that the parameter is a non-negative integer (includes 0).
226 *
227 * @since 1.7.0
228 *
229 * @since-jetpack 10.4.0
230 *
231 * @param int $value Value to check.
232 * @param WP_REST_Request $request The request sent to the WP REST API.
233 * @param string $param Name of the parameter passed to endpoint holding $value.
234 *
235 * @return bool|WP_Error
236 */
237 public static function validate_non_neg_int( $value, $request, $param ) {
238 if ( ! is_numeric( $value ) || $value < 0 ) {
239 return new WP_Error(
240 'invalid_param',
241 /* translators: %s: The literal parameter name. Should not be translated. */
242 sprintf( esc_html__( '%s must be a non-negative integer.', 'jetpack-licensing' ), $param )
243 );
244 }
245 return true;
246 }
247
248 /**
249 * Update the last licensing error message.
250 *
251 * @since 1.7.0
252 *
253 * @since-jetpack 9.0.0
254 *
255 * @param WP_REST_Request $request The request.
256 *
257 * @return bool true.
258 */
259 public static function update_licensing_error( $request ) {
260 Licensing::instance()->log_error( $request['error'] );
261
262 return true;
263 }
264
265 /**
266 * Get the last licensing error message, if any.
267 *
268 * @since 1.7.0
269 *
270 * @since-jetpack 9.0.0
271 *
272 * @return string Licensing error message or empty string.
273 */
274 public static function get_licensing_error() {
275 return Licensing::instance()->last_error();
276 }
277
278 /**
279 * Set a Jetpack license
280 *
281 * @since 1.7.0
282 *
283 * @since-jetpack 9.6.0
284 *
285 * @param WP_REST_Request $request The request.
286 *
287 * @return WP_REST_Response|WP_Error A response object if the option was successfully updated, or a WP_Error if it failed.
288 */
289 public static function set_jetpack_license( $request ) {
290 $license = trim( sanitize_text_field( $request['license'] ) );
291
292 if ( Licensing::instance()->append_license( $license ) ) {
293 return rest_ensure_response( array( 'code' => 'success' ) );
294 }
295
296 return new WP_Error(
297 'setting_license_key_failed',
298 esc_html__( 'Could not set this license key. Please try again.', 'jetpack-licensing' ),
299 array( 'status' => 500 )
300 );
301 }
302
303 /**
304 * Gets the users licenses.
305 *
306 * @since 1.7.0
307 *
308 * @since-jetpack 10.4.0
309 *
310 * @return string|WP_Error A JSON object of user licenses if the request was successful, or a WP_Error otherwise.
311 */
312 public static function get_user_licenses() {
313 $wpcom_request = Client::wpcom_json_api_request_as_user(
314 '/jetpack-licensing/user/licenses',
315 '2',
316 array(
317 'method' => 'GET',
318 'headers' => array(
319 'Content-Type' => 'application/json',
320 'X-Forwarded-For' => ( new Visitor() )->get_ip( true ),
321 ),
322 )
323 );
324
325 $response_code = wp_remote_retrieve_response_code( $wpcom_request );
326 if ( 200 === $response_code ) {
327 $licenses = json_decode( wp_remote_retrieve_body( $wpcom_request ) );
328 return $licenses;
329 } else {
330 return new WP_Error(
331 'failed_to_fetch_data',
332 esc_html__( 'Unable to fetch the requested data.', 'jetpack-licensing' ),
333 array( 'status' => $response_code )
334 );
335 }
336 }
337
338 /**
339 * Gets the users licenses counts.
340 *
341 * @since 1.7.0
342 *
343 * @since-jetpack 10.4.0
344 *
345 * @return string|WP_Error A JSON object of user license counts if the request was successful, or a WP_Error otherwise.
346 */
347 public static function get_user_license_counts() {
348 $wpcom_request = Client::wpcom_json_api_request_as_user(
349 '/jetpack-licensing/user/licenses/counts',
350 '2',
351 array(
352 'method' => 'GET',
353 'headers' => array(
354 'Content-Type' => 'application/json',
355 'X-Forwarded-For' => ( new Visitor() )->get_ip( true ),
356 ),
357 )
358 );
359
360 $response_code = wp_remote_retrieve_response_code( $wpcom_request );
361 if ( 200 === $response_code ) {
362 $license_counts = json_decode( wp_remote_retrieve_body( $wpcom_request ) );
363 return $license_counts;
364 } else {
365 return new WP_Error(
366 'failed_to_fetch_data',
367 esc_html__( 'Unable to fetch the requested data.', 'jetpack-licensing' ),
368 array( 'status' => $response_code )
369 );
370 }
371 }
372
373 /**
374 * Update the user-licenses activation notice dismissal data.
375 *
376 * @since 1.7.0
377 *
378 * @since-jetpack 10.4.0
379 *
380 * @param WP_REST_Request $request The request sent to the WP REST API.
381 *
382 * @return array|WP_Error
383 */
384 public static function update_licensing_activation_notice_dismiss( $request ) {
385
386 if ( ! isset( $request['last_detached_count'] ) ) {
387 return new WP_Error( 'invalid_param', esc_html__( 'Missing parameter "last_detached_count".', 'jetpack-licensing' ), array( 'status' => 404 ) );
388 }
389
390 $default = array(
391 'last_detached_count' => null,
392 'last_dismissed_time' => null,
393 );
394 $last_detached_count = ( '' === $request['last_detached_count'] )
395 ? $default['last_detached_count']
396 : $request['last_detached_count'];
397 $last_dismissed_time = ( '' === $request['last_detached_count'] )
398 ? $default['last_dismissed_time']
399 // Use UTC timezone and convert to ISO8601 format(DateTime::W3C) for best compatibility with JavaScript Date in all browsers.
400 : ( new \DateTime( 'NOW', new \DateTimeZone( 'UTC' ) ) )->format( \DateTime::W3C );
401
402 $notice_data = array(
403 'last_detached_count' => $last_detached_count,
404 'last_dismissed_time' => $last_dismissed_time,
405 );
406
407 Jetpack_Options::update_option( 'licensing_activation_notice_dismiss', $notice_data, true );
408 return rest_ensure_response( $notice_data );
409 }
410
411 /**
412 * Attach Jetpack licenses
413 *
414 * @since 1.7.0
415 *
416 * @since-jetpack 10.4.0
417 *
418 * @param WP_REST_Request $request The request.
419 *
420 * @return WP_REST_Response|WP_Error A response object
421 */
422 public static function attach_jetpack_licenses( $request ) {
423 $licenses = array_map(
424 function ( $license ) {
425 return trim( sanitize_text_field( $license ) );
426 },
427 $request['licenses']
428 );
429 return rest_ensure_response( Licensing::instance()->attach_licenses( $licenses ) );
430 }
431 }
432