MonsterInsights_API_Auth::rotate_tt()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 2
eloc 2
c 2
b 0
f 0
nc 2
nop 0
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * Google Client admin class.
4
 *
5
 * Handles retrieving whether a particular notice has been dismissed or not,
6
 * as well as marking a notice as dismissed.
7
 *
8
 * @since 7.0.0
9
 *
10
 * @package MonsterInsights
11
 * @subpackage GA Client
12
 * @author  Chris Christoff
13
 */
14
15
// Exit if accessed directly
16
if ( ! defined( 'ABSPATH' ) ) {
17
	exit;
18
}
19
20
final class MonsterInsights_API_Auth {
21
22
	/**
23
	 * Primary class constructor.
24
	 *
25
	 * @access public
26
	 * @since 7.0.0
27
	 */
28
	public function __construct() {
29
30
		// Authentication Actions
31
		add_action( 'wp_ajax_monsterinsights_maybe_authenticate', array( $this, 'maybe_authenticate' ) );
32
		add_action( 'wp_ajax_monsterinsights_maybe_reauthenticate', array( $this, 'maybe_reauthenticate' ) );
33
		add_action( 'wp_ajax_monsterinsights_maybe_verify', array( $this, 'maybe_verify' ) );
34
		add_action( 'wp_ajax_monsterinsights_maybe_delete', array( $this, 'maybe_delete' ) );
35
36
		add_action( 'admin_init', array( $this, 'authenticate_listener' ) );
37
		add_action( 'admin_init', array( $this, 'reauthenticate_listener' ) );
38
39
		add_action( 'wp_ajax_nopriv_monsterinsights_is_installed', array( $this, 'is_installed' ) );
40
		add_action( 'wp_ajax_nopriv_monsterinsights_rauthenticate', array( $this, 'rauthenticate' ) );
41
42
		add_filter( 'monsterinsights_maybe_authenticate_siteurl', array( $this, 'before_redirect' ) );
43
44
		add_action( 'wp_ajax_nopriv_monsterinsights_push_mp_token', array( $this, 'handle_relay_mp_token_push' ) );
45
	}
46
47
	public function get_tt() {
48
		$tt = is_network_admin() ? get_site_option( 'monsterinsights_network_tt', '' ) : get_option( 'monsterinsights_site_tt', '' );
49
		if ( empty( $tt ) ) {
50
			// if TT is empty, generate a new one, save it and then return it
51
			$tt = $this->generate_tt();
52
			$this->is_network_admin() ? update_site_option( 'monsterinsights_network_tt', $tt ) : update_option( 'monsterinsights_site_tt', $tt );
53
		}
54
55
		return $tt;
56
	}
57
58
	public function rotate_tt() {
59
		$tt = $this->generate_tt();
60
		is_network_admin() ? update_site_option( 'monsterinsights_network_tt', $tt ) : update_option( 'monsterinsights_site_tt', $tt );
61
	}
62
63
	public function generate_tt() {
64
		return defined( 'AUTH_SALT' ) ? hash( 'sha512', wp_generate_password( 128, true, true ) . AUTH_SALT . uniqid( "", true ) ) : hash( 'sha512', wp_generate_password( 128, true, true ) . uniqid( "", true ) );
65
	}
66
67
	public function validate_tt( $passed_tt = '' ) {
68
		$tt = $this->get_tt();
69
70
		return hash_equals( $tt, $passed_tt );
71
	}
72
73
	public function is_installed() {
74
		wp_send_json_success(
75
			array(
76
				'version' => MONSTERINSIGHTS_VERSION,
77
				'pro'     => monsterinsights_is_pro_version(),
78
			)
79
		);
80
	}
81
82
	public function maybe_authenticate() {
83
84
		// Check nonce
85
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
86
87
		// current user can authenticate
88
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
89
			// Translators: link tag starts with url, link tag ends.
90
			$message = sprintf(
91
				__( 'You don\'t have the correct WordPress user permissions to authenticate into MonsterInsights. Please check with your site administrator that your role is included in the MonsterInsights permissions settings. %1$sClick here for more information%2$s.', 'google-analytics-for-wordpress' ),
92
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-save-settings', 'https://www.monsterinsights.com/docs/how-to-allow-user-roles-to-access-the-monsterinsights-reports-and-settings/' ) . '">',
93
				'</a>'
94
			);
95
			wp_send_json_error( array( 'message' => $message ) );
96
		}
97
98
		if ( ! empty( $_REQUEST['isnetwork'] ) && $_REQUEST['isnetwork'] ) { // phpcs:ignore
99
			define( 'WP_NETWORK_ADMIN', true );
100
		}
101
102
		// Only for Pro users, require a license key to be entered first so we can link to things.
103
		if ( monsterinsights_is_pro_version() ) {
104
			$valid = is_network_admin() ? MonsterInsights()->license->is_network_licensed() : MonsterInsights()->license->is_site_licensed();
105
			if ( ! $valid ) {
106
				wp_send_json_error( array( 'message' => __( "Cannot authenticate. Please enter a valid, active license key for MonsterInsights Pro into the settings page.", 'google-analytics-for-wordpress' ) ) );
107
			}
108
		}
109
110
		// we do not have a current auth
111
		if ( ! $this->is_network_admin() && MonsterInsights()->auth->is_authed() ) {
112
			// Translators: Support link tag starts with url, Support link tag ends.
113
			$message = sprintf(
114
				__( 'Oops! There has been an error authenticating. Please try again in a few minutes. If the problem persists, please %1$scontact our support%2$s team.', 'google-analytics-for-wordpress' ),
115
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'error-authenticating', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
116
				'</a>'
117
			);
118
			wp_send_json_error( array( 'message' => $message ) );
119
		} else if ( $this->is_network_admin() && MonsterInsights()->auth->is_network_authed() ) {
120
			// Translators: Support link tag starts with url, Support link tag ends.
121
			$message = sprintf(
122
				__( 'Oops! There has been an error authenticating. Please try again in a few minutes. If the problem persists, please %1$scontact our support%2$s team.', 'google-analytics-for-wordpress' ),
123
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'error-authenticating', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
124
				'</a>'
125
			);
126
			wp_send_json_error( array( 'message' => $message ) );
127
		}
128
129
		$sitei = $this->get_sitei();
130
131
        $auth_request_args = array(
132
            'tt'        => $this->get_tt(),
133
            'sitei'     => $sitei,
134
            'miversion' => MONSTERINSIGHTS_VERSION,
135
            'ajaxurl'   => admin_url( 'admin-ajax.php' ),
136
            'network'   => is_network_admin() ? 'network' : 'site',
137
            'siteurl'   => is_network_admin() ? network_admin_url() : home_url(),
138
            'return'    => is_network_admin() ? network_admin_url( 'admin.php?page=monsterinsights_network' ) : admin_url( 'admin.php?page=monsterinsights_settings' ),
139
            'testurl'   => 'https://' . monsterinsights_get_api_url() . 'test/',
140
        );
141
142
        $auth_request_args = apply_filters('monsterinsights_auth_request_body', $auth_request_args);
143
144
		$siteurl = add_query_arg($auth_request_args, $this->get_route( 'https://' . monsterinsights_get_api_url() . 'auth/new/{type}' ) );
145
146
		if ( monsterinsights_is_pro_version() ) {
147
			$key     = is_network_admin() ? MonsterInsights()->license->get_network_license_key() : MonsterInsights()->license->get_site_license_key();
148
			$siteurl = add_query_arg( 'license', $key, $siteurl );
149
		}
150
151
		$siteurl = apply_filters( 'monsterinsights_maybe_authenticate_siteurl', $siteurl );
152
		wp_send_json_success( array( 'redirect' => $siteurl ) );
153
	}
