Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(Cookies): Updates WP Cookie Expiration to Same as Session Length #514

40 changes: 38 additions & 2 deletions includes/openid-connect-generic-client-wrapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,13 @@ class OpenID_Connect_Generic_Client_Wrapper {
*/
private $error = false;

/**
* Used to pass the openid token refresh expiration time to the auth_cookie_expiration filter.
*
* @var integer
*/
private $openid_token_refresh_expires_in = 0;

/**
* Inject necessary objects and services into the client.
*
Expand Down Expand Up @@ -672,11 +679,24 @@ public function login_user( $user, $token_response, $id_token_claim, $user_claim
// Allow plugins / themes to take action using current claims on existing user (e.g. update role).
do_action( 'openid-connect-generic-update-user-using-current-claim', $user, $user_claim );

// Determine the amount of days before the cookie expires.
$remember_me = apply_filters( 'openid-connect-generic-remember-me', false, $user, $token_response, $id_token_claim, $user_claim, $subject_identity );
$expiration_days = $remember_me ? 14 : 2;
$wp_expiration_days = $remember_me ? 14 : 2;

// If remember-me is enabled, and using token expiration is enabled,
// add a filter to overwrite the default cookie expiration with the
// openid token expiration.
if (
$remember_me
&& apply_filters( 'openid-connect-generic-use-token-refresh-expiration', false )
&& ( $token_response['refresh_expires_in'] ?? 0 )
) {
$this->openid_token_refresh_expires_in = $token_response['refresh_expires_in'];
add_filter( 'auth_cookie_expiration', array( $this, 'set_cookie_expiration_to_openid_token_refresh_expiration' ) );
}

// Create the WP session, so we know its token.
$expiration = time() + apply_filters( 'auth_cookie_expiration', $expiration_days * DAY_IN_SECONDS, $user->ID, false );
$expiration = time() + apply_filters( 'auth_cookie_expiration', $wp_expiration_days * DAY_IN_SECONDS, $user->ID, false );
$manager = WP_Session_Tokens::get_instance( $user->ID );
$token = $manager->create( $expiration );

Expand All @@ -686,6 +706,22 @@ public function login_user( $user, $token_response, $id_token_claim, $user_claim
// you did great, have a cookie!
wp_set_auth_cookie( $user->ID, $remember_me, '', $token );
do_action( 'wp_login', $user->user_login, $user );

// Remove the filter for the auth cookie expiration after all the auth cookies are set.
remove_filter( 'auth_cookie_expiration', array( $this, 'set_cookie_expiration_to_openid_token_refresh_expiration' ) );
}

/**
* Filter callback to overwrite the default cookie expiration with the
* openid token refresh expiration. This is applied both when creating the session
* token as well as when wp_set_auth_cookie is called.
*
* @param integer $expiration_in_seconds The expiration time in seconds.
* @return integer
*/
public function set_cookie_expiration_to_openid_token_refresh_expiration( $expiration_in_seconds ) {
$expiration_in_seconds = $this->openid_token_refresh_expires_in;
return $expiration_in_seconds;
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,26 +45,67 @@ public function test_plugin_client_wrapper_alternate_redirect_uri_parse_request(

}

/**
* Test if by using the remember-me filter, the user session expiration
* is set to 14 days, which is the default of WordPress
*
* @group ClientWrapperTests
*/
public function test_plugin_client_wrapper_remember_me() {
// Set the remember me option to true
add_filter( 'openid-connect-generic-remember-me', '__return_true' );

// Create a user and log in using the login function of the client wrapper
$user = $this->factory()->user->create_and_get( array( 'user_login' => 'test-remember-me-user' ) );
$this->client_wrapper->login_user( $user, array(
'expires_in' => 14 * HOUR_IN_SECONDS, // This does not influence the length of the cookie
'expires_in' => 5 * MINUTE_IN_SECONDS,
), array(), array(), '' );

// Retrieve the session tokens
$manager = WP_Session_Tokens::get_instance( $user->ID );
$token = $manager->get_all()[0];

// Assert if the token is set to expire in 14 days, with some seconds as a timing margin
// Assert if the token is set to expire in 14 days, with some timing margin
$this->assertGreaterThan( time() + 13 * DAY_IN_SECONDS, $token['expiration'] );
$this->assertLessThan( time() + 15 * DAY_IN_SECONDS, $token['expiration'] );

// Reset the remember me option
// Cleanup
remove_filter( 'openid-connect-generic-remember-me', '__return_true' );
$manager->destroy_all();
wp_clear_auth_cookie();
}

/**
* Test if by using the use-token-expiration, the user session expiration
* is set to the value of the expires_in parameter of the token.
*
* @group ClientWrapperTests
*/
public function test_plugin_client_wrapper_token_expiration() {
// Set the remember me option to true
add_filter( 'openid-connect-generic-remember-me', '__return_true' );
add_filter( 'openid-connect-generic-use-token-refresh-expiration', '__return_true' );

// Create a user and log in using the login function of the client wrapper
$user = $this->factory()->user->create_and_get( array( 'user_login' => 'test-remember-me-user' ) );
$this->client_wrapper->login_user( $user, array(
'expires_in' => 5 * MINUTE_IN_SECONDS,
'refresh_expires_in' => 30 * DAY_IN_SECONDS,
), array(), array(), '' );

// Retrieve the session tokens
$manager = WP_Session_Tokens::get_instance( $user->ID );
$token = $manager->get_all()[0];

// Assert if the token is set to expire in 30 days, with some timing margin
$this->assertGreaterThan( time() + 29 * DAY_IN_SECONDS, $token['expiration'] );
$this->assertLessThan( time() + 31 * DAY_IN_SECONDS, $token['expiration'] );

// Cleanup
remove_filter( 'openid-connect-generic-remember-me', '__return_true' );
remove_filter( 'openid-connect-generic-use-token-refresh-expiration', '__return_true' );
$manager->destroy_all();
wp_clear_auth_cookie();
}

}
Loading