Changeset 9941 for sites/trunk/common/includes/wporg-sso/wp-plugin.php
- Timestamp:
- 05/29/2020 03:14:48 AM (6 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
sites/trunk/common/includes/wporg-sso/wp-plugin.php
r9833 r9941 67 67 add_filter( 'register_url', [ $this, 'add_locale' ], 21 ); 68 68 add_filter( 'lostpassword_url', [ $this, 'add_locale' ], 21 ); 69 } else { 70 add_filter( 'login_redirect', [ $this, 'maybe_add_remote_login_bounce_to_post_login_url' ], 10, 3 ); 69 71 } 70 72 } … … 186 188 if ( preg_match( '!/wp-login\.php$!', $this->script ) ) { 187 189 // Don't redirect the 'confirmaction' wp-login handlers to login.wordpress.org. 188 if ( isset( $_GET['action'] ) && empty( $_POST ) && 'confirmaction' == $_GET['action'] ) {190 if ( isset( $_GET['action'] ) && empty( $_POST ) && 'confirmaction' == $_GET['action'] ) { 189 191 return; 192 } 193 194 // Allow logout on non-dotorg hosts. 195 if ( isset( $_GET['action'] ) && empty( $_POST ) && 'logout' == $_GET['action'] ) { 196 if ( ! preg_match( '!wordpress\.org$!', $_SERVER['HTTP_HOST'] ) ) { 197 return; 198 } 199 } 200 201 // Remote SSO login? 202 if ( isset( $_GET['action'] ) && 'remote-login' === $_GET['action'] && ! empty( $_GET['sso_token'] ) ) { 203 $this->_maybe_perform_remote_login(); 190 204 } 191 205 … … 200 214 // Pay extra attention to the post-process redirect_to 201 215 $redirect_to_sso_login = add_query_arg( 'redirect_to', urlencode( $redirect_req ), $redirect_to_sso_login ); 216 if ( ! preg_match( '!wordpress\.org$!', $this->host ) ) { 217 $redirect_to_sso_login = add_query_arg( 'from', $this->host, $redirect_to_sso_login ); 218 } 202 219 203 220 // And actually redirect to the SSO login … … 244 261 // Else let the theme render, or redirect if logged in 245 262 if ( is_user_logged_in() ) { 246 $this->_redirect_to_ profile();263 $this->_redirect_to_source_or_profile(); 247 264 } else { 248 265 if ( empty( $_GET['screen'] ) ) { … … 259 276 } else if ( is_user_logged_in() ) { 260 277 // Otherwise, redirect to the their profile. 261 $this->_redirect_to_ profile();278 $this->_redirect_to_source_or_profile(); 262 279 } 263 280 } elseif ( ( is_admin() && is_super_admin() ) || 0 === strpos( $_SERVER['REQUEST_URI'], '/wp-json' ) || 0 === strpos( $_SERVER['REQUEST_URI'], '/xmlrpc.php' ) ) { … … 265 282 } elseif ( is_user_logged_in() ) { 266 283 // Logged in catch all, before last fallback 267 $this->_redirect_to_ profile();284 $this->_redirect_to_source_or_profile(); 268 285 } else { 269 286 // Otherwise, redirect to the login screen. … … 365 382 366 383 /** 367 * Redirects the user to her/his (support) profile.368 */ 369 protected function _redirect_to_ profile() {370 if ( ! is_user_logged_in() ) {371 return; 372 }373 374 if ( ! empty( $_GET['redirect_to']) ) {375 $this->_safe_redirect( $this->_get_safer_redirect_to());384 * Redirects the user back to where they came from (or w.org profile) 385 */ 386 protected function _redirect_to_source_or_profile() { 387 $redirect = $this->_get_safer_redirect_to(); 388 389 if ( $redirect ) { 390 $this->_safe_redirect( $this->_maybe_add_remote_login_bounce( $redirect ) ); 391 } elseif ( is_user_logged_in() ) { 392 $this->_safe_redirect( 'https://profiles.wordpress.org/' . wp_get_current_user()->user_nicename . '/' ); 376 393 } else { 377 $this->_safe_redirect( 'https://profiles.wordpress.org/' . wp_get_current_user()->user_nicename . '/' ); 378 } 394 $this->_safe_redirect( 'https://wordpress.org/' ); 395 } 396 } 397 398 /** 399 * Logs in a user on the current domain on a remote-login action. 400 */ 401 protected function _maybe_perform_remote_login() { 402 $remote_token = wp_unslash( $_GET['sso_token'] ); 403 if ( ! is_string( $remote_token ) || 3 !== substr_count( $remote_token, '|' ) ) { 404 wp_die( 'Invalid token.' ); 405 } 406 407 list( $user_id, $sso_hash, $valid_until, $remember_me ) = explode( '|', $remote_token, 4 ); 408 409 $remote_expiration_valid = ( 410 // +/- 5s on a 5s timeout. 411 $valid_until >= ( time() - 5 ) && 412 $valid_until <= ( time() + 10 ) 413 ); 414 415 $valid_remote_hash = false; 416 $user = get_user_by( 'id', $user_id ); 417 if ( $user ) { 418 $valid_remote_hash = hash_equals( 419 $this->_generate_remote_login_hash( $user, $valid_until, $remember_me ), 420 $sso_hash 421 ); 422 } 423 424 if ( $remote_expiration_valid && $valid_remote_hash ) { 425 wp_set_current_user( (int) $user_id ); 426 wp_set_auth_cookie( (int) $user_id, (bool) $remember_me ); 427 428 if ( isset( $_GET['redirect_to'] ) ) { 429 $this->_safe_redirect( wp_unslash( $_GET['redirect_to'] ) ); 430 } else { 431 $this->_safe_redirect( home_url( '/' ) ); 432 } 433 exit; 434 } 435 436 return false; 437 } 438 439 public function maybe_add_remote_login_bounce_to_post_login_url( $redirect, $requested, $user ) { 440 return $this->_maybe_add_remote_login_bounce( $redirect, $user ); 441 } 442 443 protected function _maybe_add_remote_login_bounce( $redirect, $user = false ) { 444 if ( ! $user ) { 445 $user = wp_get_current_user(); 446 } 447 448 // If it's on a different _supported_ host, bounce through the remote-login. 449 $redirect_host = parse_url( $redirect, PHP_URL_HOST ); 450 451 if ( $user && $this->_is_valid_targeted_domain( $redirect_host ) && ! preg_match( '!wordpress.org$!i', $redirect_host ) ) { 452 453 // Fetch auth cookie parts to find out if the user has selected 'remember me'. 454 $auth_cookie_parts = wp_parse_auth_cookie( '', 'secure_auth' ); 455 456 $valid_until = time() + 5; // Super short timeout. 457 $remember_me = ! empty( $_POST['rememberme'] ) || ( $auth_cookie_parts && $auth_cookie_parts['expiration'] >= ( time() + ( 2 * DAY_IN_SECONDS ) ) ); 458 459 $hash = $this->_generate_remote_login_hash( $user, $valid_until, $remember_me ); 460 $sso_token = $user->ID . '|' . $hash . '|' . $valid_until . '|' . $remember_me; 461 462 $redirect = add_query_arg( 463 array( 464 'action' => 'remote-login', 465 'sso_token' => urlencode( $sso_token ), 466 'redirect_to' => urlencode( $redirect ), 467 ), 468 'https://' . $redirect_host . '/wp-login.php' // Assume that wp-login exists and is accessible 469 ); 470 } 471 472 return $redirect; 473 } 474 475 /** 476 * Generate a hash for remote-login for non-wordpress.org domains 477 */ 478 protected function _generate_remote_login_hash( $user, $valid_until, $remember_me = false ) { 479 // re-use the same frag that Auth cookies use to invalidate sessions. 480 $pass_frag = substr( $user->user_pass, 8, 4 ); 481 $key = wp_hash( $user->user_login . '|' . $pass_frag . '|' . $valid_until ); 482 $hash = hash_hmac( 'sha256', $user->user_login . '|' . $valid_until . '|' . (int) $remember_me, $key ); 483 484 return $hash; 379 485 } 380 486 }
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)