Completed
Push — fix/typo-pro-promo ( e5832e...fc698e )
by
unknown
29:20
created

_inc/class.jetpack-provision.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
class Jetpack_Provision {
3
	static function partner_provision( $access_token, $named_args ) {
4
		// first, verify the token
5
		$verify_response = self::verify_token( $access_token );
6
7
		if ( is_wp_error( $verify_response ) ) {
8
			return $verify_response;
9
		}
10
11
		$url_args = array(
12
			'home_url' => 'WP_HOME',
13
			'site_url' => 'WP_SITEURL',
14
		);
15
16
		foreach ( $url_args as $url_arg => $constant_name ) {
17
			// Anonymous functions were introduced in 5.3.0. So, if we're running on
18
			// >= 5.3.0, use an anonymous function to set the home/siteurl value%s.
19
			//
20
			// Otherwise, fallback to setting the home/siteurl value via the WP_HOME and
21
			// WP_SITEURL constants if the constant hasn't already been defined.
22
			if ( isset( $named_args[ $url_arg ] ) ) {
23
				if ( version_compare( phpversion(), '5.3.0', '>=') ) {
24
					add_filter( $url_arg, function( $url ) use ( $url_arg, $named_args ) {
25
						return $named_args[ $url_arg ];
26
					}, 11 );
27
				} else if ( ! defined( $constant_name ) ) {
28
					define( $constant_name, $named_args[ $url_arg ] );
29
				}
30
			}
31
		}
32
33
		// If Jetpack is currently connected, and is not in Safe Mode already, kick off a sync of the current
34
		// functions/callables so that we can test if this site is in IDC.
35
		if ( Jetpack::is_active() && ! Jetpack::validate_sync_error_idc_option() && Jetpack_Sync_Actions::sync_allowed() ) {
36
			Jetpack_Sync_Actions::do_full_sync( array( 'functions' => true ) );
37
			Jetpack_Sync_Actions::$sender->do_full_sync();
38
		}
39
40
		if ( Jetpack::validate_sync_error_idc_option() ) {
41
			return new WP_Error(
42
				'site_in_safe_mode',
43
				esc_html__( 'Can not provision a plan while in safe mode. See: https://jetpack.com/support/safe-mode/', 'jetpack' )
44
			);
45
		}
46
47
		$blog_id    = Jetpack_Options::get_option( 'id' );
48
		$blog_token = Jetpack_Options::get_option( 'blog_token' );
49
50
		if ( ! $blog_id || ! $blog_token || ( isset( $named_args['force_register'] ) && intval( $named_args['force_register'] ) ) ) {
51
			// this code mostly copied from Jetpack::admin_page_load
52
			Jetpack::maybe_set_version_option();
53
			$registered = Jetpack::try_registration();
54
			if ( is_wp_error( $registered ) ) {
55
				return $registered;
56
			} elseif ( ! $registered ) {
57
				return new WP_Error( 'registration_error', __( 'There was an unspecified error registering the site', 'jetpack' ) );
58
			}
59
60
			$blog_id    = Jetpack_Options::get_option( 'id' );
61
			$blog_token = Jetpack_Options::get_option( 'blog_token' );
62
		}
63
64
		// if the user isn't specified, but we have a current master user, then set that to current user
65
		if ( ! get_current_user_id() && $master_user_id = Jetpack_Options::get_option( 'master_user' ) ) {
66
			wp_set_current_user( $master_user_id );
67
		}
68
69
		$site_icon = ( function_exists( 'has_site_icon') && has_site_icon() )
70
			? get_site_icon_url()
71
			: false;
72
73
		$auto_enable_sso = ( ! Jetpack::is_active() || Jetpack::is_module_active( 'sso' ) );
74
75
		/** This filter is documented in class.jetpack-cli.php */
76
		if ( apply_filters( 'jetpack_start_enable_sso', $auto_enable_sso ) ) {
77
			$redirect_uri = add_query_arg(
78
				array( 'action' => 'jetpack-sso', 'redirect_to' => urlencode( admin_url() ) ),
79
				wp_login_url() // TODO: come back to Jetpack dashboard?
80
			);
81
		} else {
82
			$redirect_uri = admin_url();
83
		}
84
85
		$request_body = array(
86
			'jp_version'    => JETPACK__VERSION,
87
			'redirect_uri'  => $redirect_uri
88
		);
89
90
		if ( $site_icon ) {
91
			$request_body['site_icon'] = $site_icon;
92
		}
93
94
		if ( get_current_user_id() ) {
95
			$user = wp_get_current_user();
96
97
			// role
98
			$role = Jetpack::translate_current_user_to_role();
99
			$signed_role = Jetpack::sign_role( $role );
100
101
			$secrets = Jetpack::init()->generate_secrets( 'authorize' );
102
103
			// Jetpack auth stuff
104
			$request_body['scope']  = $signed_role;
105
			$request_body['secret'] = $secrets['secret_1'];
106
107
			// User stuff
108
			$request_body['user_id']    = $user->ID;
109
			$request_body['user_email'] = $user->user_email;
110
			$request_body['user_login'] = $user->user_login;
111
		}
112
113
		// optional additional params
114 View Code Duplication
		if ( isset( $named_args['wpcom_user_id'] ) && ! empty( $named_args['wpcom_user_id'] ) ) {
115
			$request_body['wpcom_user_id'] = $named_args['wpcom_user_id'];
116
		}
117
118
		// override email of selected user
119 View Code Duplication
		if ( isset( $named_args['wpcom_user_email'] ) && ! empty( $named_args['wpcom_user_email'] ) ) {
120
			$request_body['user_email'] = $named_args['wpcom_user_email'];
121
		}
122
123 View Code Duplication
		if ( isset( $named_args['plan'] ) && ! empty( $named_args['plan'] ) ) {
124
			$request_body['plan'] = $named_args['plan'];
125
		}
126
127 View Code Duplication
		if ( isset( $named_args['onboarding'] ) && ! empty( $named_args['onboarding'] ) ) {
128
			$request_body['onboarding'] = intval( $named_args['onboarding'] );
129
		}
130
131 View Code Duplication
		if ( isset( $named_args['force_connect'] ) && ! empty( $named_args['force_connect'] ) ) {
132
			$request_body['force_connect'] = intval( $named_args['force_connect'] );
133
		}
134
135
		if ( isset( $request_body['onboarding'] ) && (bool) $request_body['onboarding'] ) {
136
			Jetpack::create_onboarding_token();
137
		}
138
139
		$request = array(
140
			'headers' => array(
141
				'Authorization' => "Bearer " . $access_token,
142
				'Host'          => defined( 'JETPACK__WPCOM_JSON_API_HOST_HEADER' ) ? JETPACK__WPCOM_JSON_API_HOST_HEADER : 'public-api.wordpress.com',
143
			),
144
			'timeout' => 60,
145
			'method'  => 'POST',
146
			'body'    => json_encode( $request_body )
147
		);
148
149
		$url = sprintf( 'https://%s/rest/v1.3/jpphp/%d/partner-provision', self::get_api_host(), $blog_id );
150 View Code Duplication
		if ( ! empty( $named_args['partner_tracking_id'] ) ) {
151
			$url = esc_url_raw( add_query_arg( 'partner_tracking_id', $named_args['partner_tracking_id'], $url ) );
152
		}
153
154
		// add calypso env if set
155
		if ( getenv( 'CALYPSO_ENV' ) ) {
156
			$url = add_query_arg( array( 'calypso_env' => getenv( 'CALYPSO_ENV' ) ), $url );
157
		}
158
159
		$result = Jetpack_Client::_wp_remote_request( $url, $request );
160
161
		if ( is_wp_error( $result ) ) {
162
			return $result;
163
		}
164
165
		$response_code = wp_remote_retrieve_response_code( $result );
166
		$body_json     = json_decode( wp_remote_retrieve_body( $result ) );
167
168 View Code Duplication
		if( 200 !== $response_code ) {
169
			if ( isset( $body_json->error ) ) {
170
				return new WP_Error( $body_json->error, $body_json->message );
171
			} else {
172
				return new WP_Error( 'server_error', sprintf( __( "Request failed with code %s" ), $response_code ) );
173
			}
174
		}
175
176
		if ( isset( $body_json->access_token ) ) {
177
			// check if this matches the existing token before replacing
178
			$existing_token = Jetpack_Data::get_access_token( $user->ID );
0 ignored issues
show
The variable $user does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
179
			if ( empty( $existing_token ) || $existing_token->secret !== $body_json->access_token ) {
180
				self::authorize_user( $user->ID, $body_json->access_token );
181
			}
182
		}
183
184
		return $body_json;
185
	}
186
187
	private static function authorize_user( $user_id, $access_token ) {
188
		// authorize user and enable SSO
189
		Jetpack::update_user_token( $user_id, sprintf( '%s.%d', $access_token, $user_id ), true );
190
191
		/**
192
		 * Auto-enable SSO module for new Jetpack Start connections
193
		 *
194
		 * @since 5.0.0
195
		 *
196
		 * @param bool $enable_sso Whether to enable the SSO module. Default to true.
197
		 */
198
		$other_modules = apply_filters( 'jetpack_start_enable_sso', true )
199
			? array( 'sso' )
200
			: array();
201
202 View Code Duplication
		if ( $active_modules = Jetpack_Options::get_option( 'active_modules' ) ) {
203
			Jetpack::delete_active_modules();
204
			Jetpack::activate_default_modules( 999, 1, array_merge( $active_modules, $other_modules ), false );
205
		} else {
206
			Jetpack::activate_default_modules( false, false, $other_modules, false );
207
		}
208
	}
209
210
	private static function verify_token( $access_token ) {
211
		$request = array(
212
			'headers' => array(
213
				'Authorization' => "Bearer " . $access_token,
214
				'Host'          => defined( 'JETPACK__WPCOM_JSON_API_HOST_HEADER' ) ? JETPACK__WPCOM_JSON_API_HOST_HEADER : 'public-api.wordpress.com',
215
			),
216
			'timeout' => 10,
217
			'method'  => 'POST',
218
			'body'    => ''
219
		);
220
221
		$url = sprintf( 'https://%s/rest/v1.3/jpphp/partner-keys/verify', self::get_api_host() );
222
		$result = Jetpack_Client::_wp_remote_request( $url, $request );
223
224
		if ( is_wp_error( $result ) ) {
225
			return $result;
226
		}
227
228
		$response_code = wp_remote_retrieve_response_code( $result );
229
		$body_json     = json_decode( wp_remote_retrieve_body( $result ) );
230
231 View Code Duplication
		if( 200 !== $response_code ) {
232
			if ( isset( $body_json->error ) ) {
233
				return new WP_Error( $body_json->error, $body_json->message );
234
			} else {
235
				return new WP_Error( 'server_error', sprintf( __( "Request failed with code %s" ), $response_code ) );
236
			}
237
		}
238
239
		return true;
240
	}
241
242
	private static function get_api_host() {
243
		$env_api_host = getenv( 'JETPACK_START_API_HOST', true );
244
		return $env_api_host ? $env_api_host : JETPACK__WPCOM_JSON_API_HOST;
245
	}
246
}
247