154
155
	private function send_missing_args_error( $arg ) {
156
		wp_send_json_error(
157
			array(
158
				'error'   => 'authenticate_missing_arg',
159
				'message' => 'Authenticate missing parameter: ' . $arg,
160
				'version' => MONSTERINSIGHTS_VERSION,
161
				'pro'     => monsterinsights_is_pro_version(),
162
			)
163
		);
164
	}
165
166
	public function rauthenticate() {
167
		// Check for missing params
168
		$reqd_args = array( 'key', 'token', 'miview', 'a', 'w', 'p', 'tt', 'network' );
169
170
		if ( empty( $_REQUEST['v4'] ) ) {
171
			$this->send_missing_args_error( 'v4' );
172
		}
173
174
		foreach ( $reqd_args as $arg ) {
175
			if ( empty( $_REQUEST[ $arg ] ) ) {
176
				$this->send_missing_args_error( $arg );
177
			}
178
		}
179
180
		if ( ! empty( $_REQUEST['network'] ) && 'network' === $_REQUEST['network'] ) {
181
			define( 'WP_NETWORK_ADMIN', true );
182
		}
183
184
		if ( ! $this->validate_tt( $_REQUEST['tt'] ) ) { // phpcs:ignore
185
			wp_send_json_error(
186
				array(
187
					'error'   => 'authenticate_invalid_tt',
188
					'message' => 'Invalid TT sent',
189
					'version' => MONSTERINSIGHTS_VERSION,
190
					'pro'     => monsterinsights_is_pro_version(),
191
				)
192
			);
193
		}
194
195
		// If the tt is validated, send a success response to trigger the regular auth process.
196
		wp_send_json_success();
197
	}
198
199
	public function authenticate_listener() {
200
		// Make sure it's for us
201
		if ( empty( $_REQUEST['mi-oauth-action'] ) || $_REQUEST['mi-oauth-action'] !== 'auth' ) {
202
			return;
203
		}
204
205
		// User can authenticate
206
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
207
			return;
208
		}
