Completed
Push — try/blocks-fix-default-attribu... ( e93e8d...58d11e )
by
unknown
68:14 queued 60:09
created

class-broken-token.php ➔ broken_token_jetpack_not_active()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 3
rs 10
c 0
b 0
f 0
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.1';
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_clear_blog_token', array( $this, 'admin_post_clear_blog_token' ) );
92
		add_action( 'admin_post_clear_user_tokens', array( $this, 'admin_post_clear_user_tokens' ) );
93
		add_action( 'admin_post_randomize_master_user', array( $this, 'admin_post_randomize_master_user' ) );
94
		add_action( 'admin_post_clear_master_user', array( $this, 'admin_post_clear_master_user' ) );
95
		add_action( 'admin_post_randomize_blog_id', array( $this, 'admin_post_randomize_blog_id' ) );
96
		add_action( 'admin_post_clear_blog_id', array( $this, 'admin_post_clear_blog_id' ) );
97
98
		$this->blog_token  = Jetpack_Options::get_option( 'blog_token' );
99
		$this->user_tokens = Jetpack_Options::get_option( 'user_tokens' );
100
		$this->master_user = Jetpack_Options::get_option( 'master_user' );
101
		$this->id          = Jetpack_Options::get_option( 'id' );
102
103
		if ( isset( $_GET['notice'] ) && check_admin_referer( 'jetpack_debug_broken_token_admin_notice', 'nonce' ) ) {
104
			$this->notice_type = $_GET['notice'];
105
			add_action( 'admin_notices', array( $this, 'render_admin_notice' ) );
106
		}
107
	}
108
109
	/**
110
	 * Enqueue scripts.
111
	 *
112
	 * @param string $hook Called hook.
113
	 */
114
	public function enqueue_scripts( $hook ) {
115
		if ( strpos( $hook, 'jetpack_page_broken-token' ) === 0 ) {
116
			wp_enqueue_style( 'broken_token_style', plugin_dir_url( __FILE__ ) . '/css/style.css', array(), JETPACK_DEBUG_HELPER_VERSION );
117
		}
118
	}
119
120
	/**
121
	 * Register's submenu.
122
	 */
123
	public function broken_token_register_submenu_page() {
124
		add_submenu_page(
125
			'jetpack',
126
			'Broken Token',
127
			'Broken Token',
128
			'manage_options',
129
			'broken-token',
130
			array( $this, 'render_ui' ),
131
			99
132
		);
133
	}
134
135
	/**
136
	 * Render UI.
137
	 */
138
	public function render_ui() {
139
		$stored_options = $this->get_stored_connection_options();
140
		?>
141
		<h1>Broken Token 😱!</h1>
142
		<p>This plugin will help you break the Jetpack connection in various ways.</p>
143
		<p>All instances of breaking only involve modifying the local DB options. Nothing done here will alter tokens stored in wp.com</p>
144
		<hr>
145
146
		<h2>Current token options being used by Jetpack:</h2>
147
		<p>Blog Token: <?php echo esc_html( $this->blog_token ); ?></p>
148
		<p>User Tokens: <?php print_r( $this->user_tokens ); ?></p>
149
		<p>Primary User: <?php echo esc_html( $this->master_user ); ?></p>
150
		<p>Blog ID: <?php echo esc_html( $this->id ); ?></p>
151
152
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
153
			<input type="hidden" name="action" value="store_current_options">
154
			<?php wp_nonce_field( 'store-current-options' ); ?>
155
			<input type="submit" value="Store these options" class="button button-primary">
156
		</form>
157
		<br>
158
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
159
			<input type="hidden" name="action" value="restore_from_stored_options">
160
			<?php wp_nonce_field( 'restore-stored-options' ); ?>
161
			<input type="submit" value="Restore from stored options" class="button button-primary <?php echo empty( $stored_options ) ? 'disabled' : ''; ?>">
162
		</form>
163
164
		<?php
165
		echo '<h2>Stored connection options.</h2>';
166
		echo '<p>Might be useful to store valid connection options before breaking it, so you can restore later.</p>';
167
		if ( empty( $stored_options ) ) {
168
			echo '<p>No connection options are currently stored!</p>';
169
		} else {
170
			echo '<pre>';
171
			print_r( $stored_options );
172
			echo '</pre>';
173
		}
174
		?>
175
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
176
			<input type="hidden" name="action" value="clear_stored_options">
177
			<?php wp_nonce_field( 'clear-stored-options' ); ?>
178
			<input type="submit" value="Clear stored options" class="button button-primary <?php echo empty( $stored_options ) ? 'disabled' : ''; ?>">
179
		</form>
180
181
		<hr>
182
183
		<h2>Break some stuff:</h2>
184
		<p><strong>Break the blog token:</strong></p>
185
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
186
			<input type="hidden" name="action" value="set_invalid_blog_token">
187
			<?php wp_nonce_field( 'set-invalid-blog-token' ); ?>
188
			<input type="submit" value="Set invalid blog token" class="button button-primary button-break-it">
189
		</form>
190
		<br>
191
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
192
			<input type="hidden" name="action" value="clear_blog_token">
193
			<?php wp_nonce_field( 'clear-blog-token' ); ?>
194
			<input type="submit" value="Clear blog token" class="button button-primary button-break-it">
195
		</form>
196
197
		<p><strong>Break the user tokens:</strong></p>
198
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
199
			<input type="hidden" name="action" value="clear_user_tokens">
200
			<?php wp_nonce_field( 'clear-user-tokens' ); ?>
201
			<input type="submit" value="Clear user tokens" class="button button-primary button-break-it">
202
		</form>
203
		<br>
204
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
205
			<input type="hidden" name="action" value="set_invalid_user_tokens">
206
			<?php wp_nonce_field( 'set-invalid-user-tokens' ); ?>
207
			<input type="submit" value="Set invalid user tokens" class="button button-primary button-break-it">
208
		</form>
209
210
		<p><strong>Break the Primary User:</strong></p>
211
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
212
			<input type="hidden" name="action" value="randomize_master_user">
213
			<?php wp_nonce_field( 'randomize-master-user' ); ?>
214
			<input type="submit" value="Randomize Primary User ID" class="button button-primary button-break-it">
215
		</form>
216
		<br>
217
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
218
			<input type="hidden" name="action" value="clear_master_user">
219
			<?php wp_nonce_field( 'clear-master-user' ); ?>
220
			<input type="submit" value="Clear the Primary User" class="button button-primary button-break-it">
221
		</form>
222
223
		<p><strong>Break the blog ID:</strong></p>
224
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
225
			<input type="hidden" name="action" value="randomize_blog_id">
226
			<?php wp_nonce_field( 'randomize-blog-id' ); ?>
227
			<input type="submit" value="Randomize Blog ID" class="button button-primary button-break-it">
228
		</form>
229
		<br>
230
		<form action="<?php echo esc_url( admin_url( 'admin-post.php' ) ); ?>" method="post">
231
			<input type="hidden" name="action" value="clear_blog_id">
232
			<?php wp_nonce_field( 'clear-blog-id' ); ?>
233
			<input type="submit" value="Clear the Blog ID" class="button button-primary button-break-it">
234
		</form>
235
		<?php
236
	}
