PluginProbe
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More / 2.6.1
Content Control – The Ultimate Content Restriction Plugin! Restrict Content, Create Conditional Blocks & More v2.6.1
trunk 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 2.0.0 2.0.1 2.0.10 2.0.11 2.0.12 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 All 47 releases
← All changes | classes/Plugin/Connect.php +55 -24 2.0.42.6.1 View file →
@@ -15,15 +15,17 @@
15 15
16 16 /**
17 17 * Connection management.
18 18 *
19 + * NOTE: For wordpress.org admins: This is not called in the free, hosted version. This is only used if:
20 + * - The user explicitly entered a license key.
21 + * - This then opens a window to our site allowing the user to authorize the connection & installation of pro.
22 + *
19 23 * @package ContentControl
20 24 */
21 25 class Connect {
22 26
23 - const API_URL = 'https://upgrade.contentcontrolplugin.com/';
24 - const DEBUG_MODE = false;
25 -
27 + const API_URL = 'https://upgrade.contentcontrolplugin.com/';
26 28 const TOKEN_OPTION_NAME = 'content_control_connect_token';
27 29 const NONCE_OPTION_NAME = 'content_control_connect_nonce';
28 30
29 31 const ERROR_REFERRER = 1;
@@ -49,16 +51,25 @@
49 51 $this->c = $c;
50 52 }
51 53
52 54 /**
55 + * Check if debug mode is enabled.
56 + *
57 + * @return bool
58 + */
59 + public function debug_mode_enabled() {
60 + return defined( '\WP_DEBUG' ) && \WP_DEBUG;
61 + }
62 +
63 + /**
53 64 * Generate a new authorizatin token.
54 65 *
55 66 * @return string
56 67 */
57 68 public function generate_token() {
58 - $token = hash( 'sha512', wp_rand() );
69 + $token = hash( 'sha512', (string) wp_rand() );
59 70
60 - \update_option( self::TOKEN_OPTION_NAME, $token );
71 + \set_site_transient( self::TOKEN_OPTION_NAME, $token, HOUR_IN_SECONDS );
61 72
62 73 return $token;
63 74 }
64 75
@@ -67,9 +78,9 @@
67 78 *
68 79 * @return string|false
69 80 */
70 81 public function get_access_token() {
71 - return \get_option( self::TOKEN_OPTION_NAME, false );
82 + return \get_site_transient( self::TOKEN_OPTION_NAME );
72 83 }
73 84
74 85 /**
75 86 * Get the current nonce.
@@ -88,11 +99,13 @@
88 99 * Here to prevent constant conditional checks for the debug mode.
89 100 *
90 101 * @param string $message Message.
91 102 * @param string $type Type.
103 + *
104 + * @return void
92 105 */
93 106 public function debug_log( $message, $type = 'INFO' ) {
94 - if ( self::DEBUG_MODE ) {
107 + if ( $this->debug_mode_enabled() ) {
95 108 plugin( 'logging' )->log( "Plugin\Connect.$type: $message" );
96 109 }
97 110 }
98 111
@@ -98,9 +111,9 @@
98 111
99 112 /**
100 113 * Get header Authorization
101 114 *
102 - * @return string
115 + * @return null|string
103 116 */
104 117 public function get_request_authorization_header() {
105 118 $headers = null;
106 119
@@ -156,9 +169,9 @@
156 169 * Get the OAuth connect URL.
157 170 *
158 171 * @param string $license_key License key.
159 172 *
160 - * @return string
173 + * @return array{url:string,back_url:string}
161 174 */
162 175 public function get_connect_info( $license_key ) {
163 176 $token = $this->generate_token();
164 177 $nonce = wp_create_nonce( $this->get_nonce_name( $token ) );
@@ -205,15 +218,25 @@
205 218
206 219 /**
207 220 * Kill the connection with no permission.
208 221 *
209 - * @param int $error_no Error number.
210 - * @param string $message Error message.
222 + * @param int $error_no Error number.
223 + * @param string|false $message Error message.
224 + *
225 + * @return void
211 226 */
212 227 public function kill_connection( $error_no = self::ERROR_REFERRER, $message = false ) {
213 228 $this->debug_log( "Killing connection with error ($error_no) message: " . $message, 'ERROR' );
214 229
215 - wp_die( esc_html( self::DEBUG_MODE && $message ? $message : __( 'Sorry, You Are Not Allowed to Access This Page.', 'content-control' ) ), esc_attr( $error_no ), [ 'response' => 403 ] );
230 + wp_die(
231 + esc_html(
232 + $this->debug_mode_enabled() && $message ?
233 + $message :
234 + __( 'Sorry, You Are Not Allowed to Access This Page.', 'content-control' )
235 + ),
236 + esc_attr( (string) $error_no ),
237 + [ 'response' => 403 ]
238 + );
216 239 }
217 240
218 241 /**
219 242 * Verify the user agent.
@@ -260,8 +283,10 @@
260 283 /**
261 284 * Verify the nonce.
262 285 *
263 286 * @deprecated 2.0.0 Don't use, it doesn't work as its a separate server making request.
287 + *
288 + * @return void
264 289 */
265 290 public function verify_nonce() {
266 291 $token = $this->get_access_token();
267 292 $nonce = $this->get_request_nonce();
@@ -300,10 +325,14 @@
300 325
301 326 /**
302 327 * Generate signature hash.
303 328 *
304 - * @param array|string $data Data to hash.
305 - * @param string $token Token to hash with.
329 + * This must match the hash generated on the server.
330 + *
331 + * @see \ontentControlUpgrader\App::generate_hash()
332 + *
333 + * @param array<string,mixed>|string $data Data to hash.
334 + * @param string $token Token to hash with.
306 335 * @return string
307 336 */
308 337 public function generate_hash( $data, $token ) {
309 338 // Convert boolean values to their string representation.
@@ -324,8 +353,9 @@
324 353
325 354 // Generate the hash binary.
326 355 $hash = hash_hmac( 'sha256', $data, $token, true );
327 356
357 + // The only deviation from ServerSide is that we optionally log the hash if debug mode is enabled.
328 358 $this->debug_log( 'Hash: ' . $hash, 'DEBUG' );
329 359 $this->debug_log( 'Data: ' . $data, 'DEBUG' );
330 360
331 361 // Encode the hash in base64 to make it URL safe.
@@ -386,9 +416,9 @@
386 416
387 417 /**
388 418 * Get the webhook args.
389 419 *
390 - * @return array
420 + * @return array{file:string,type:string,slug:string,force:boolean}
391 421 */
392 422 public function get_webhook_args() {
393 423 $args = [
394 424 // phpcs:disable WordPress.Security.NonceVerification.Recommended
@@ -406,9 +436,9 @@
406 436
407 437 /**
408 438 * Verify and return webhook args.
409 439 *
410 - * @param array $args The webhook args.
440 + * @param array{file:string,type:string,slug:string,force:bool} $args The webhook args.
411 441 *
412 442 * @return void
413 443 */
414 444 public function verify_webhook_args( $args ) {
@@ -439,15 +469,9 @@
439 469
440 470 // 2. Get the webhook data.
441 471 $args = $this->get_webhook_args();
442 472
443 - // 3. Delete the token to prevent abuse.
444 - if ( ! self::DEBUG_MODE ) {
445 - $this->debug_log( 'Deleting token', 'DEBUG' );
446 - \delete_option( self::TOKEN_OPTION_NAME );
447 - }
448 -
449 - // 4. Validate license key.
473 + // 3. Validate license key.
450 474 if ( ! plugin( 'license' )->is_license_active() ) {
451 475 $this->debug_log( 'License not active', 'DEBUG' );
452 476 wp_send_json_error( $error );
453 477 }
@@ -454,19 +478,26 @@
454 478
455 479 // Set the current screen to avoid undefined notices.
456 480 set_current_screen( 'settings_page_content-control-settings' );
457 481
482 + // 4. Install the plugin.
458 483 switch ( $args['type'] ) {
459 484 case 'plugin':
460 485 $this->install_plugin( $args );
461 486 break;
462 487 }
488 +
489 + // 5. Delete the token to prevent abuse. Doing so last means it should be possible to retry if something goes wrong.
490 + if ( ! $this->debug_mode_enabled() ) {
491 + $this->debug_log( 'Deleting token', 'DEBUG' );
492 + \delete_site_transient( self::TOKEN_OPTION_NAME );
493 + }
463 494 }
464 495
465 496 /**
466 497 * Install a plugin.
467 498 *
468 - * @param array $args The file args.
499 + * @param array{file:string,type:string,slug:string,force:bool} $args The file args.
469 500 * @return void
470 501 */
471 502 public function install_plugin( $args ) {
472 503 $this->debug_log( 'Installing plugin...', 'DEBUG' );