Completed
Push — update/editor-blocks-icon-colo... ( 093ab2...3cfb5e )
by
unknown
08:47
created

Broken_Token   A

Complexity

Total Complexity 36

Size/Duplication

Total Lines 466
Duplicated Lines 5.79 %

Coupling/Cohesion

Components 1
Dependencies 1

Importance

Changes 0
Metric Value
dl 27
loc 466
rs 9.52
c 0
b 0
f 0
wmc 36
lcom 1
cbo 1

22 Methods

Rating   Name   Duplication   Size   Complexity  
A enqueue_scripts() 0 5 2
A broken_token_register_submenu_page() 0 11 1
A __construct() 0 32 3
B render_ui() 0 111 4
A admin_post_store_current_options() 0 7 1
A admin_post_clear_stored_options() 0 6 1
A admin_post_restore_from_stored_options() 0 12 3
A admin_post_set_invalid_blog_token() 0 7 1
A admin_post_set_invalid_user_tokens() 14 14 2
A admin_post_set_invalid_current_user_token() 13 13 1
A admin_post_clear_blog_token() 0 6 1
A admin_post_clear_user_tokens() 0 6 1
A admin_post_randomize_master_user() 0 7 1
A admin_post_randomize_master_user_and_token() 0 14 2
A admin_post_clear_master_user() 0 6 1
A admin_post_randomize_blog_id() 0 6 1
A admin_post_clear_blog_id() 0 6 1
A store_current_options() 0 11 1
A get_stored_connection_options() 0 3 1
A clear_stored_options() 0 3 1
A admin_post_redirect_referrer() 0 15 2
A render_admin_notice() 0 18 4

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php // phpcs:disable WordPress.PHP.DevelopmentFunctions.error_log_print_r
2
/**
3
 * Plugin Name: Broken Token
4
 * Description: Give me a Jetpack connection, and I'll break it every way possible.
5
 * Author: Bestpack
6
 * Version: 1.0
7
 * Text Domain: jetpack
8
 *
9
 * @package Jetpack
10
 */
11
12
/**
13
 * Require the XMLRPC functionality.
14
 */
15
require 'inc/class-broken-token-xmlrpc.php';
16
17
/**
18
 * Class Broken_Token
19
 */