209
210
		// Invalid request
211
		if ( empty( $_REQUEST['tt'] ) || ! $this->validate_tt( $_REQUEST['tt'] ) ) {
212
			return;
213
		}
214
215
		// Make sure has required params
216
		if (
217
			empty( $_REQUEST['key'] ) ||
218
			empty( $_REQUEST['token'] ) ||
219
			empty( $_REQUEST['miview'] ) ||
220
			empty( $_REQUEST['a'] ) ||
221
			empty( $_REQUEST['w'] ) ||
222
			empty( $_REQUEST['p'] ) ||
223
			empty( $_REQUEST['v4'] )
224
		) {
225
			return;
226
		}
227
228
        $code_value = monsterinsights_is_valid_v4_id( $_REQUEST['v4'] ); // phpcs:ignore
229
230
		if ( empty( $code_value ) ) {
231
			return;
232
		}
233
234
		$profile = array(
235
			'key'           => sanitize_text_field( $_REQUEST['key'] ),
236
			'token'         => sanitize_text_field( $_REQUEST['token'] ),
237
			'viewname'      => sanitize_text_field( $_REQUEST['miview'] ),
238
			'a'             => sanitize_text_field( $_REQUEST['a'] ), // AccountID
239
			'w'             => sanitize_text_field( $_REQUEST['w'] ), // PropertyID
240
			'p'             => sanitize_text_field( $_REQUEST['p'] ), // View ID
241
			'siteurl'       => home_url(),
242
			'neturl'        => network_admin_url(),
243
		);
244
245
		if ( ! empty( $_REQUEST['mp'] ) ) {
246
			$profile['measurement_protocol_secret'] = sanitize_text_field( $_REQUEST['mp'] );
247
		}
248
249
		$profile['v4'] = $code_value;
250
251
		$worked = $this->verify_auth( $profile );
252
		if ( ! $worked || is_wp_error( $worked ) ) {
253
			return;
254
		}
255
256
		// Save Profile
257
		$this->is_network_admin() ? MonsterInsights()->auth->set_network_analytics_profile( $profile ) : MonsterInsights()->auth->set_analytics_profile( $profile );
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
258
259
		// Clear cache
260
		$where = $this->is_network_admin() ? 'network' : 'site';
261
		MonsterInsights()->reporting->delete_aggregate_data( $where );
262
263
		$url = $this->is_network_admin() ? network_admin_url( 'admin.php?page=monsterinsights_network' ) : admin_url( 'admin.php?page=monsterinsights_settings' );
264
		$url = add_query_arg( array(
265
			'mi_action' => 'auth',
266
			'success'   => 'true',
267
		), $url );
268
		$url = apply_filters( 'monsterinsights_auth_success_redirect_url', $url );
269
		wp_safe_redirect( $url );
270
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
271
	}
272
273
	public function maybe_reauthenticate() {
274
275
		// Check nonce
276
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
277
278
		$url = admin_url( 'admin.php?page=monsterinsights-onboarding' );
279
280
		// current user can authenticate
281
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
282
			// Translators: Link tag starts with url and link tag ends.
283
			$message = sprintf(
284
				__( 'You don\'t have the correct WordPress user permissions to re-authenticate into MonsterInsights. Please check with your site administrator that your role is included in the MonsterInsights permissions settings. %1$sClick here for more information%2$s.', 'google-analytics-for-wordpress' ),
285
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-save-settings', 'https://www.monsterinsights.com/docs/how-to-allow-user-roles-to-access-the-monsterinsights-reports-and-settings/' ) . '">',
286
				'</a>'
287
			);
288
			wp_send_json_error( array( 'message' => $message ) );
289
		}
290
291
		if ( ! empty( $_REQUEST['isnetwork'] ) && filter_var($_REQUEST['isnetwork'], FILTER_VALIDATE_BOOLEAN) ) {
292
			define( 'WP_NETWORK_ADMIN', true );
293
		}
294
295
		// Only for Pro users, require a license key to be entered first so we can link to things.
296
		if ( monsterinsights_is_pro_version() ) {
297
			$valid = is_network_admin() ? MonsterInsights()->license->is_network_licensed() : MonsterInsights()->license->is_site_licensed();
298
			if ( monsterinsights_is_pro_version() && ! $valid ) {
299
				wp_send_json_error( array( 'message' => __( "Your license key for MonsterInsights is invalid. The key no longer exists or the user associated with the key has been deleted. Please use a different key.", 'google-analytics-for-wordpress' ) ) );
300
			}
301
		}
302
303
		// we do have a current auth