237
238
	/**
239
	 * Store options.
240
	 */
241
	public function admin_post_store_current_options() {
242
		check_admin_referer( 'store-current-options' );
243
		$this->notice_type = 'store-options';
244
		$this->store_current_options();
245
246
		$this->admin_post_redirect_referrer();
247
	}
248
249
	/**
250
	 * Clear options.
251
	 */
252
	public function admin_post_clear_stored_options() {
253
		check_admin_referer( 'clear-stored-options' );
254
		$this->clear_stored_options();
255
256
		$this->admin_post_redirect_referrer();
257
	}
258
259
	/**
260
	 * Restore from options.
261
	 */
262
	public function admin_post_restore_from_stored_options() {
263
		check_admin_referer( 'restore-stored-options' );
264
		$this->notice_type = 'restore-options';
265
		foreach ( $this->get_stored_connection_options() as $key => $value ) {
266
			if ( empty( $value ) ) {
267
				continue;
268
			}
269
			Jetpack_Options::update_option( $key, $value );
270
		}
271
272
		$this->admin_post_redirect_referrer();
273
	}
274
275
	/**
276
	 * Set invalid blog token.
277
	 */
278
	public function admin_post_set_invalid_blog_token() {
279
		check_admin_referer( 'set-invalid-blog-token' );
280
		$this->notice_type = 'jetpack-broken';
281
		Jetpack_Options::update_option( 'blog_token', $this->invalid_blog_token );
282
283
		$this->admin_post_redirect_referrer();
284
	}
285
286
	/**
287
	 * Set invalid user token.
288
	 */
289
	public function admin_post_set_invalid_user_tokens() {
290
		check_admin_referer( 'set-invalid-user-tokens' );
291
		$this->notice_type = 'jetpack-broken';
292
		foreach ( Jetpack_Options::get_option( 'user_tokens', array() ) as $id => $token ) {
293
			Jetpack_Options::update_option( 'user_tokens', array( $id => $this->invalid_user_token ) );
294
		}
295
296
		$this->admin_post_redirect_referrer();
297
	}
298
299
	/**
300
	 * Clear blog token.
301
	 */
302
	public function admin_post_clear_blog_token() {
303
		check_admin_referer( 'clear-blog-token' );
304
		$this->notice_type = 'jetpack-broken';
305
		Jetpack_Options::delete_option( 'blog_token' );
306
		$this->admin_post_redirect_referrer();
307
	}
308
309
	/**
310
	 * Clear user token.
311
	 */
