These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | use Automattic\Jetpack\Connection\Client; |
||
4 | use Automattic\Jetpack\Connection\Utils as Connection_Utils; |
||
5 | use Automattic\Jetpack\Roles; |
||
6 | use Automattic\Jetpack\Tracking; |
||
7 | |||
8 | /** |
||
9 | * Client = Plugin |
||
10 | * Client Server = API Methods the Plugin must respond to |
||
11 | */ |
||
12 | class Jetpack_Client_Server { |
||
13 | |||
14 | /** |
||
15 | * Authorizations |
||
16 | */ |
||
17 | function client_authorize() { |
||
18 | $data = stripslashes_deep( $_GET ); |
||
19 | $data['auth_type'] = 'client'; |
||
20 | $roles = new Roles(); |
||
21 | $role = $roles->translate_current_user_to_role(); |
||
22 | $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : ''; |
||
23 | |||
24 | check_admin_referer( "jetpack-authorize_{$role}_{$redirect}" ); |
||
25 | |||
26 | $tracking = new Tracking(); |
||
27 | $result = $this->authorize( $data ); |
||
28 | if ( is_wp_error( $result ) ) { |
||
29 | Jetpack::state( 'error', $result->get_error_code() ); |
||
30 | |||
31 | $tracking->record_user_event( |
||
32 | 'jpc_client_authorize_fail', |
||
33 | array( |
||
34 | 'error_code' => $result->get_error_code(), |
||
35 | 'error_message' => $result->get_error_message(), |
||
36 | ) |
||
37 | ); |
||
38 | } else { |
||
39 | /** |
||
40 | * Fires after the Jetpack client is authorized to communicate with WordPress.com. |
||
41 | * |
||
42 | * @since 4.2.0 |
||
43 | * |
||
44 | * @param int Jetpack Blog ID. |
||
45 | */ |
||
46 | do_action( 'jetpack_client_authorized', Jetpack_Options::get_option( 'id' ) ); |
||
47 | } |
||
48 | |||
49 | if ( wp_validate_redirect( $redirect ) ) { |
||
50 | // Exit happens below in $this->do_exit() |
||
51 | wp_safe_redirect( $redirect ); |
||
52 | } else { |
||
53 | // Exit happens below in $this->do_exit() |
||
54 | wp_safe_redirect( Jetpack::admin_url() ); |
||
55 | } |
||
56 | |||
57 | $tracking->record_user_event( 'jpc_client_authorize_success' ); |
||
58 | |||
59 | $this->do_exit(); |
||
60 | } |
||
61 | |||
62 | function authorize( $data = array() ) { |
||
63 | $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : ''; |
||
64 | |||
65 | $jetpack_unique_connection = Jetpack_Options::get_option( 'unique_connection' ); |
||
66 | // Checking if site has been active/connected previously before recording unique connection |
||
67 | if ( ! $jetpack_unique_connection ) { |
||
68 | // jetpack_unique_connection option has never been set |
||
69 | $jetpack_unique_connection = array( |
||
70 | 'connected' => 0, |
||
71 | 'disconnected' => 0, |
||
72 | 'version' => '3.6.1', |
||
73 | ); |
||
74 | |||
75 | update_option( 'jetpack_unique_connection', $jetpack_unique_connection ); |
||
76 | |||
77 | // track unique connection |
||
78 | $jetpack = $this->get_jetpack(); |
||
79 | |||
80 | $jetpack->stat( 'connections', 'unique-connection' ); |
||
81 | $jetpack->do_stats( 'server_side' ); |
||
82 | } |
||
83 | |||
84 | // increment number of times connected |
||
85 | $jetpack_unique_connection['connected'] += 1; |
||
86 | Jetpack_Options::update_option( 'unique_connection', $jetpack_unique_connection ); |
||
87 | |||
88 | $roles = new Roles(); |
||
89 | $role = $roles->translate_current_user_to_role(); |
||
90 | |||
91 | if ( ! $role ) { |
||
92 | return new Jetpack_Error( 'no_role', 'Invalid request.', 400 ); |
||
93 | } |
||
94 | |||
95 | $cap = $roles->translate_role_to_cap( $role ); |
||
96 | if ( ! $cap ) { |
||
97 | return new Jetpack_Error( 'no_cap', 'Invalid request.', 400 ); |
||
98 | } |
||
99 | |||
100 | if ( ! empty( $data['error'] ) ) { |
||
101 | return new Jetpack_Error( $data['error'], 'Error included in the request.', 400 ); |
||
102 | } |
||
103 | |||
104 | if ( ! isset( $data['state'] ) ) { |
||
105 | return new Jetpack_Error( 'no_state', 'Request must include state.', 400 ); |
||
106 | } |
||
107 | |||
108 | if ( ! ctype_digit( $data['state'] ) ) { |
||
109 | return new Jetpack_Error( $data['error'], 'State must be an integer.', 400 ); |
||
110 | } |
||
111 | |||
112 | $current_user_id = get_current_user_id(); |
||
113 | if ( $current_user_id != $data['state'] ) { |
||
114 | return new Jetpack_Error( 'wrong_state', 'State does not match current user.', 400 ); |
||
115 | } |
||
116 | |||
117 | if ( empty( $data['code'] ) ) { |
||
118 | return new Jetpack_Error( 'no_code', 'Request must include an authorization code.', 400 ); |
||
119 | } |
||
120 | |||
121 | $token = $this->get_token( $data ); |
||
122 | |||
123 | View Code Duplication | if ( is_wp_error( $token ) ) { |
|
124 | $code = $token->get_error_code(); |
||
0 ignored issues
–
show
|
|||
125 | if ( empty( $code ) ) { |
||
126 | $code = 'invalid_token'; |
||
127 | } |
||
128 | return new Jetpack_Error( $code, $token->get_error_message(), 400 ); |
||
0 ignored issues
–
show
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. ![]() |
|||
129 | } |
||
130 | |||
131 | if ( ! $token ) { |
||
132 | return new Jetpack_Error( 'no_token', 'Error generating token.', 400 ); |
||
133 | } |
||
134 | |||
135 | $is_master_user = ! Jetpack::is_active(); |
||
136 | |||
137 | Connection_Utils::update_user_token( $current_user_id, sprintf( '%s.%d', $token, $current_user_id ), $is_master_user ); |
||
138 | |||
139 | if ( ! $is_master_user ) { |
||
140 | Jetpack::state( 'message', 'linked' ); |
||
141 | // Don't activate anything since we are just connecting a user. |
||
142 | return 'linked'; |
||
143 | } |
||
144 | |||
145 | // If this site has been through the Jetpack Onboarding flow, delete the onboarding token |
||
146 | Jetpack::invalidate_onboarding_token(); |
||
147 | |||
148 | // If redirect_uri is SSO, ensure SSO module is enabled |
||
149 | parse_str( wp_parse_url( $data['redirect_uri'], PHP_URL_QUERY ), $redirect_options ); |
||
150 | |||
151 | /** This filter is documented in class.jetpack-cli.php */ |
||
152 | $jetpack_start_enable_sso = apply_filters( 'jetpack_start_enable_sso', true ); |
||
153 | |||
154 | $activate_sso = ( |
||
155 | isset( $redirect_options['action'] ) && |
||
156 | 'jetpack-sso' === $redirect_options['action'] && |
||
157 | $jetpack_start_enable_sso |
||
158 | ); |
||
159 | |||
160 | $do_redirect_on_error = ( 'client' === $data['auth_type'] ); |
||
161 | |||
162 | Jetpack::handle_post_authorization_actions( $activate_sso, $do_redirect_on_error ); |
||
163 | |||
164 | return 'authorized'; |
||
165 | } |
||
166 | |||
167 | public static function deactivate_plugin( $probable_file, $probable_title ) { |
||
168 | include_once ABSPATH . 'wp-admin/includes/plugin.php'; |
||
169 | if ( is_plugin_active( $probable_file ) ) { |
||
170 | deactivate_plugins( $probable_file ); |
||
171 | return 1; |
||
172 | } else { |
||
173 | // If the plugin is not in the usual place, try looking through all active plugins. |
||
174 | $active_plugins = Jetpack::get_active_plugins(); |
||
175 | foreach ( $active_plugins as $plugin ) { |
||
176 | $data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin ); |
||
177 | if ( $data['Name'] == $probable_title ) { |
||
178 | deactivate_plugins( $plugin ); |
||
179 | return 1; |
||
180 | } |
||
181 | } |
||
182 | } |
||
183 | |||
184 | return 0; |
||
185 | } |
||
186 | |||
187 | /** |
||
188 | * @return object|WP_Error |
||
189 | */ |
||
190 | function get_token( $data ) { |
||
191 | $roles = new Roles(); |
||
192 | $role = $roles->translate_current_user_to_role(); |
||
193 | |||
194 | if ( ! $role ) { |
||
195 | return new Jetpack_Error( 'role', __( 'An administrator for this blog must set up the Jetpack connection.', 'jetpack' ) ); |
||
0 ignored issues
–
show
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 ![]() |
|||
196 | } |
||
197 | |||
198 | $client_secret = Jetpack_Data::get_access_token(); |
||
0 ignored issues
–
show
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. ![]() |
|||
199 | if ( ! $client_secret ) { |
||
200 | return new Jetpack_Error( 'client_secret', __( 'You need to register your Jetpack before connecting it.', 'jetpack' ) ); |
||
0 ignored issues
–
show
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 ![]() |
|||
201 | } |
||
202 | |||
203 | $redirect = isset( $data['redirect'] ) ? esc_url_raw( (string) $data['redirect'] ) : ''; |
||
204 | $redirect_uri = ( 'calypso' === $data['auth_type'] ) |
||
205 | ? $data['redirect_uri'] |
||
206 | : add_query_arg( |
||
207 | array( |
||
208 | 'action' => 'authorize', |
||
209 | '_wpnonce' => wp_create_nonce( "jetpack-authorize_{$role}_{$redirect}" ), |
||
210 | 'redirect' => $redirect ? urlencode( $redirect ) : false, |
||
211 | ), |
||
212 | menu_page_url( 'jetpack', false ) |
||
213 | ); |
||
214 | |||
215 | // inject identity for analytics |
||
216 | $tracks = new Automattic\Jetpack\Tracking(); |
||
217 | $tracks_identity = $tracks->tracks_get_identity( get_current_user_id() ); |
||
218 | |||
219 | $body = array( |
||
220 | 'client_id' => Jetpack_Options::get_option( 'id' ), |
||
221 | 'client_secret' => $client_secret->secret, |
||
222 | 'grant_type' => 'authorization_code', |
||
223 | 'code' => $data['code'], |
||
224 | 'redirect_uri' => $redirect_uri, |
||
225 | '_ui' => $tracks_identity['_ui'], |
||
226 | '_ut' => $tracks_identity['_ut'], |
||
227 | ); |
||
228 | |||
229 | $args = array( |
||
230 | 'method' => 'POST', |
||
231 | 'body' => $body, |
||
232 | 'headers' => array( |
||
233 | 'Accept' => 'application/json', |
||
234 | ), |
||
235 | ); |
||
236 | $response = Client::_wp_remote_request( Connection_Utils::fix_url_for_bad_hosts( Jetpack::connection()->api_url( 'token' ) ), $args ); |
||
237 | |||
238 | if ( is_wp_error( $response ) ) { |
||
239 | return new Jetpack_Error( 'token_http_request_failed', $response->get_error_message() ); |
||
0 ignored issues
–
show
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 ![]() |
|||
240 | } |
||
241 | |||
242 | $code = wp_remote_retrieve_response_code( $response ); |
||
243 | $entity = wp_remote_retrieve_body( $response ); |
||
244 | |||
245 | if ( $entity ) { |
||
246 | $json = json_decode( $entity ); |
||
247 | } else { |
||
248 | $json = false; |
||
249 | } |
||
250 | |||
251 | if ( 200 != $code || ! empty( $json->error ) ) { |
||
252 | if ( empty( $json->error ) ) { |
||
253 | return new Jetpack_Error( 'unknown', '', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
254 | } |
||
255 | |||
256 | $error_description = isset( $json->error_description ) ? sprintf( __( 'Error Details: %s', 'jetpack' ), (string) $json->error_description ) : ''; |
||
257 | |||
258 | return new Jetpack_Error( (string) $json->error, $error_description, $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
259 | } |
||
260 | |||
261 | if ( empty( $json->access_token ) || ! is_scalar( $json->access_token ) ) { |
||
262 | return new Jetpack_Error( 'access_token', '', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
263 | } |
||
264 | |||
265 | if ( empty( $json->token_type ) || 'X_JETPACK' != strtoupper( $json->token_type ) ) { |
||
266 | return new Jetpack_Error( 'token_type', '', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
267 | } |
||
268 | |||
269 | if ( empty( $json->scope ) ) { |
||
270 | return new Jetpack_Error( 'scope', 'No Scope', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
271 | } |
||
272 | |||
273 | @list( $role, $hmac ) = explode( ':', $json->scope ); |
||
0 ignored issues
–
show
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.');
}
![]() |
|||
274 | if ( empty( $role ) || empty( $hmac ) ) { |
||
275 | return new Jetpack_Error( 'scope', 'Malformed Scope', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
276 | } |
||
277 | |||
278 | if ( Jetpack::connection()->sign_role( $role ) !== $json->scope ) { |
||
279 | return new Jetpack_Error( 'scope', 'Invalid Scope', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
280 | } |
||
281 | |||
282 | $cap = $roles->translate_role_to_cap( $role ); |
||
283 | if ( ! $cap ) { |
||
284 | return new Jetpack_Error( 'scope', 'No Cap', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
285 | } |
||
286 | |||
287 | if ( ! current_user_can( $cap ) ) { |
||
288 | return new Jetpack_Error( 'scope', 'current_user_cannot', $code ); |
||
0 ignored issues
–
show
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 ![]() |
|||
289 | } |
||
290 | |||
291 | /** |
||
292 | * Fires after user has successfully received an auth token. |
||
293 | * |
||
294 | * @since 3.9.0 |
||
295 | */ |
||
296 | do_action( 'jetpack_user_authorized' ); |
||
297 | |||
298 | return (string) $json->access_token; |
||
299 | } |
||
300 | |||
301 | public function get_jetpack() { |
||
302 | return Jetpack::init(); |
||
303 | } |
||
304 | |||
305 | public function do_exit() { |
||
306 | exit; |
||
307 | } |
||
308 | } |
||
309 |
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.