304
		if ( ! $this->is_network_admin() && ! MonsterInsights()->auth->is_authed() ) {
305
			// Translators: Wizard Link tag starts with url, Wizard link tag ends, Support link tag starts, Support link tag ends.
306
			$message = sprintf(
307
				__( 'Oops! There was a problem while re-authenticating. Please try to complete the MonsterInsights %1$ssetup wizard%2$s again. If the problem persists, please %3$scontact our support%4$s team.', 'google-analytics-for-wordpress' ),
308
				'<a href="' . esc_url( $url ) . '">',
309
				'</a>',
310
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-re-authenticate', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
311
				'</a>'
312
			);
313
			wp_send_json_error( array( 'message' => $message ) );
314
		} else if ( $this->is_network_admin() && ! MonsterInsights()->auth->is_network_authed() ) {
315
			// Translators: Wizard Link tag starts with url, Wizard link tag ends, Support link tag starts, Support link tag ends.
316
			$message = sprintf(
317
				__( 'Oops! There was a problem while re-authenticating. Please try to complete the MonsterInsights %1$ssetup wizard%2$s again. If the problem persists, please %3$scontact our support%4$s team.', 'google-analytics-for-wordpress' ),
318
				'<a href="' . esc_url( $url ) . '">',
319
				'</a>',
320
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-re-authenticate', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
321
				'</a>'
322
			);
323
			wp_send_json_error( array( 'message' => $message ) );
324
		}
325
326
        $auth_request_args = array(
327
            'tt'        => $this->get_tt(),
328
            'sitei'     => $this->get_sitei(),
329
            'miversion' => MONSTERINSIGHTS_VERSION,
330
            'ajaxurl'   => admin_url( 'admin-ajax.php' ),
331
            'network'   => is_network_admin() ? 'network' : 'site',
332
            'siteurl'   => is_network_admin() ? network_admin_url() : home_url(),
333
            'key'       => is_network_admin() ? MonsterInsights()->auth->get_network_key() : MonsterInsights()->auth->get_key(),
334
            'token'     => is_network_admin() ? MonsterInsights()->auth->get_network_token() : MonsterInsights()->auth->get_token(),
335
            'return'    => is_network_admin() ? network_admin_url( 'admin.php?page=monsterinsights_network' ) : admin_url( 'admin.php?page=monsterinsights_settings' ),
336
            'testurl'   => 'https://' . monsterinsights_get_api_url() . 'test/',
337
        );
338
339
        $auth_request_args = apply_filters('monsterinsights_auth_request_body', $auth_request_args);
340
341
		$siteurl = add_query_arg( $auth_request_args, $this->get_route( 'https://' . monsterinsights_get_api_url() . 'auth/reauth/{type}' ) );
342
343
		if ( monsterinsights_is_pro_version() ) {
344
			$key     = is_network_admin() ? MonsterInsights()->license->get_network_license_key() : MonsterInsights()->license->get_site_license_key();
345
			$siteurl = add_query_arg( 'license', $key, $siteurl );
346
		}
347
348
		$siteurl = apply_filters( 'monsterinsights_maybe_authenticate_siteurl', $siteurl );
349
350
		wp_send_json_success( array( 'redirect' => $siteurl ) );
351
	}
352
353
	public function reauthenticate_listener() {
354
		// Make sure it's for us
355
		if ( empty( $_REQUEST['mi-oauth-action'] ) || $_REQUEST['mi-oauth-action'] !== 'reauth' ) {
356
			return;
357
		}
358
359
		// User can authenticate
360
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
361
			return;
362
		}
363
364
		// Invalid request
365
		if ( empty( $_REQUEST['tt'] ) || ! $this->validate_tt( $_REQUEST['tt'] ) ) { // phpcs:ignore
366
			return;
367
		}
368
369
		// Make sure has required params
370
		if (
371
            empty( $_REQUEST['v4'] ) ||
372
			empty( $_REQUEST['miview'] ) ||
373
			empty( $_REQUEST['a'] ) ||
374
			empty( $_REQUEST['w'] ) ||
375
			empty( $_REQUEST['p'] )
376
		) {
377
			return;
378
		}
379
380
        $code_value = monsterinsights_is_valid_v4_id( $_REQUEST['v4'] ); // phpcs:ignore
381
382
		if ( empty( $code_value ) ) {
383
			return;
384
		}
385
386
		// we do have a current auth
387
		$existing = $this->is_network_admin() ? MonsterInsights()->auth->get_network_analytics_profile() : MonsterInsights()->auth->get_analytics_profile();
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
388
		if ( empty( $existing['key'] ) || empty( $existing['token'] ) ) {
389
			return;
390
		}
391
392
		$profile = array(
393
			'key'           => $existing['key'],
394
			'token'         => $existing['token'],
395
			'viewname'      => sanitize_text_field( $_REQUEST['miview'] ),
396
			'a'             => sanitize_text_field( $_REQUEST['a'] ),
397
			'w'             => sanitize_text_field( $_REQUEST['w'] ),
398
			'p'             => sanitize_text_field( $_REQUEST['p'] ),
399
			'v4'            => $existing['v4'],
400
			'siteurl'       => home_url(),
401
			'neturl'        => network_admin_url(),
402
		);
