summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/jetpack/modules/sso.php')
-rw-r--r--plugins/jetpack/modules/sso.php193
1 files changed, 92 insertions, 101 deletions
diff --git a/plugins/jetpack/modules/sso.php b/plugins/jetpack/modules/sso.php
index 96a60858..c5f5538e 100644
--- a/plugins/jetpack/modules/sso.php
+++ b/plugins/jetpack/modules/sso.php
@@ -1,5 +1,6 @@
<?php
+use Automattic\Jetpack\Connection\Manager as Connection_Manager;
use Automattic\Jetpack\Roles;
use Automattic\Jetpack\Status;
use Automattic\Jetpack\Tracking;
@@ -14,6 +15,7 @@ require_once( JETPACK__PLUGIN_DIR . 'modules/sso/class.jetpack-sso-notices.php'
* Recommendation Order: 5
* First Introduced: 2.6
* Requires Connection: Yes
+ * Requires User Connection: Yes
* Auto Activate: No
* Module Tags: Developers
* Feature: Security
@@ -37,7 +39,6 @@ class Jetpack_SSO {
add_action( 'login_form_logout', array( $this, 'store_wpcom_profile_cookies_on_logout' ) );
add_action( 'jetpack_unlinked_user', array( $this, 'delete_connection_for_user') );
add_action( 'wp_login', array( 'Jetpack_SSO', 'clear_cookies_after_login' ) );
- add_action( 'jetpack_jitm_received_envelopes', array( $this, 'inject_sso_jitm' ) );
// Adding this action so that on login_init, the action won't be sanitized out of the $action global.
add_action( 'login_form_jetpack-sso', '__return_true' );
@@ -361,11 +362,6 @@ class Jetpack_SSO {
$reauth = ! empty( $_GET['force_reauth'] );
$sso_url = $this->get_sso_url_or_die( $reauth );
- // Is this our first SSO Login. Set an option.
- if ( ! Jetpack_Options::get_option( 'sso_first_login' ) ) {
- Jetpack_options::update_option( 'sso_first_login', true );
- }
-
$tracking->record_user_event( 'sso_login_redirect_success' );
wp_safe_redirect( $sso_url );
exit;
@@ -465,7 +461,17 @@ class Jetpack_SSO {
?>
<div id="jetpack-sso-wrap">
- <?php if ( $display_name && $gravatar ) : ?>
+ <?php
+ /**
+ * Allow extension above Jetpack's SSO form.
+ *
+ * @module sso
+ *
+ * @since 8.6.0
+ */
+ do_action( 'jetpack_sso_login_form_above_wpcom' );
+
+ if ( $display_name && $gravatar ) : ?>
<div id="jetpack-sso-wrap__user">
<img width="72" height="72" src="<?php echo esc_html( $gravatar ); ?>" />
@@ -492,33 +498,55 @@ class Jetpack_SSO {
<?php else : ?>
<p>
<?php
- echo esc_html(
+ /**
+ * Filter the messeage displayed below the SSO button.
+ *
+ * @module sso
+ *
+ * @since 10.3.0
+ *
+ * @param string $sso_explanation Message displayed below the SSO button.
+ */
+ $sso_explanation = apply_filters(
+ 'jetpack_sso_login_form_explanation_text',
sprintf(
+ /* Translators: %s is the name of the site. */
__( 'You can now save time spent logging in by connecting your WordPress.com account to %s.', 'jetpack' ),
esc_html( $site_name )
)
);
+ echo esc_html( $sso_explanation );
?>
</p>
<?php endif; ?>
</div>
- <?php if ( ! Jetpack_SSO_Helpers::should_hide_login_form() ) : ?>
- <div class="jetpack-sso-or">
- <span><?php esc_html_e( 'Or', 'jetpack' ); ?></span>
- </div>
+ <?php
+ /**
+ * Allow extension below Jetpack's SSO form.
+ *
+ * @module sso
+ *
+ * @since 8.6.0
+ */
+ do_action( 'jetpack_sso_login_form_below_wpcom' );
+
+ if ( ! Jetpack_SSO_Helpers::should_hide_login_form() ) : ?>
+ <div class="jetpack-sso-or">
+ <span><?php esc_html_e( 'Or', 'jetpack' ); ?></span>
+ </div>
+
+ <a href="<?php echo esc_url( add_query_arg( 'jetpack-sso-show-default-form', '1' ) ); ?>" class="jetpack-sso-toggle wpcom">
+ <?php
+ esc_html_e( 'Log in with username and password', 'jetpack' )
+ ?>
+ </a>
- <a href="<?php echo esc_url( add_query_arg( 'jetpack-sso-show-default-form', '1' ) ); ?>" class="jetpack-sso-toggle wpcom">
- <?php
- esc_html_e( 'Log in with username and password', 'jetpack' )
- ?>
- </a>
-
- <a href="<?php echo esc_url( add_query_arg( 'jetpack-sso-show-default-form', '0' ) ); ?>" class="jetpack-sso-toggle default">
- <?php
- esc_html_e( 'Log in with WordPress.com', 'jetpack' )
- ?>
- </a>
+ <a href="<?php echo esc_url( add_query_arg( 'jetpack-sso-show-default-form', '0' ) ); ?>" class="jetpack-sso-toggle default">
+ <?php
+ esc_html_e( 'Log in with WordPress.com', 'jetpack' )
+ ?>
+ </a>
<?php endif; ?>
</div>
<?php
@@ -621,9 +649,7 @@ class Jetpack_SSO {
: false;
if ( ! $nonce ) {
- $xml = new Jetpack_IXR_Client( array(
- 'user_id' => get_current_user_id(),
- ) );
+ $xml = new Jetpack_IXR_Client();
$xml->query( 'jetpack.sso.requestNonce' );
if ( $xml->isError() ) {
@@ -652,9 +678,7 @@ class Jetpack_SSO {
$wpcom_nonce = sanitize_key( $_GET['sso_nonce'] );
$wpcom_user_id = (int) $_GET['user_id'];
- $xml = new Jetpack_IXR_Client( array(
- 'user_id' => get_current_user_id(),
- ) );
+ $xml = new Jetpack_IXR_Client();
$xml->query( 'jetpack.sso.validateResult', $wpcom_nonce, $wpcom_user_id );
$user_data = $xml->isError() ? false : $xml->getResponse();
@@ -687,8 +711,10 @@ class Jetpack_SSO {
'error_message' => 'error_msg_enable_two_step'
) );
+ $error = new WP_Error( 'two_step_required', __( 'You must have Two-Step Authentication enabled on your WordPress.com account.', 'jetpack' ) );
+
/** This filter is documented in core/src/wp-includes/pluggable.php */
- do_action( 'wp_login_failed', $user_data->login );
+ do_action( 'wp_login_failed', $user_data->login, $error );
add_filter( 'login_message', array( 'Jetpack_SSO_Notices', 'error_msg_enable_two_step' ) );
return;
}
@@ -696,8 +722,17 @@ class Jetpack_SSO {
$user_found_with = '';
if ( empty( $user ) && isset( $user_data->external_user_id ) ) {
$user_found_with = 'external_user_id';
- $user = get_user_by( 'id', intval( $user_data->external_user_id ) );
+ $user = get_user_by( 'id', (int) $user_data->external_user_id );
if ( $user ) {
+ $expected_id = get_user_meta( $user->ID, 'wpcom_user_id', true );
+ if ( $expected_id && $expected_id != $user_data->ID ) { // phpcs:ignore WordPress.PHP.StrictComparisons.LooseComparison
+ $error = new WP_Error( 'expected_wpcom_user', __( 'Something got a little mixed up and an unexpected WordPress.com user logged in.', 'jetpack' ) );
+
+ /** This filter is documented in core/src/wp-includes/pluggable.php */
+ do_action( 'wp_login_failed', $user_data->login, $error );
+ add_filter( 'login_message', array( 'Jetpack_SSO_Notices', 'error_invalid_response_data' ) ); // @todo Need to have a better notice. This is only for the sake of testing the validation.
+ return;
+ }
update_user_meta( $user->ID, 'wpcom_user_id', $user_data->ID );
}
}
@@ -758,8 +793,8 @@ class Jetpack_SSO {
*
* @since 2.6.0
*
- * @param array $user Local User information.
- * @param object $user_data WordPress.com User Login information.
+ * @param WP_User|false|null $user Local User information.
+ * @param object $user_data WordPress.com User Login information.
*/
do_action( 'jetpack_sso_handle_login', $user, $user_data );
@@ -788,7 +823,7 @@ class Jetpack_SSO {
$json_api_auth_environment = Jetpack_SSO_Helpers::get_json_api_auth_environment();
$is_json_api_auth = ! empty( $json_api_auth_environment );
- $is_user_connected = Jetpack::is_user_connected( $user->ID );
+ $is_user_connected = ( new Connection_Manager( 'jetpack' ) )->is_user_connected( $user->ID );
$roles = new Roles();
$tracking->record_user_event( 'sso_user_logged_in', array(
'user_found_with' => $user_found_with,
@@ -831,8 +866,11 @@ class Jetpack_SSO {
) );
$this->user_data = $user_data;
+
+ $error = new WP_Error( 'account_not_found', __( 'Account not found. If you already have an account, make sure you have connected to WordPress.com.', 'jetpack' ) );
+
/** This filter is documented in core/src/wp-includes/pluggable.php */
- do_action( 'wp_login_failed', $user_data->login );
+ do_action( 'wp_login_failed', $user_data->login, $error );
add_filter( 'login_message', array( 'Jetpack_SSO_Notices', 'cant_find_user' ) );
}
@@ -854,7 +892,7 @@ class Jetpack_SSO {
: 'jetpack-sso button';
return sprintf(
- '<a rel="nofollow" href="%1$s" class="%2$s"><span>%3$s %4$s</span></a>',
+ '<a rel="nofollow" href="%1$s" class="%2$s">%3$s %4$s</a>',
esc_url( $url ),
$classes,
'<span class="genericon genericon-wordpress"></span>',
@@ -890,6 +928,11 @@ class Jetpack_SSO {
* @return string The WordPress.com SSO URL.
*/
function get_sso_url_or_die( $reauth = false, $args = array() ) {
+ $custom_login_url = Jetpack_SSO_Helpers::get_custom_login_url();
+ if ( $custom_login_url ) {
+ $args['login_url'] = rawurlencode( $custom_login_url );
+ }
+
if ( empty( $reauth ) ) {
$sso_redirect = $this->build_sso_url( $args );
} else {
@@ -915,12 +958,12 @@ class Jetpack_SSO {
/**
* Build WordPress.com SSO URL with appropriate query parameters.
*
- * @param array $args Optional query parameters.
- * @return string WordPress.com SSO URL
+ * @param array $args Optional query parameters.
+ * @return string WordPress.com SSO URL
*/
- function build_sso_url( $args = array() ) {
+ public function build_sso_url( $args = array() ) {
$sso_nonce = ! empty( $args['sso_nonce'] ) ? $args['sso_nonce'] : self::request_initial_nonce();
- $defaults = array(
+ $defaults = array(
'action' => 'jetpack-sso',
'site_id' => Jetpack_Options::get_option( 'id' ),
'sso_nonce' => $sso_nonce,
@@ -941,10 +984,10 @@ class Jetpack_SSO {
* including the parameters necessary to force the user to reauthenticate
* on WordPress.com.
*
- * @param array $args Optional query parameters.
- * @return string WordPress.com SSO URL
+ * @param array $args Optional query parameters.
+ * @return string WordPress.com SSO URL
*/
- function build_reauth_and_sso_url( $args = array() ) {
+ public function build_reauth_and_sso_url( $args = array() ) {
$sso_nonce = ! empty( $args['sso_nonce'] ) ? $args['sso_nonce'] : self::request_initial_nonce();
$redirect = $this->build_sso_url( array( 'force_auth' => '1', 'sso_nonce' => $sso_nonce ) );
@@ -981,7 +1024,7 @@ class Jetpack_SSO {
static function get_user_by_wpcom_id( $wpcom_user_id ) {
$user_query = new WP_User_Query( array(
'meta_key' => 'wpcom_user_id',
- 'meta_value' => intval( $wpcom_user_id ),
+ 'meta_value' => (int) $wpcom_user_id,
'number' => 1,
) );
@@ -1016,7 +1059,11 @@ class Jetpack_SSO {
/**
* Return the raw connect URL with our redirect and attribute connection to SSO.
+ * We remove any other filters that may be turning on the in-place connection
+ * since we will be redirecting the user as opposed to iFraming.
*/
+ remove_all_filters( 'jetpack_use_iframe_authorization_flow' );
+ add_filter( 'jetpack_use_iframe_authorization_flow', '__return_false' );
$connect_url = Jetpack::init()->build_connect_url( true, $redirect_after_auth, 'sso' );
add_filter( 'allowed_redirect_hosts', array( 'Jetpack_SSO_Helpers', 'allowed_redirect_hosts' ) );
@@ -1029,7 +1076,7 @@ class Jetpack_SSO {
* stored when the user logs out, and then deleted when the user logs in.
*/
function store_wpcom_profile_cookies_on_logout() {
- if ( ! Jetpack::is_user_connected( get_current_user_id() ) ) {
+ if ( ! ( new Connection_Manager( 'jetpack' ) )->is_user_connected( get_current_user_id() ) ) {
return;
}
@@ -1081,62 +1128,6 @@ class Jetpack_SSO {
public function get_user_data( $user_id ) {
return get_user_meta( $user_id, 'wpcom_user_data', true );
}
-
- /**
- * Mark SSO as discovered when an SSO JITM is viewed.
- *
- * @since 6.9.0
- *
- * @param array $envelopes Array of JITM messages received after API call.
- *
- * @return array $envelopes New array of JITM messages. May now contain only one message, about SSO.
- */
- public function inject_sso_jitm( $envelopes ) {
- // Bail early if that's not the first time the user uses SSO.
- if ( true != Jetpack_Options::get_option( 'sso_first_login' ) ) {
- return $envelopes;
- }
-
- // Update our option to mark that SSO was discovered.
- Jetpack_Options::update_option( 'sso_first_login', false );
-
- return $this->prepare_sso_first_login_jitm();
- }
-
- /**
- * Prepare JITM array for new SSO users
- *
- * @since 6.9.0
- *
- * @return array $sso_first_login_jitm array containting one object of information about our message.
- */
- private function prepare_sso_first_login_jitm() {
- // Build our custom SSO JITM.
- $discover_sso_message = array(
- 'content' => array(
- 'message' => esc_html__( "You've successfully signed in with WordPress.com Secure Sign On!", 'jetpack' ),
- 'icon' => 'jetpack',
- 'list' => array(),
- 'description' => esc_html__( 'Interested in learning more about how Secure Sign On keeps your site safer?', 'jetpack' ),
- 'classes' => '',
- ),
- 'CTA' => array(
- 'message' => esc_html__( 'Learn More', 'jetpack' ),
- 'hook' => '',
- 'newWindow' => true,
- 'primary' => true,
- ),
- 'template' => 'default',
- 'ttl' => 300,
- 'id' => 'sso_discover',
- 'feature_class' => 'sso',
- 'expires' => 3628800,
- 'max_dismissal' => 1,
- 'activate_module' => null,
- );
-
- return array( json_decode( json_encode( $discover_sso_message ) ) );
- }
}
Jetpack_SSO::get_instance();