Completed
Push — changelog/76 ( 041739...62986d )
by Jeremy
24:19 queued 16:33
created

Jetpack_Client_Server::get_token()   F

Complexity

Conditions 22
Paths 94

Size

Total Lines 107

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 22
nc 94
nop 1
dl 0
loc 107
rs 3.3333
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
use Automattic\Jetpack\Connection\Client;
4
use Automattic\Jetpack\Roles;
5
use Automattic\Jetpack\Tracking;
6
7
/**
8
 * Client = Plugin
9
 * Client Server = API Methods the Plugin must respond to
10
 */
11
class Jetpack_Client_Server {
12
13
	/**
14
	 * Authorizations
15
	 */
16
	function client_authorize() {
17
		$data              = stripslashes_deep( $_GET );
18
		$data['auth_type'] = 'client';
19
		$roles             = new Roles();
20
		$role              = $roles->translate_current_user_to_role();
21
		$redirect          = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
22
23
		check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" );
24
25
		$tracking = new Tracking();
26
		$result = $this->authorize( $data );
27
		if ( is_wp_error( $result ) ) {
28
			Jetpack::state( 'error', $result->get_error_code() );
0 ignored issues
show
Bug introduced by
The method get_error_code() does not seem to exist on object<Jetpack_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
29
30
			$tracking->record_user_event( 'jpc_client_authorize_fail', array(
31
				'error_code' => $result->get_error_code(),
0 ignored issues
show
Bug introduced by
The method get_error_code() does not seem to exist on object<Jetpack_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
32
				'error_message' => $result->get_error_message()
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<Jetpack_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
33
			) );
34
		} else {
35
			/**
36
			 * Fires after the Jetpack client is authorized to communicate with WordPress.com.
37
			 *
38
			 * @since 4.2.0
39
			 *
40
			 * @param int Jetpack Blog ID.
41
			 */
42
			do_action( 'jetpack_client_authorized', Jetpack_Options::get_option( 'id' ) );
43
		}
44
45
		if ( wp_validate_redirect( $redirect ) ) {
46
			// Exit happens below in $this->do_exit()
47
			wp_safe_redirect( $redirect );
48
		} else {
49
			// Exit happens below in $this->do_exit()
50
			wp_safe_redirect( Jetpack::admin_url() );
51
		}
52
53
		$tracking->record_user_event( 'jpc_client_authorize_success' );
54
55
		$this->do_exit();
56
	}
57
58
	function authorize( $data = array() ) {
59
		$redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
0 ignored issues
show
Unused Code introduced by
$redirect is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
60
61
		$jetpack_unique_connection = Jetpack_Options::get_option( 'unique_connection' );
62
		// Checking if site has been active/connected previously before recording unique connection
63
		if ( ! $jetpack_unique_connection ) {
64
			// jetpack_unique_connection option has never been set
65
			$jetpack_unique_connection = array(
66
				'connected'     => 0,
67
				'disconnected'  => 0,
68
				'version'       => '3.6.1',
69
			);
70
71
			update_option( 'jetpack_unique_connection', $jetpack_unique_connection );
72
73
			//track unique connection
74
			$jetpack = $this->get_jetpack();
75
76
			$jetpack->stat( 'connections', 'unique-connection' );
77
			$jetpack->do_stats( 'server_side' );
78
		}
79
80
		// increment number of times connected
81
		$jetpack_unique_connection['connected'] += 1;
82
		Jetpack_Options::update_option( 'unique_connection', $jetpack_unique_connection );
83
84
		$roles = new Roles();
85
		$role  = $roles->translate_current_user_to_role();
86
87
		if ( ! $role ) {
88
			return new Jetpack_Error( 'no_role', 'Invalid request.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'no_role'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
89
		}
90
91
		$cap = $roles->translate_role_to_cap( $role );
92
		if ( ! $cap ) {
93
			return new Jetpack_Error( 'no_cap', 'Invalid request.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'no_cap'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
94
		}
95
96
		if ( ! empty( $data['error'] ) ) {
97
			return new Jetpack_Error( $data['error'], 'Error included in the request.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with $data['error'].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
98
		}
99
100
		if ( ! isset( $data['state'] ) ) {
101
			return new Jetpack_Error( 'no_state', 'Request must include state.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'no_state'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
102
		}
103
104
		if ( ! ctype_digit( $data['state'] ) ) {
105
			return new Jetpack_Error( $data['error'], 'State must be an integer.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with $data['error'].

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
106
		}
107
108
		$current_user_id = get_current_user_id();
109
		if ( $current_user_id != $data['state'] ) {
110
			return new Jetpack_Error( 'wrong_state', 'State does not match current user.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'wrong_state'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
111
		}
112
113
		if ( empty( $data['code'] ) ) {
114
			return new Jetpack_Error( 'no_code', 'Request must include an authorization code.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'no_code'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
115
		}
116
117
		$token = $this->get_token( $data );
118
119 View Code Duplication
		if ( is_wp_error( $token ) ) {
120
			$code = $token->get_error_code();
0 ignored issues
show
Bug introduced by
The method get_error_code() does not seem to exist on object<Jetpack_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
121
			if ( empty( $code ) ) {
122
				$code = 'invalid_token';
123
			}
124
			return new Jetpack_Error( $code, $token->get_error_message(), 400 );
0 ignored issues
show
Bug introduced by
The method get_error_message() does not seem to exist on object<Jetpack_Error>.

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with $code.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
125
		}
126
127
		if ( ! $token ) {
128
			return new Jetpack_Error( 'no_token', 'Error generating token.', 400 );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'no_token'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
129
		}
130
131
		$is_master_user = ! Jetpack::is_active();
132
133
		Jetpack::update_user_token( $current_user_id, sprintf( '%s.%d', $token, $current_user_id ), $is_master_user );
134
135
		if ( ! $is_master_user ) {
136
			Jetpack::state( 'message', 'linked' );
137
			// Don't activate anything since we are just connecting a user.
138
			return 'linked';
139
		}
140
141
		// If this site has been through the Jetpack Onboarding flow, delete the onboarding token
142
		Jetpack::invalidate_onboarding_token();
143
144
		// If redirect_uri is SSO, ensure SSO module is enabled
145
		parse_str( parse_url( $data['redirect_uri'], PHP_URL_QUERY ), $redirect_options );
146
147
		/** This filter is documented in class.jetpack-cli.php */
148
		$jetpack_start_enable_sso = apply_filters( 'jetpack_start_enable_sso', true );
149
150
		$activate_sso = (
151
			isset( $redirect_options['action'] ) &&
152
			'jetpack-sso' === $redirect_options['action'] &&
153
			$jetpack_start_enable_sso
154
		);
155
156
		$do_redirect_on_error = ( 'client' === $data['auth_type'] );
157
158
		Jetpack::handle_post_authorization_actions( $activate_sso, $do_redirect_on_error );
159
160
		return 'authorized';
161
	}
162
163
	public static function deactivate_plugin( $probable_file, $probable_title ) {
164
		include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
165
		if ( is_plugin_active( $probable_file ) ) {
166
			deactivate_plugins( $probable_file );
167
			return 1;
168
		} else {
169
			// If the plugin is not in the usual place, try looking through all active plugins.
170
			$active_plugins = Jetpack::get_active_plugins();
171
			foreach ( $active_plugins as $plugin ) {
172
				$data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
173
				if ( $data['Name'] == $probable_title ) {
174
					deactivate_plugins( $plugin );
175
					return 1;
176
				}
177
			}
178
		}
179
180
		return 0;
181
	}
182
183
	/**
184
	 * @return object|WP_Error
185
	 */
186
	function get_token( $data ) {
187
		$roles = new Roles();
188
		$role  = $roles->translate_current_user_to_role();
189
190
		if ( ! $role ) {
191
			return new Jetpack_Error( 'role', __( 'An administrator for this blog must set up the Jetpack connection.', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'role'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
192
		}
193
194
		$client_secret = Jetpack_Data::get_access_token();
0 ignored issues
show
Deprecated Code introduced by
The method Jetpack_Data::get_access_token() has been deprecated with message: 7.5 Use Connection_Manager instead.

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
195
		if ( ! $client_secret ) {
196
			return new Jetpack_Error( 'client_secret', __( 'You need to register your Jetpack before connecting it.', 'jetpack' ) );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'client_secret'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
197
		}
198
199
		$redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : '';
200
		$redirect_uri = ( 'calypso' === $data['auth_type'] )
201
			? $data['redirect_uri']
202
			: add_query_arg( array(
203
				'action' => 'authorize',
204
				'_wpnonce' => wp_create_nonce( "jetpack-authorize_{$role}_{$redirect}" ),
205
				'redirect' => $redirect ? urlencode( $redirect ) : false,
206
			), menu_page_url( 'jetpack', false ) );
207
208
		// inject identity for analytics
209
		$tracks = new Automattic\Jetpack\Tracking();
210
		$tracks_identity = $tracks->tracks_get_identity( get_current_user_id() );
211
212
		$body = array(
213
			'client_id' => Jetpack_Options::get_option( 'id' ),
214
			'client_secret' => $client_secret->secret,
215
			'grant_type' => 'authorization_code',
216
			'code' => $data['code'],
217
			'redirect_uri' => $redirect_uri,
218
			'_ui' => $tracks_identity['_ui'],
219
			'_ut' => $tracks_identity['_ut'],
220
		);
221
222
		$args = array(
223
			'method' => 'POST',
224
			'body' => $body,
225
			'headers' => array(
226
				'Accept' => 'application/json',
227
			),
228
		);
229
		$response = Client::_wp_remote_request( Jetpack::fix_url_for_bad_hosts( Jetpack::api_url( 'token' ) ), $args );
230
231
		if ( is_wp_error( $response ) ) {
232
			return new Jetpack_Error( 'token_http_request_failed', $response->get_error_message() );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'token_http_request_failed'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
233
		}
234
235
		$code = wp_remote_retrieve_response_code( $response );
236
		$entity = wp_remote_retrieve_body( $response );
237
238
		if ( $entity ) {
239
			$json = json_decode( $entity );
240
		} else {
241
			$json = false;
242
		}
243
244
		if ( 200 != $code || ! empty( $json->error ) ) {
245
			if ( empty( $json->error ) ) {
246
				return new Jetpack_Error( 'unknown', '', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'unknown'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
247
			}
248
249
			$error_description = isset( $json->error_description ) ? sprintf( __( 'Error Details: %s', 'jetpack' ), (string) $json->error_description ) : '';
250
251
			return new Jetpack_Error( (string) $json->error, $error_description, $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with (string) $json->error.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
252
		}
253
254
		if ( empty( $json->access_token ) || ! is_scalar( $json->access_token ) ) {
255
			return new Jetpack_Error( 'access_token', '', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'access_token'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
256
		}
257
258
		if ( empty( $json->token_type ) || 'X_JETPACK' != strtoupper( $json->token_type ) ) {
259
			return new Jetpack_Error( 'token_type', '', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'token_type'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
260
		}
261
262
		if ( empty( $json->scope ) ) {
263
			return new Jetpack_Error( 'scope', 'No Scope', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'scope'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
264
		}
265
266
		@list( $role, $hmac ) = explode( ':', $json->scope );
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
267
		if ( empty( $role ) || empty( $hmac ) ) {
268
			return new Jetpack_Error( 'scope', 'Malformed Scope', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'scope'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
269
		}
270
271
		if ( Jetpack::sign_role( $role ) !== $json->scope ) {
272
			return new Jetpack_Error( 'scope', 'Invalid Scope', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'scope'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
273
		}
274
275
		$cap = $roles->translate_role_to_cap( $role );
276
		if ( ! $cap ) {
277
			return new Jetpack_Error( 'scope', 'No Cap', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'scope'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
278
		}
279
280
		if ( ! current_user_can( $cap ) ) {
281
			return new Jetpack_Error( 'scope', 'current_user_cannot', $code );
0 ignored issues
show
Unused Code introduced by
The call to Jetpack_Error::__construct() has too many arguments starting with 'scope'.

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.

In this case you can add the @ignore PhpDoc annotation to the duplicate definition and it will be ignored.

Loading history...
282
		}
283
284
		/**
285
		 * Fires after user has successfully received an auth token.
286
		 *
287
		 * @since 3.9.0
288
		 */
289
		do_action( 'jetpack_user_authorized' );
290
291
		return (string) $json->access_token;
292
	}
293
294
	public function get_jetpack() {
295
		return Jetpack::init();
296
	}
297
298
	public function do_exit() {
299
		exit;
300
	}
301
}
302