403
404
		if ( ! empty( $_REQUEST['mp'] ) ) {
405
			$profile['measurement_protocol_secret'] = sanitize_text_field( $_REQUEST['mp'] );
406
		}
407
408
		$profile['v4'] = $code_value;
409
410
		// Save Profile
411
		$this->is_network_admin() ? MonsterInsights()->auth->set_network_analytics_profile( $profile ) : MonsterInsights()->auth->set_analytics_profile( $profile );
412
413
		// Clear cache
414
		$where = $this->is_network_admin() ? 'network' : 'site';
415
		MonsterInsights()->reporting->delete_aggregate_data( $where );
416
417
		$url = $this->is_network_admin() ? network_admin_url( 'admin.php?page=monsterinsights_network' ) : admin_url( 'admin.php?page=monsterinsights_settings' );
418
		$url = add_query_arg( array(
419
			'mi_action' => 'reauth',
420
			'success'   => 'true',
421
		), $url );
422
		$url = apply_filters( 'monsterinsights_reauth_success_redirect_url', $url );
423
424
		wp_safe_redirect( $url );
425
		exit;
0 ignored issues
show
Best Practice introduced by
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
426
	}
427
428
	public function maybe_verify() {
429
430
		// Check nonce
431
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
432
433
		// current user can verify
434
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
435
			// Translators: Link tag starts with url and link tag ends.
436
			$message = sprintf(
437
				__( 'You don\'t have the correct user permissions to verify the MonsterInsights license you are trying to use. Please check with your site administrator that your role is included in the MonsterInsights permissions settings. %1$sClick here for more information%2$s.', 'google-analytics-for-wordpress' ),
438
				'<a target="_blank" rel="noopener" href="' . monsterinsights_get_url( 'notice', 'cannot-save-settings', 'https://www.monsterinsights.com/docs/how-to-allow-user-roles-to-access-the-monsterinsights-reports-and-settings/' ) . '">',
439
				'</a>'
440
			);
441
			wp_send_json_error( array( 'message' => $message ) );
442
		}
443
444
		if ( ! empty( $_REQUEST['isnetwork'] ) && filter_var($_REQUEST['isnetwork'], FILTER_VALIDATE_BOOL) ) {
445
			define( 'WP_NETWORK_ADMIN', true );
446
		}
447
448
		// we have an auth to verify
449
		if ( $this->is_network_admin() && ! MonsterInsights()->auth->is_network_authed() ) {
450
			// Translators: Support Link tag starts with url and Support link tag ends.
451
			$message = sprintf(
452
				__( 'Please enter a valid license within the MonsterInsights settings panel. You can check your license by logging into your MonsterInsights account by %1$sclicking here%2$s.', 'google-analytics-for-wordpress' ),
453
				'<a target="_blank" rel="noopener" href="' . monsterinsights_get_url( 'notice', 'cannot-verify-license', 'https://www.monsterinsights.com/my-account/' ) . '">',
454
				'</a>'
455
			);
456
			wp_send_json_error( array( 'message' => $message ) );
457
		} else if ( ! $this->is_network_admin() && ! MonsterInsights()->auth->is_authed() ) {
458
			// Translators: Support Link tag starts with url and Support link tag ends.
459
			$message = sprintf(
460
				__( 'Please enter a valid license within the MonsterInsights settings panel. You can check your license by logging into your MonsterInsights account by %1$sclicking here%2$s.', 'google-analytics-for-wordpress' ),
461
				'<a target="_blank" rel="noopener" href="' . monsterinsights_get_url( 'notice', 'cannot-verify-license', 'https://www.monsterinsights.com/my-account/' ) . '">',
462
				'</a>'
463
			);
464
			wp_send_json_error( array( 'message' => $message ) );
465
		}
466
467
		if ( monsterinsights_is_pro_version() ) {
468
			$valid = is_network_admin() ? MonsterInsights()->license->is_network_licensed() : MonsterInsights()->license->is_site_licensed();
469
			if ( ! $valid ) {
470
				// Translators: Support Link tag starts with url and Support link tag ends.
471
				$message = sprintf(
472
					__( 'Please enter a valid license within the MonsterInsights settings panel. You can check your license by logging into your MonsterInsights account by %1$sclicking here%2$s.', 'google-analytics-for-wordpress' ),
473
					'<a target="_blank" rel="noopener" href="' . monsterinsights_get_url( 'notice', 'cannot-verify-license', 'https://www.monsterinsights.com/my-account/' ) . '">',
474
					'</a>'
475
				);
476
				wp_send_json_error( array( 'message' => $message ) );
477
			}
478
		}
