PluginProbe ʕ •ᴥ•ʔ
Jetpack – WP Security, Backup, Speed, & Growth / 16.2-a.1
Jetpack – WP Security, Backup, Speed, & Growth v16.2-a.1
16.1.2 16.2-a.1 16.1.1 16.1 16.1-beta 16.1-beta.2 16.1-beta.3 16.1-a.5 16.1-a.3 16.0.1 16.1-a.1 16.0 16.0-beta 16.0-a.7 16.0-a.5 15.9.1 16.0-a.3 16.0-a.1 15.9 15.9-beta 15.9-a.7 15.9-a.5 15.9-a.3 15.9-a.1 15.8 15.8-beta 15.8-a.7 15.8-a.5 5.2.5 5.3.4 5.4.4 5.5.5 5.6.5 5.7.5 5.8.4 5.9.4 6.0.4 6.1 6.1.1 6.1.2 6.1.3 6.1.4 6.1.5 6.2 6.2.1 6.2.2 6.2.3 6.2.4 6.2.5 6.3 6.3.1 6.3.2 6.3.3 6.3.4 6.3.5 6.3.6 6.3.7 6.4 6.4.1 6.4.2 6.4.3 6.4.4 6.4.5 6.4.6 6.5 6.5.1 6.5.2 6.5.3 6.5.4 6.6 6.6.1 6.6.2 6.6.3 6.6.4 6.6.5 6.7 6.7.1 6.7.2 6.7.3 6.7.4 6.8 6.8.1 6.8.2 6.8.3 6.8.4 6.8.5 6.9 6.9.1 6.9.2 6.9.3 6.9.4 7.0 7.0.1 7.0.2 7.0.3 7.0.4 7.0.5 7.1 7.1.1 7.1.2 7.1.3 7.1.4 7.1.5 7.2 7.2.1 7.2.1.1 7.2.2 7.2.3 7.2.4 7.2.5 7.3 7.3.0.1 7.3.1 7.3.1.1 7.3.2 7.3.3 7.3.4 7.3.5 7.4 7.4.1 7.4.2 7.4.3 7.4.4 7.4.5 7.5 7.5.0.1 7.5.1 7.5.2 7.5.3 7.5.4 7.5.5 7.5.6 7.5.7 7.6 7.6.1 7.6.2 7.6.3 7.6.4 7.7 7.7.1 7.7.2 7.7.3 7.7.4 7.7.5 7.7.6 7.8 7.8.1 7.8.2 7.8.3 7.8.4 7.9 7.9.1 7.9.2 7.9.3 7.9.4 8.0 8.0.1 8.0.2 8.0.3 8.1 8.1.1 8.1.2 8.1.3 8.1.4 8.2 8.2.0.1 8.2.1 8.2.2 8.2.3 8.2.4 8.2.5 8.2.6 8.3 8.3.1 8.3.2 8.3.3 8.4 8.4.1 8.4.2 8.4.3 8.4.4 8.4.5 8.5 8.5.1 8.5.2 8.5.3 8.6 8.6.1 8.6.2 8.6.3 8.6.4 8.7 8.7.0.1 8.7.1 8.7.2 8.7.3 8.7.4 8.8 8.8.1 8.8.2 8.8.3 8.8.4 8.8.5 8.9 8.9.1 8.9.2 8.9.3 8.9.4 9.0 9.0.1 9.0.2 9.0.3 9.0.4 9.0.5 9.1 9.1.1 9.1.2 9.1.3 9.2 9.2.1 9.2.2 9.2.3 9.2.4 9.3 9.3.1 9.3.2 9.3.3 9.3.4 9.3.5 9.4 9.4.1 9.4.2 9.4.3 9.4.4 9.5 9.5.1 9.5.2 9.5.3 9.5.4 9.5.5 9.6 9.6.1 9.6.2 9.6.3 9.6.4 9.7 9.7.1 9.7.2 15.7-beta.2 9.7.3 15.7.1 9.8 15.8-a.1 9.8.1 15.8-a.3 9.8.2 2.0.9 9.8.3 2.1.7 9.9 2.2.10 9.9.1 2.3.10 9.9.2 2.4.7 9.9.3 2.5.5 2.6.6 2.7.5 2.8.5 2.9.6 3.0.6 3.1.5 3.2.5 3.3.6 3.4.6 3.5.6 3.6.4 3.7.5 3.8.5 3.9.10 4.0.7 4.1.4 4.2.5 4.3.5 4.4.5 4.5.3 4.6.3 4.7.4 4.8.5 4.9.3 5.0.3 5.1.4 trunk 10.0 10.0.1 10.0.2 10.1 10.1.1 10.1.2 10.2 10.2.1 10.2.2 10.2.3 10.3 10.3.1 10.3.2 10.4 10.4.1 10.4.2 10.5 10.5.1 10.5.2 10.5.3 10.6 10.6.1 10.6.2 10.7 10.7.1 10.7.2 10.8 10.8.1 10.8.2 10.9 10.9.1 10.9.2 10.9.3 11.0 11.0.1 11.0.2 11.1 11.1.1 11.1.2 11.1.3 11.1.4 11.2 11.2.1 11.2.2 11.3 11.3.1 11.3.2 11.3.3 11.3.4 11.4 11.4.1 11.4.2 11.5 11.5.1 11.5.2 11.5.3 11.6 11.6.1 11.6.2 11.7 11.7.1 11.7.2 11.7.3 11.8 11.8.3 11.8.4 11.8.5 11.8.6 11.9 11.9.1 11.9.2 11.9.3 12.0 12.0.1 12.0.2 12.1 12.1.1 12.1.2 12.2 12.2.1 12.2.2 12.3 12.3.1 12.4 12.4.1 12.5 12.5.1 12.6 12.6.1 12.6.2 12.6.3 12.7 12.7.1 12.7.2 12.8 12.8.1 12.8.2 12.9 12.9.1 12.9.2 12.9.3 12.9.4 13.0 13.0.1 13.1 13.1.1 13.1.2 13.1.3 13.1.4 13.2 13.2.1 13.2.2 13.2.3 13.3 13.3.1 13.3.2 13.4 13.4.1 13.4.2 13.4.3 13.4.4 13.5 13.5.1 13.6 13.6.1 13.7 13.7.1 13.8 13.8.1 13.8.2 13.9 13.9.1 14.0 14.1 14.2 14.2.1 14.3 14.4 14.4.1 14.5 14.6 14.7 14.8 14.9 14.9.1 15.0 15.0.1 15.0.2 15.1 15.1.1 15.2 15.3 15.3.1 15.4 15.5 15.6 15.7 15.7-a.1 15.7-a.3 15.7-a.5 15.7-a.7 15.7-beta
jetpack / jetpack_vendor / automattic / jetpack-connection / src / sso / class-helpers.php
jetpack / jetpack_vendor / automattic / jetpack-connection / src / sso Last commit date
class-force-2fa.php 8 months ago class-helpers.php 3 months ago class-notices.php 6 months ago class-sso.php 1 month ago class-user-admin.php 2 months ago jetpack-sso-admin-create-user.css 8 months ago jetpack-sso-admin-create-user.js 2 years ago jetpack-sso-login.css 8 months ago jetpack-sso-login.js 2 years ago jetpack-sso-users.js 8 months ago
class-helpers.php
399 lines
1 <?php
2 /**
3 * A collection of helper functions used in the SSO module.
4 *
5 * @package automattic/jetpack-connection
6 */
7
8 namespace Automattic\Jetpack\Connection\SSO;
9
10 use Automattic\Jetpack\Connection\SSO;
11 use Automattic\Jetpack\Constants;
12 use Jetpack_IXR_Client;
13
14 /**
15 * A collection of helper functions used in the SSO module.
16 *
17 * @since jetpack-4.1.0
18 */
19 class Helpers {
20 /**
21 * Determine if the login form should be hidden or not
22 *
23 * @return bool
24 **/
25 public static function should_hide_login_form() {
26 /**
27 * Remove the default log in form, only leave the WordPress.com log in button.
28 *
29 * @module sso
30 *
31 * @since jetpack-3.1.0
32 *
33 * @param bool get_option( 'jetpack_sso_remove_login_form', false ) Should the default log in form be removed. Default to false.
34 */
35 return (bool) apply_filters( 'jetpack_remove_login_form', get_option( 'jetpack_sso_remove_login_form', false ) );
36 }
37
38 /**
39 * Returns a boolean value for whether logging in by matching the WordPress.com user email to a
40 * Jetpack site user's email is allowed.
41 *
42 * @return bool
43 */
44 public static function match_by_email() {
45 $match_by_email = defined( 'WPCC_MATCH_BY_EMAIL' ) ? \WPCC_MATCH_BY_EMAIL : (bool) get_option( 'jetpack_sso_match_by_email', true );
46
47 /**
48 * Link the local account to an account on WordPress.com using the same email address.
49 *
50 * @module sso
51 *
52 * @since jetpack-2.6.0
53 *
54 * @param bool $match_by_email Should we link the local account to an account on WordPress.com using the same email address. Default to false.
55 */
56 return (bool) apply_filters( 'jetpack_sso_match_by_email', $match_by_email );
57 }
58
59 /**
60 * Returns a boolean for whether users are allowed to register on the Jetpack site with SSO,
61 * even though the site disallows normal registrations.
62 *
63 * @param object|null $user_data WordPress.com user information.
64 * @return bool|string
65 */
66 public static function new_user_override( $user_data = null ) {
67 $new_user_override = defined( 'WPCC_NEW_USER_OVERRIDE' ) ? \WPCC_NEW_USER_OVERRIDE : false;
68
69 /**
70 * Allow users to register on your site with a WordPress.com account, even though you disallow normal registrations.
71 * If you return a string that corresponds to a user role, the user will be given that role.
72 *
73 * @module sso
74 *
75 * @since jetpack-2.6.0
76 * @since jetpack-4.6 $user_data object is now passed to the jetpack_sso_new_user_override filter
77 *
78 * @param bool|string $new_user_override Allow users to register on your site with a WordPress.com account. Default to false.
79 * @param object|null $user_data An object containing the user data returned from WordPress.com.
80 */
81 $role = apply_filters( 'jetpack_sso_new_user_override', $new_user_override, $user_data );
82
83 if ( $role ) {
84 if ( is_string( $role ) && get_role( $role ) ) {
85 return $role;
86 } else {
87 return get_option( 'default_role' );
88 }
89 }
90
91 return false;
92 }
93
94 /**
95 * Returns a boolean value for whether two-step authentication is required for SSO.
96 *
97 * @since jetpack-4.1.0
98 *
99 * @return bool
100 */
101 public static function is_two_step_required() {
102 /**
103 * Is it required to have 2-step authentication enabled on WordPress.com to use SSO?
104 *
105 * @module sso
106 *
107 * @since jetpack-2.8.0
108 *
109 * @param bool get_option( 'jetpack_sso_require_two_step' ) Does SSO require 2-step authentication?
110 */
111 return (bool) apply_filters( 'jetpack_sso_require_two_step', get_option( 'jetpack_sso_require_two_step', false ) );
112 }
113
114 /**
115 * Returns a boolean for whether a user that is attempting to log in will be automatically
116 * redirected to WordPress.com to begin the SSO flow.
117 *
118 * @return bool
119 */
120 public static function bypass_login_forward_wpcom() {
121 /**
122 * Redirect the site's log in form to WordPress.com's log in form.
123 *
124 * @module sso
125 *
126 * @since jetpack-3.1.0
127 *
128 * @param bool false Should the site's log in form be automatically forwarded to WordPress.com's log in form.
129 */
130 return (bool) apply_filters( 'jetpack_sso_bypass_login_forward_wpcom', false );
131 }
132
133 /**
134 * Returns a boolean for whether the SSO login form should be displayed as the default
135 * when both the default and SSO login form allowed.
136 *
137 * @since jetpack-4.1.0
138 *
139 * @return bool
140 */
141 public static function show_sso_login() {
142 if ( self::should_hide_login_form() ) {
143 return true;
144 }
145
146 /**
147 * Display the SSO login form as the default when both the default and SSO login forms are enabled.
148 *
149 * @module sso
150 *
151 * @since jetpack-4.1.0
152 *
153 * @param bool true Should the SSO login form be displayed by default when the default login form is also enabled?
154 */
155 return (bool) apply_filters( 'jetpack_sso_default_to_sso_login', true );
156 }
157
158 /**
159 * Returns a boolean for whether the two step required checkbox, displayed on the Jetpack admin page, should be disabled.
160 *
161 * @since jetpack-4.1.0
162 *
163 * @return bool
164 */
165 public static function is_require_two_step_checkbox_disabled() {
166 return (bool) has_filter( 'jetpack_sso_require_two_step' );
167 }
168
169 /**
170 * Returns a boolean for whether the match by email checkbox, displayed on the Jetpack admin page, should be disabled.
171 *
172 * @since jetpack-4.1.0
173 *
174 * @return bool
175 */
176 public static function is_match_by_email_checkbox_disabled() {
177 return defined( 'WPCC_MATCH_BY_EMAIL' ) || has_filter( 'jetpack_sso_match_by_email' );
178 }
179
180 /**
181 * Returns an array of hosts that SSO will redirect to.
182 *
183 * Instead of accessing JETPACK__API_BASE within the method directly, we set it as the
184 * default for $api_base due to restrictions with testing constants in our tests.
185 *
186 * @since jetpack-4.3.0
187 * @since jetpack-4.6.0 Added public-api.wordpress.com as an allowed redirect
188 *
189 * @param array $hosts Allowed redirect hosts.
190 * @param string $api_base Base API URL.
191 *
192 * @return array
193 */
194 public static function allowed_redirect_hosts( $hosts, $api_base = '' ) {
195 if ( empty( $api_base ) ) {
196 $api_base = Constants::get_constant( 'JETPACK__API_BASE' );
197 }
198
199 if ( empty( $hosts ) ) {
200 $hosts = array();
201 }
202
203 $hosts[] = 'wordpress.com';
204 $hosts[] = 'jetpack.wordpress.com';
205 $hosts[] = 'public-api.wordpress.com';
206 $hosts[] = 'jetpack.com';
207
208 if ( ! str_contains( $api_base, 'jetpack.wordpress.com/jetpack' ) ) {
209 $base_url_parts = wp_parse_url( esc_url_raw( $api_base ) );
210 if ( $base_url_parts && ! empty( $base_url_parts['host'] ) ) {
211 $hosts[] = $base_url_parts['host'];
212 }
213 }
214
215 foreach ( array( SSO::get_broker_url(), SSO::get_broker_auth_url() ) as $broker_url ) {
216 if ( $broker_url ) {
217 $broker_parts = wp_parse_url( $broker_url );
218 if ( $broker_parts && ! empty( $broker_parts['host'] ) ) {
219 $hosts[] = $broker_parts['host'];
220 }
221 }
222 }
223
224 return array_unique( $hosts );
225 }
226
227 /**
228 * Determines how long the auth cookie is valid for when a user logs in with SSO.
229 *
230 * @return int result of the jetpack_sso_auth_cookie_expiration filter.
231 */
232 public static function extend_auth_cookie_expiration_for_sso() {
233 /**
234 * Determines how long the auth cookie is valid for when a user logs in with SSO.
235 *
236 * @module sso
237 *
238 * @since jetpack-4.4.0
239 * @since jetpack-6.1.0 Fixed a typo. Filter was previously jetpack_sso_auth_cookie_expirtation.
240 *
241 * @param int YEAR_IN_SECONDS
242 */
243 return (int) apply_filters( 'jetpack_sso_auth_cookie_expiration', YEAR_IN_SECONDS );
244 }
245
246 /**
247 * Determines if the SSO form should be displayed for the current action.
248 *
249 * @since jetpack-4.6.0
250 *
251 * @param string $action SSO action being performed.
252 *
253 * @return bool Is SSO allowed for the current action?
254 */
255 public static function display_sso_form_for_action( $action ) {
256 /**
257 * Allows plugins the ability to overwrite actions where the SSO form is allowed to be used.
258 *
259 * @module sso
260 *
261 * @since jetpack-4.6.0
262 *
263 * @param array $allowed_actions_for_sso
264 */
265 $allowed_actions_for_sso = (array) apply_filters(
266 'jetpack_sso_allowed_actions',
267 array(
268 'login',
269 'jetpack-sso',
270 'jetpack_json_api_authorization',
271 'entered_recovery_mode',
272 )
273 );
274 return in_array( $action, $allowed_actions_for_sso, true );
275 }
276
277 /**
278 * This method returns an environment array that is meant to simulate `$_REQUEST` when the initial
279 * JSON API auth request was made.
280 *
281 * @since jetpack-4.6.0
282 *
283 * @return array|bool
284 */
285 public static function get_json_api_auth_environment() {
286 if ( empty( $_COOKIE['jetpack_sso_original_request'] ) ) {
287 return false;
288 }
289
290 $original_request = esc_url_raw( wp_unslash( $_COOKIE['jetpack_sso_original_request'] ) );
291
292 $parsed_url = wp_parse_url( $original_request );
293 if ( empty( $parsed_url ) || empty( $parsed_url['query'] ) ) {
294 return false;
295 }
296
297 $args = array();
298 wp_parse_str( $parsed_url['query'], $args );
299
300 if ( empty( $args ) || empty( $args['action'] ) ) {
301 return false;
302 }
303
304 if ( 'jetpack_json_api_authorization' !== $args['action'] ) {
305 return false;
306 }
307
308 return array_merge(
309 $args,
310 array( 'jetpack_json_api_original_query' => $original_request )
311 );
312 }
313
314 /**
315 * Check if the site has a custom login page URL, and return it.
316 * If default login page URL is used (`wp-login.php`), `null` will be returned.
317 *
318 * @return string|null
319 */
320 public static function get_custom_login_url() {
321 $login_url = wp_login_url();
322
323 if ( str_ends_with( $login_url, 'wp-login.php' ) ) {
324 // No custom URL found.
325 return null;
326 }
327
328 $site_url = trailingslashit( site_url() );
329
330 if ( ! str_starts_with( $login_url, $site_url ) ) {
331 // Something went wrong, we can't properly extract the custom URL.
332 return null;
333 }
334
335 // Extracting the "path" part of the URL, because we don't need the `site_url` part.
336 return str_ireplace( $site_url, '', $login_url );
337 }
338
339 /**
340 * Clear the cookies that store the profile information for the last
341 * WPCOM user to connect.
342 */
343 public static function clear_wpcom_profile_cookies() {
344 if ( isset( $_COOKIE[ 'jetpack_sso_wpcom_name_' . COOKIEHASH ] ) ) {
345 setcookie(
346 'jetpack_sso_wpcom_name_' . COOKIEHASH,
347 ' ',
348 time() - YEAR_IN_SECONDS,
349 COOKIEPATH,
350 COOKIE_DOMAIN,
351 is_ssl(),
352 true
353 );
354 }
355
356 if ( isset( $_COOKIE[ 'jetpack_sso_wpcom_gravatar_' . COOKIEHASH ] ) ) {
357 setcookie(
358 'jetpack_sso_wpcom_gravatar_' . COOKIEHASH,
359 ' ',
360 time() - YEAR_IN_SECONDS,
361 COOKIEPATH,
362 COOKIE_DOMAIN,
363 is_ssl(),
364 true
365 );
366 }
367 }
368
369 /**
370 * Remove an SSO connection for a user.
371 *
372 * @param int $user_id The local user id.
373 */
374 public static function delete_connection_for_user( $user_id ) {
375 $wpcom_user_id = get_user_meta( $user_id, 'wpcom_user_id', true );
376 if ( ! $wpcom_user_id ) {
377 return;
378 }
379
380 $xml = new Jetpack_IXR_Client(
381 array(
382 'wpcom_user_id' => $user_id,
383 )
384 );
385 $xml->query( 'jetpack.sso.removeUser', $wpcom_user_id );
386
387 if ( $xml->isError() ) {
388 return false;
389 }
390
391 // Clean up local data stored for SSO.
392 delete_user_meta( $user_id, 'wpcom_user_id' );
393 delete_user_meta( $user_id, 'wpcom_user_data' );
394 self::clear_wpcom_profile_cookies();
395
396 return $xml->getResponse();
397 }
398 }
399