312
	public function admin_post_clear_user_tokens() {
313
		check_admin_referer( 'clear-user-tokens' );
314
		$this->notice_type = 'jetpack-broken';
315
		Jetpack_Options::delete_option( 'user_tokens' );
316
		$this->admin_post_redirect_referrer();
317
	}
318
319
	/**
320
	 * Randomize master user.
321
	 */
322
	public function admin_post_randomize_master_user() {
323
		check_admin_referer( 'randomize-master-user' );
324
		$this->notice_type = 'jetpack-broken';
325
		$current_id        = Jetpack_Options::get_option( 'master_user' );
326
		Jetpack_Options::update_option( 'master_user', wp_rand( $current_id + 1, $current_id + 100 ) );
327
		$this->admin_post_redirect_referrer();
328
	}
329
330
	/**
331
	 * Clear master user.
332
	 */
333
	public function admin_post_clear_master_user() {
334
		check_admin_referer( 'clear-master-user' );
335
		$this->notice_type = 'jetpack-broken';
336
		Jetpack_Options::delete_option( 'master_user' );
337
		$this->admin_post_redirect_referrer();
338
	}
339
340
	/**
341
	 * Randomize blog ID.
342
	 */
343
	public function admin_post_randomize_blog_id() {
344
		check_admin_referer( 'randomize-blog-id' );
345
		$this->notice_type = 'jetpack-broken';
346
		Jetpack_Options::update_option( 'id', wp_rand( 100, 10000 ) );
347
		$this->admin_post_redirect_referrer();
348
	}
349
350
	/**
351
	 * Clear blog ID.
352
	 */
353
	public function admin_post_clear_blog_id() {
354
		check_admin_referer( 'clear-blog-id' );
355
		$this->notice_type = 'jetpack-broken';
356
		Jetpack_Options::delete_option( 'id' );
357
		$this->admin_post_redirect_referrer();
358
	}
359
360
	/**
361
	 * Stores a backup of the current Jetpack connection options.
362
	 */
363
	public function store_current_options() {
364
		update_option(
365
			self::STORED_OPTIONS_KEY,
366
			array(
367
				'blog_token'  => $this->blog_token,
368
				'user_tokens' => $this->user_tokens,
369
				'master_user' => $this->master_user,
370
				'id'          => $this->id,
371
			)
372
		);
373
	}
374
375
	/**
376
	 * Retrieves the stored connection options.
377
	 *
378
	 * @return array
379
	 */
380
	public function get_stored_connection_options() {
381
		return get_option( self::STORED_OPTIONS_KEY );
382
	}
383
384
	/**
385
	 * Clears all stored connection option values.
386
	 */
387
	public function clear_stored_options() {
388
		delete_option( self::STORED_OPTIONS_KEY );
389
	}
390
391
	/**
392
	 * Just redirects back to the referrer. Keeping it DRY.
393
	 */
394
	public function admin_post_redirect_referrer() {
395
		if ( wp_get_referer() ) {
396
			wp_safe_redirect(
397
				add_query_arg(
398
					array(
399
						'notice' => $this->notice_type,
400
						'nonce'  => wp_create_nonce( 'jetpack_debug_broken_token_admin_notice' ),
401
					),
402
					wp_get_referer()
403
				)
404
			);
405
		} else {
406
			wp_safe_redirect( get_home_url() );
407
		}
408
	}
409
410
	/**
411
	 * Displays an admin notice...
412
	 */
413
	public function render_admin_notice() {
414
		switch ( $this->notice_type ) {
415
			case 'jetpack-broken':
416
				$message = 'Nice! You broke Jetpack!';
417
				break;
418
			case 'store-options':
419
				$message = 'Success! Backup of the connection options stored safely.';
420
				break;
421
			case 'restore-options':
422
				$message = 'Success! You\'ve restored the connection options. I hope things are working well now.';
423
				break;
424
			default:
425
				$message = 'Setting saved!';
426
				break;
427
		}
428
429
		printf( '<div class="notice notice-success"><p>%s</p></div>', esc_html( $message ) );
430
	}
431
}
432
433
add_action( 'plugins_loaded', 'register_broken_token', 1000 );
434
435
436
/**
437
 * Load the brokenness.
438
 */
439
function register_broken_token() {
440
	if ( class_exists( 'Jetpack' ) ) {
441
		new Broken_Token();
442
		if ( class_exists( 'Automattic\Jetpack\Connection\Error_Handler' ) ) {
443
			new Broken_Token_XmlRpc();
444
		}
445
	} else {
446
		add_action( 'admin_notices', 'broken_token_jetpack_not_active' );
447
	}
448
}
449
450
/**
451
 * Notice for if Jetpack is not active.
452
 */
453
function broken_token_jetpack_not_active() {
454
	echo '<div class="notice info"><p>Jetpack needs to be active and installed for the Broken Token plugin.</p></div>';
455
}
456
457
// phpcs:enable
458