479
480
		$worked = $this->verify_auth();
481
		if ( $worked && ! is_wp_error( $worked ) ) {
482
			wp_send_json_success( array( 'message' => __( "Successfully verified.", 'google-analytics-for-wordpress' ) ) );
483
		} else {
484
			// Translators: Support Link tag starts with url and Support link tag ends.
485
			$message = sprintf(
486
				__( 'Oops! There has been an error while trying to verify your license. Please try again or contact our support team by %1$sclicking here%2$s.', 'google-analytics-for-wordpress' ),
487
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-verify-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
488
				'</a>'
489
			);
490
			wp_send_json_error( array( 'message' => $message ) );
491
		}
492
	}
493
494
	public function verify_auth( $credentials = array() ) {
495
		$creds = ! empty( $credentials ) ? $credentials : ( $this->is_network_admin() ? MonsterInsights()->auth->get_network_analytics_profile( true ) : MonsterInsights()->auth->get_analytics_profile( true ) );
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
496
497
		if ( empty( $creds['key'] ) ) {
498
			// Translators: Support Link tag starts with url and Support link tag ends.
499
			$message = sprintf(
500
				__( 'Oops! There has been an error while trying to verify your license. Please try again or contact our support team by %1$sclicking here%2$s.', 'google-analytics-for-wordpress' ),
501
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-verify-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
502
				'</a>'
503
			);
504
505
			return new WP_Error( 'validation-error', $message );
506
		}
507
508
		$network = ! empty( $_REQUEST['network'] ) ? $_REQUEST['network'] === 'network' : $this->is_network_admin();
509
		$api     = new MonsterInsights_API_Request( $this->get_route( 'auth/verify/{type}/' ), array(
510
			'network' => $network,
511
			'tt'      => $this->get_tt(),
512
			'key'     => $creds['key'],
513
			'token'   => $creds['token'],
514
			'testurl' => 'https://' . monsterinsights_get_api_url() . 'test/'
515
		) );
516
		$ret     = $api->request();
517
518
		$this->rotate_tt();
519
		if ( is_wp_error( $ret ) ) {
520
			return $ret;
521
		} else {
522
			return true;
523
		}
524
	}
525
526
	public function maybe_delete() {
527
528
		// Check nonce
529
		check_ajax_referer( 'mi-admin-nonce', 'nonce' );
530
531
		$url = network_admin_url( 'admin.php?page=monsterinsights-onboarding' );
532
533
		// current user can delete
534
		if ( ! current_user_can( 'monsterinsights_save_settings' ) ) {
535
			// Translators: Link tag starts with url and link tag ends.
536
			$message = sprintf(
537
				__( 'You don\'t have the correct WordPress user permissions to deauthenticate into MonsterInsights. Please check with your site administrator that your role is included in the MonsterInsights permissions settings. %1$sClick here for more information%2$s.', 'google-analytics-for-wordpress' ),
538
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-save-settings', 'https://www.monsterinsights.com/docs/how-to-allow-user-roles-to-access-the-monsterinsights-reports-and-settings/' ) . '">',
539
				'</a>'
540
			);
541
			wp_send_json_error( array( 'message' => $message ) );
542
		}
543
544
		if ( ! empty( $_REQUEST['isnetwork'] ) && filter_var($_REQUEST['isnetwork'], FILTER_VALIDATE_BOOL) ) {
545
			define( 'WP_NETWORK_ADMIN', true );
546
		}
547
548
		// we have an auth to delete
549
		if ( $this->is_network_admin() && ! MonsterInsights()->auth->is_network_authed() ) {
550
			// Translators: Setup Wizard link tag starts, Setup Wizard link tag end, Support link tag starts with url and support link tag ends.
551
			$message = sprintf(
552
				__( 'Could not disconnect as you are not currently authenticated properly. Please try to authenticate again with our MonsterInsights %1$ssetup wizard%2$s.  If you are still having problems, please %3$scontact our support%4$s team.', 'google-analytics-for-wordpress' ),
553
				'<a href="' . esc_url( $url ) . '">',
554
				'</a>',
555
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-de-authenticate-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
556
				'</a>'
557
			);
558
			wp_send_json_error( array( 'message' => $message ) );
559
		} else if ( ! $this->is_network_admin() && ! MonsterInsights()->auth->is_authed() ) {
560
			// Translators: Setup Wizard link tag starts, Setup Wizard link tag end, Support link tag starts with url and support link tag ends.
561
			$message = sprintf(
562
				__( 'Could not disconnect as you are not currently authenticated properly. Please try to authenticate again with our MonsterInsights %1$ssetup wizard%2$s.  If you are still having problems, please %3$scontact our support%4$s team.', 'google-analytics-for-wordpress' ),
563
				'<a href="' . esc_url( $url ) . '">',
564
				'</a>',
565
				'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-de-authenticate-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
566
				'</a>'
567
			);
568
			wp_send_json_error( array( 'message' => $message ) );
569
		}
570
571
		if ( monsterinsights_is_pro_version() ) {
572
			$valid = is_network_admin() ? MonsterInsights()->license->is_network_licensed() : MonsterInsights()->license->is_site_licensed();
573
			if ( ! $valid ) {
574
				// Translators: Setup Wizard link tag starts, Setup Wizard link tag end, Support link tag starts with url and support link tag ends.
575
				$message = sprintf(
576
					__( 'Could not disconnect your account, as you are not currently authenticated properly. Please try to authenticate again with our %1$sMonsterInsights setup wizard%2$s.  If you are still having problems, please %3$scontact our support%4$s team.', 'google-analytics-for-wordpress' ),
577
					'<a href="' . esc_url( $url ) . '">',
578
					'</a>',
579
					'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-de-authenticate-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
580
					'</a>'
581
				);
582
				wp_send_json_error( array( 'message' => $message ) );
583
			}
584
		}
585
586
		$force = ! empty( $_REQUEST['forcedelete'] ) && $_REQUEST['forcedelete'] === 'true';
587
588
		$worked = $this->delete_auth( $force );
589
		if ( $worked && ! is_wp_error( $worked ) ) {
590
			wp_send_json_success( array( 'message' => __( "Successfully deauthenticated.", 'google-analytics-for-wordpress' ) ) );
591
		} else {
592
			if ( $force ) {
593
				wp_send_json_success( array( 'message' => __( "Successfully force deauthenticated.", 'google-analytics-for-wordpress' ) ) );
594
			} else {
595
				// Translators: Support link tag starts with url and support link tag ends.
596
				$message = sprintf(
597
					__( 'Oops! There has been an error while trying to deauthenticate. Please try again. If the issue persists, please %1$scontact our support%2$s team.', 'google-analytics-for-wordpress' ),
598
					'<a target="_blank" href="' . monsterinsights_get_url( 'notice', 'cannot-de-authenticate-license', 'https://www.monsterinsights.com/my-account/support/' ) . '">',
599
					'</a>'
600
				);
601
				wp_send_json_error( array( 'message' => $message ) );
602
			}
603
		}
604
	}