20
class Broken_Token {
21
	/**
22
	 * Notice type.
23
	 *
24
	 * @var mixed|string
25
	 */
26
	public $notice_type = '';
27
28
	/**
29
	 * Blog token.
30
	 *
31
	 * @var bool|mixed
32
	 */
33
	public $blog_token;
34
35
	/**
36
	 * User token.
37
	 *
38
	 * @var bool|mixed
39
	 */
40
	public $user_tokens;
41
42
	/**
43
	 * Jetpack Primary User.
44
	 *
45
	 * @var bool|mixed
46
	 */
47
	public $master_user;
48
49
	/**
50
	 * Site ID.
51
	 *
52
	 * @var bool|mixed
53
	 */
54
	public $id;
55
56
	/**
57
	 * Options.
58
	 */
59
	const STORED_OPTIONS_KEY = 'broken_token_stored_options';
60
61
	/**
62
	 * Token name.
63
	 *
64
	 * @var string
65
	 */
66
	public $invalid_blog_token = 'broken.token';
67
68
	/**
69
	 * User token name.
70
	 *
71
	 * @var string
72
	 */
73
	public $invalid_user_token = 'broken.token.%d';
74
75
	/**
76
	 * Broken_Token constructor.
77
	 */
78
	public function __construct() {
79
		add_action( 'admin_menu', array( $this, 'broken_token_register_submenu_page' ), 1000 );
80
81
		add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
82
83
		// Stored options.
84
		add_action( 'admin_post_clear_stored_options', array( $this, 'admin_post_clear_stored_options' ) );
85
		add_action( 'admin_post_store_current_options', array( $this, 'admin_post_store_current_options' ) );
86
		add_action( 'admin_post_restore_from_stored_options', array( $this, 'admin_post_restore_from_stored_options' ) );
87
88
		// Break stuff.
89
		add_action( 'admin_post_set_invalid_blog_token', array( $this, 'admin_post_set_invalid_blog_token' ) );
90
		add_action( 'admin_post_set_invalid_user_tokens', array( $this, 'admin_post_set_invalid_user_tokens' ) );
91
		add_action( 'admin_post_set_invalid_current_user_token', array( $this, 'admin_post_set_invalid_current_user_token' ) );
92
		add_action( 'admin_post_clear_blog_token', array( $this, 'admin_post_clear_blog_token' ) );
93
		add_action( 'admin_post_clear_user_tokens', array( $this, 'admin_post_clear_user_tokens' ) );
94
		add_action( 'admin_post_randomize_master_user', array( $this, 'admin_post_randomize_master_user' ) );
95
		add_action( 'admin_post_randomize_master_user_and_token', array( $this, 'admin_post_randomize_master_user_and_token' ) );
96
		add_action( 'admin_post_clear_master_user', array( $this, 'admin_post_clear_master_user' ) );
97
		add_action( 'admin_post_randomize_blog_id', array( $this, 'admin_post_randomize_blog_id' ) );
98
		add_action( 'admin_post_clear_blog_id', array( $this, 'admin_post_clear_blog_id' ) );
99
100
		$this->blog_token  = Jetpack_Options::get_option( 'blog_token' );
101
		$this->user_tokens = Jetpack_Options::get_option( 'user_tokens' );
102
		$this->master_user = Jetpack_Options::get_option( 'master_user' );
103
		$this->id          = Jetpack_Options::get_option( 'id' );
104
105
		if ( isset( $_GET['notice'] ) && check_admin_referer( 'jetpack_debug_broken_token_admin_notice', 'nonce' ) ) {
106
			$this->notice_type = $_GET['notice'];
107
			add_action( 'admin_notices', array( $this, 'render_admin_notice' ) );
108
		}
109
	}
110
111
	/**
112
	 * Enqueue scripts.
113
	 *
114
	 * @param string $hook Called hook.
115
	 */
116
	public function enqueue_scripts( $hook ) {
117
		if ( strpos( $hook, 'jetpack_page_broken-token' ) === 0 ) {
118
			wp_enqueue_style( 'broken_token_style', plugin_dir_url( __FILE__ ) . '/css/style.css', array(), JETPACK_DEBUG_HELPER_VERSION );
119
		}
120
	}
121
122
	/**
123
	 * Register's submenu.
124
	 */
125
	public function broken_token_register_submenu_page() {
126
		add_submenu_page(
127
			'jetpack-debug-tools',
128
			'Broken Token',
129
			'Broken Token',
130
			'manage_options',
131
			'broken-token',
132
			array( $this, 'render_ui' ),
133
			99
134
		);
135
	}
136
137
	/**
138
	 * Render UI.
139
	 */
140
	public function render_ui() {
141
		$stored_options = $this->get_stored_connection_options();
142
		?>
143
		<h1>Broken Token 😱!</h1>
144
		<p>This plugin will help you break the Jetpack connection in various ways.</p>
145
		<p>All instances of breaking only involve modifying the local DB options. Nothing done here will alter tokens stored in wp.com</p>
146
		<hr>
147
148
		<h2>Current token options being used by Jetpack:</h2>
149
		<p>Blog Token: <?php echo esc_html( $this->blog_token ); ?></p>
150
		<p>User Tokens: <?php print_r( $this->user_tokens ); ?></p>
151
		<p>Primary User: <?php echo esc_html( $this->master_user ); ?></p>
152
		<p>Blog ID: <?php echo esc_html( $this->id ); ?></p>
153
154
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
155
			<input type="hidden" name="action" value="store_current_options">
156
			<?php wp_nonce_field( 'store-current-options' ); ?>
157
			<input type="submit" value="Store these options" class="button button-primary">
158
		</form>
159
		<br>
160
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
161
			<input type="hidden" name="action" value="restore_from_stored_options">
162
			<?php wp_nonce_field( 'restore-stored-options' ); ?>
163
			<input type="submit" value="Restore from stored options" class="button button-primary <?php echo empty( $stored_options ) ? 'disabled' : ''; ?>">
164
		</form>
165
166
		<?php
167
		echo '<h2>Stored connection options.</h2>';
168
		echo '<p>Might be useful to store valid connection options before breaking it, so you can restore later.</p>';
169
		if ( empty( $stored_options ) ) {
170
			echo '<p>No connection options are currently stored!</p>';
171
		} else {
172
			echo '<pre>';
173
			print_r( $stored_options );
174
			echo '</pre>';
175
		}
176
		?>
177
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
178
			<input type="hidden" name="action" value="clear_stored_options">
179
			<?php wp_nonce_field( 'clear-stored-options' ); ?>
180
			<input type="submit" value="Clear stored options" class="button button-primary <?php echo empty( $stored_options ) ? 'disabled' : ''; ?>">
181
		</form>
182
183
		<hr>
184
185
		<h2>Break some stuff:</h2>
186
		<p><strong>Break the blog token:</strong></p>
187
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
188
			<input type="hidden" name="action" value="set_invalid_blog_token">
189
			<?php wp_nonce_field( 'set-invalid-blog-token' ); ?>
190
			<input type="submit" value="Set invalid blog token" class="button button-primary button-break-it">
191
		</form>
192
		<br>
193
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
194
			<input type="hidden" name="action" value="clear_blog_token">
195
			<?php wp_nonce_field( 'clear-blog-token' ); ?>
196
			<input type="submit" value="Clear blog token" class="button button-primary button-break-it">
197
		</form>
198
199
		<p><strong>Break the user tokens:</strong></p>
200
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
201
			<input type="hidden" name="action" value="clear_user_tokens">
202
			<?php wp_nonce_field( 'clear-user-tokens' ); ?>
203
			<input type="submit" value="Clear user tokens" class="button button-primary button-break-it">
204
		</form>
205
		<br>
206
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
207
			<input type="hidden" name="action" value="set_invalid_user_tokens">
208
			<?php wp_nonce_field( 'set-invalid-user-tokens' ); ?>
209
			<input type="submit" value="Set invalid user tokens" class="button button-primary button-break-it">
210
		</form>
211
		<br>
212
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
213
			<input type="hidden" name="action" value="set_invalid_current_user_token">
214
			<?php wp_nonce_field( 'set-invalid-current-user-token' ); ?>
215
			<input type="submit" value="Set invalid user token (current user)" class="button button-primary button-break-it">
216
		</form>
217
218
		<p><strong>Break the Primary User:</strong></p>
219
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
220
			<input type="hidden" name="action" value="randomize_master_user">
221
			<?php wp_nonce_field( 'randomize-master-user' ); ?>
222
			<input type="submit" value="Randomize Primary User ID" class="button button-primary button-break-it">
223
		</form>
224
		<br>
225
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
226
			<input type="hidden" name="action" value="randomize_master_user_and_token">
227
			<?php wp_nonce_field( 'randomize-master-user-and-token' ); ?>
228
			<input type="submit" value="Randomize Primary User ID and move the user token together" class="button button-primary button-break-it">
229
		</form>
230
		<br>
231
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
232
			<input type="hidden" name="action" value="clear_master_user">
233
			<?php wp_nonce_field( 'clear-master-user' ); ?>
234
			<input type="submit" value="Clear the Primary User" class="button button-primary button-break-it">
235
		</form>
236
237
		<p><strong>Break the blog ID:</strong></p>
238
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
239
			<input type="hidden" name="action" value="randomize_blog_id">
240
			<?php wp_nonce_field( 'randomize-blog-id' ); ?>
241
			<input type="submit" value="Randomize Blog ID" class="button button-primary button-break-it">
242
		</form>
243
		<br>
244
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
245
			<input type="hidden" name="action" value="clear_blog_id">
246
			<?php wp_nonce_field( 'clear-blog-id' ); ?>
247
			<input type="submit" value="Clear the Blog ID" class="button button-primary button-break-it">
248
		</form>
249
		<?php
250
	}
251
252
	/**
253
	 * Store options.
254
	 */
255
	public function admin_post_store_current_options() {
256
		check_admin_referer( 'store-current-options' );
257
		$this->notice_type = 'store-options';
258
		$this->store_current_options();
259
260
		$this->admin_post_redirect_referrer();
261
	}
262
263
	/**
264
	 * Clear options.
265
	 */
266
	public function admin_post_clear_stored_options() {
267
		check_admin_referer( 'clear-stored-options' );
268
		$this->clear_stored_options();
269
270
		$this->admin_post_redirect_referrer();
271
	}
272
273
	/**
274
	 * Restore from options.
275
	 */
276
	public function admin_post_restore_from_stored_options() {
277
		check_admin_referer( 'restore-stored-options' );
278
		$this->notice_type = 'restore-options';
279
		foreach ( $this->get_stored_connection_options() as $key => $value ) {
280
			if ( empty( $value ) ) {
281
				continue;
282
			}
283
			Jetpack_Options::update_option( $key, $value );
284
		}
285
286
		$this->admin_post_redirect_referrer();
287
	}
288
289
	/**
290
	 * Set invalid blog token.
291
	 */
292
	public function admin_post_set_invalid_blog_token() {
293
		check_admin_referer( 'set-invalid-blog-token' );
294
		$this->notice_type = 'jetpack-broken';
295
		Jetpack_Options::update_option( 'blog_token', $this->invalid_blog_token );
296
297
		$this->admin_post_redirect_referrer();
298
	}
299
300
	/**
301
	 * Set invalid user token.
302
	 */
303 View Code Duplication
	public function admin_post_set_invalid_user_tokens() {
304
		check_admin_referer( 'set-invalid-user-tokens' );
305
		$this->notice_type = 'jetpack-broken';
306
307
		$new_tokens = array();
308
309
		foreach ( Jetpack_Options::get_option( 'user_tokens' ) as $id => $token ) {
310
			$new_tokens[ $id ] = sprintf( $this->invalid_user_token, $id );
311
		}
312
313
		Jetpack_Options::update_option( 'user_tokens', $new_tokens );
314
315
		$this->admin_post_redirect_referrer();
316
	}
317
318
	/**
319
	 * Set invalid current user token.
320
	 */
321 View Code Duplication
	public function admin_post_set_invalid_current_user_token() {
322
		check_admin_referer( 'set-invalid-current-user-token' );
323
		$this->notice_type = 'jetpack-broken';
324
325
		$tokens = Jetpack_Options::get_option( 'user_tokens' );
326
327
		$id            = get_current_user_id();
328
		$tokens[ $id ] = sprintf( $this->invalid_user_token, $id );
329
330
		Jetpack_Options::update_option( 'user_tokens', $tokens );
331
332
		$this->admin_post_redirect_referrer();
333
	}
334
335
	/**
336
	 * Clear blog token.
337
	 */
338
	public function admin_post_clear_blog_token() {
339
		check_admin_referer( 'clear-blog-token' );
340
		$this->notice_type = 'jetpack-broken';
341
		Jetpack_Options::delete_option( 'blog_token' );
342
		$this->admin_post_redirect_referrer();
343
	}
344
345
	/**
346
	 * Clear user token.
347
	 */
348
	public function admin_post_clear_user_tokens() {
349
		check_admin_referer( 'clear-user-tokens' );
350
		$this->notice_type = 'jetpack-broken';
351
		Jetpack_Options::delete_option( 'user_tokens' );
352
		$this->admin_post_redirect_referrer();
353
	}
354
355
	/**
356
	 * Randomize master user.
357
	 */
358
	public function admin_post_randomize_master_user() {
359
		check_admin_referer( 'randomize-master-user' );
360
		$this->notice_type = 'jetpack-broken';
361
		$current_id        = Jetpack_Options::get_option( 'master_user' );
362
		Jetpack_Options::update_option( 'master_user', wp_rand( $current_id + 1, $current_id + 100 ) );
363
		$this->admin_post_redirect_referrer();
364
	}
365
366
	/**
367
	 * Randomize master user and its token.
368
	 */
369
	public function admin_post_randomize_master_user_and_token() {
370
		check_admin_referer( 'randomize-master-user-and-token' );
371
		$this->notice_type = 'jetpack-broken';
372
		$current_id        = Jetpack_Options::get_option( 'master_user' );
373
		$random_id         = wp_rand( $current_id + 1, $current_id + 100 );
374
		Jetpack_Options::update_option( 'master_user', $random_id );
375
		$user_tokens = Jetpack_Options::get_option( 'user_tokens', array() );
376
		if ( isset( $user_tokens[ $current_id ] ) ) {
377
			$user_tokens[ $random_id ] = substr( $user_tokens[ $current_id ], 0, strrpos( $user_tokens[ $current_id ], '.' ) ) . ".$random_id";
378
			unset( $user_tokens[ $current_id ] );
379
		}
380
		Jetpack_Options::update_option( 'user_tokens', $user_tokens );
381
		$this->admin_post_redirect_referrer();
382
	}
383
384
	/**
385
	 * Clear master user.
386
	 */
387
	public function admin_post_clear_master_user() {
388
		check_admin_referer( 'clear-master-user' );
389
		$this->notice_type = 'jetpack-broken';
390
		Jetpack_Options::delete_option( 'master_user' );
391
		$this->admin_post_redirect_referrer();
392
	}
393
394
	/**
395
	 * Randomize blog ID.
396
	 */
397
	public function admin_post_randomize_blog_id() {
398
		check_admin_referer( 'randomize-blog-id' );
399
		$this->notice_type = 'jetpack-broken';
400
		Jetpack_Options::update_option( 'id', wp_rand( 100, 10000 ) );
401
		$this->admin_post_redirect_referrer();
402
	}
403
404
	/**
405
	 * Clear blog ID.
406
	 */
407
	public function admin_post_clear_blog_id() {
408
		check_admin_referer( 'clear-blog-id' );
409
		$this->notice_type = 'jetpack-broken';
410
		Jetpack_Options::delete_option( 'id' );
411
		$this->admin_post_redirect_referrer();
412
	}
413
414
	/**
415
	 * Stores a backup of the current Jetpack connection options.
416
	 */
417
	public function store_current_options() {
418
		update_option(
419
			self::STORED_OPTIONS_KEY,
420
			array(
421
				'blog_token'  => $this->blog_token,
422
				'user_tokens' => $this->user_tokens,
423
				'master_user' => $this->master_user,
424
				'id'          => $this->id,
425
			)
426
		);
427
	}
428
429
	/**
430
	 * Retrieves the stored connection options.
431
	 *
432
	 * @return array
433
	 */
434
	public function get_stored_connection_options() {
435
		return get_option( self::STORED_OPTIONS_KEY );
436
	}
437
438
	/**
439
	 * Clears all stored connection option values.
440
	 */
441
	public function clear_stored_options() {
442
		delete_option( self::STORED_OPTIONS_KEY );
443
	}
444
445
	/**
446
	 * Just redirects back to the referrer. Keeping it DRY.
447
	 */
448
	public function admin_post_redirect_referrer() {
449
		if ( wp_get_referer() ) {
450
			wp_safe_redirect(
451
				add_query_arg(
452
					array(
453
						'notice' => $this->notice_type,
454
						'nonce'  => wp_create_nonce( 'jetpack_debug_broken_token_admin_notice' ),
455
					),
456
					wp_get_referer()
457
				)
458
			);
459
		} else {
460
			wp_safe_redirect( get_home_url() );
461
		}
462
	}
463
464
	/**
465
	 * Displays an admin notice...
466
	 */
467
	public function render_admin_notice() {
468
		switch ( $this->notice_type ) {
469
			case 'jetpack-broken':
470
				$message = 'Nice! You broke Jetpack!';
471
				break;
472
			case 'store-options':
473
				$message = 'Success! Backup of the connection options stored safely.';
474
				break;
475
			case 'restore-options':
476
				$message = 'Success! You\'ve restored the connection options. I hope things are working well now.';
477
				break;
478
			default:
479
				$message = 'Setting saved!';
480
				break;
481
		}
482
483
		printf( '<div class="notice notice-success"><p>%s</p></div>', esc_html( $message ) );
484
	}
485
}
486
487
add_action( 'plugins_loaded', 'register_broken_token', 1000 );
488
489
490
/**
491
 * Load the brokenness.
492
 */
493
function register_broken_token() {
494
	if ( class_exists( 'Jetpack_Options' ) ) {
495
		new Broken_Token();
496
		if ( class_exists( 'Automattic\Jetpack\Connection\Error_Handler' ) ) {
497
			new Broken_Token_XmlRpc();
498
		}
499
	} else {
500
		add_action( 'admin_notices', 'broken_token_jetpack_not_active' );
501
	}
502
}
503
504
/**
505
 * Notice for if Jetpack is not active.
506
 */
507
function broken_token_jetpack_not_active() {
508
	echo '<div class="notice info"><p>Jetpack Debug tools: Jetpack_Options package must be present for the Broken Token to work.</p></div>';
509
}
510
511
// phpcs:enable
512