605
606
	public function delete_auth( $force = false ) {
607
		if ( $this->is_network_admin() && ! MonsterInsights()->auth->is_network_authed() ) {
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
608
			return false;
609
		} else if ( ! $this->is_network_admin() && ! MonsterInsights()->auth->is_authed() ) {
610
			return false;
611
		}
612
613
		$creds = $this->is_network_admin() ? MonsterInsights()->auth->get_network_analytics_profile( true ) : MonsterInsights()->auth->get_analytics_profile( true );
614
615
		if ( empty( $creds['key'] ) ) {
616
			return false;
617
		}
618
619
		// If we have a new siteurl enabled option and the profile site doesn't match the current site, deactivate anyways
620
		if ( is_network_admin() ) {
621
			$siteurl = network_admin_url();
622
			if ( ! empty( $creds['neturl'] ) && $creds['neturl'] !== $siteurl ) {
623
				MonsterInsights()->auth->delete_network_analytics_profile( true );
624
625
				return true;
626
			}
627
		} else {
628
			$siteurl = home_url();
629
			if ( ! empty( $creds['siteurl'] ) && $creds['siteurl'] !== $siteurl ) {
630
				MonsterInsights()->auth->delete_analytics_profile( true );
631
632
				return true;
633
			}
634
		}
635
636
		$api = new MonsterInsights_API_Request( $this->get_route( 'auth/delete/{type}/' ), array(
637
			'network' => $this->is_network_admin(),
638
			'tt'      => $this->get_tt(),
639
			'key'     => $creds['key'],
640
			'token'   => $creds['token'],
641
			'testurl' => 'https://' . monsterinsights_get_api_url() . 'test/'
642
		) );
643
		$ret = $api->request();
644
645
		$this->rotate_tt();
646
		if ( is_wp_error( $ret ) && ! $force ) {
647
			return false;
648
		} else {
649
			if ( $this->is_network_admin() ) {
650
				MonsterInsights()->auth->delete_network_analytics_profile( true );
651
			} else {
652
				MonsterInsights()->auth->delete_analytics_profile( true );
653
			}
654
655
			return true;
656
		}
657
	}
658
659
	/**
660
	 * Function to delete network auth in the uninstall process where we can't check if is network admin.
661
	 *
662
	 * @return bool
663
	 */
664
	public function uninstall_network_auth() {
665
666
		if ( ! MonsterInsights()->auth->is_network_authed() ) {
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
667
			return false;
668
		}
669
670
		$creds = MonsterInsights()->auth->get_network_analytics_profile( true );
671
672
		$api = new MonsterInsights_API_Request( $this->get_route( 'auth/delete/{type}/' ), array(
673
			'network' => true,
674
			'tt'      => $this->get_tt(),
675
			'key'     => $creds['key'],
676
			'token'   => $creds['token'],
677
			'testurl' => 'https://' . monsterinsights_get_api_url() . 'test/'
678
		) );
679
		// Force the network admin url otherwise this will fail not finding the url in relay.
680
		$api->site_url = network_admin_url();
0 ignored issues
show
Bug introduced by
The property site_url is declared protected in MonsterInsights_API_Request and cannot be accessed from this context.
Loading history...
681
		$ret           = $api->request();
682
683
		$this->rotate_tt();
684
		if ( is_wp_error( $ret ) ) {
685
			return false;
686
		} else {
687
			MonsterInsights()->auth->delete_network_analytics_profile( true );
688
689
			return true;
690
		}
691
	}
692
693
	public function get_type() {
694
		$base = monsterinsights_is_pro_version() ? 'pro' : 'lite';
695
696
		return apply_filters( 'monsterinsights_api_auth_get_type', $base );
697
	}
698
699
	public function get_route( $route = '' ) {
700
		$route = str_replace( '{type}', $this->get_type(), $route );
701
		$route = trailingslashit( $route );
702
703
		return $route;
704
	}
705
706
	public function is_network_admin() {
707
		return is_multisite() && is_network_admin();
708
	}
709
710
	public function get_sitei() {
711
		// $sitei = get_network_option(  get_current_network_id(), 'monsterinsights_network_sitei', false );
712
		// if ( ! empty( $sitei ) && strlen( $sitei ) >= 1 ) {
713
		// 	return $sitei;
714
		// }
715
716
		return monsterinsights_get_sitei();
717
	}
718
719
	/**
720
	 * Logic to run before serving the redirect url during auth.
721
	 *
722
	 * @param string $url
723
	 *
724
	 * @return string
725
	 */
726
	public function before_redirect( $url ) {
727
728
		// If Bad Behavior plugin is installed.
729
		if ( function_exists( 'bb2_read_settings' ) ) {
730
			// Make sure the offsite_forms option is enabled to allow auth.
731
			$bb_settings = get_option( 'bad_behavior_settings' );
732
			if ( empty( $bb_settings['offsite_forms'] ) || false === $bb_settings['offsite_forms'] ) {
733
				$bb_settings['offsite_forms'] = true;
734
				update_option( 'bad_behavior_settings', $bb_settings );
735
			}
736
		}
737
738
		return $url;
739
	}
740
741
	/**
742
	 * Delete auth-related options from the db - should be run at site level.
743
	 */
744
	public function uninstall_auth() {
745
		delete_option( 'monsterinsights_site_profile' );
746
		delete_option( 'monsterinsights_site_tt' );
747
	}
748
749
	/**
750
	 * Save the measurement protocol that Relay pushes to this site
751
	 */
752
	public function handle_relay_mp_token_push() {
753
		$mp_token  = sanitize_text_field( $_POST['mp_token'] ); // phpcs:ignore
754
		$timestamp = (int) sanitize_text_field( $_POST['timestamp'] ); // phpcs:ignore
755
		$signature = sanitize_text_field( $_POST['signature'] ); // phpcs:ignore
756
757
		// check if expired
758
		if ( time() > $timestamp + 1000 ) {
759
			wp_send_json_error( new WP_Error( 'monsterinsights_mp_token_timestamp_expired' ) );
760
		}
761
762
		// Check hashed signature
763
		$auth = MonsterInsights()->auth;
0 ignored issues
show
Bug Best Practice introduced by
The property $auth is declared protected in MonsterInsights_Lite. Since you implement __get, consider adding a @property or @property-read.
Loading history...
764
765
		$is_network = is_multisite();
766
		$public_key = $is_network
767
			? $auth->get_network_key()
768
			: $auth->get_key();
769
770
		$hashed_data = array(
771
			'mp_token'  => sanitize_text_field($_POST['mp_token']),
772
			'timestamp' => $timestamp,
773
		);
774
775
		// These `hash_` functions are polyfilled by WP in wp-includes/compat.php
776
		$expected_signature = hash_hmac( 'md5', http_build_query( $hashed_data ), $public_key );
777
		if ( ! hash_equals( $signature, $expected_signature ) ) {
778
			wp_send_json_error( new WP_Error( 'monsterinsights_mp_token_invalid_signature' ) );
779
		}
780
781
		// Save measurement protocol token
782
		if ( $is_network ) {
783
			$auth->set_network_measurement_protocol_secret( $mp_token );
784
		} else {
785
			$auth->set_measurement_protocol_secret( $mp_token );
786
		}
787
		wp_send_json_success();
788
	}
789
}
790