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

State handling during login process for both types #406

Merged
merged 4 commits into from
Mar 12, 2018

Conversation

joshcanhelp
Copy link
Contributor

@joshcanhelp joshcanhelp commented Mar 2, 2018

The WordPress plugin doesn't not currently handle state checking at all. A value is set in Lock and sent back but not stored and checked. This PR:

  • Adds a WP_Auth0_State_Handler class used to generate, store, and validate a state nonce using cookies
  • Adjusts Lock to use the new nonce value and stores it as a cookie
  • Checks for this value during login for both flows, redirect and implicit
  • Adds a WP_Auth0_LoginManager->die_on_login() method to handling error message display for login errors
  • Adjusts the auth0-singlelogout-handler.php to not pull Lock options and skip anything related to state

@joshcanhelp joshcanhelp added the WIP label Mar 2, 2018
@joshcanhelp joshcanhelp added this to the v3-Next milestone Mar 2, 2018
…rect; added WP_Auth0_LoginManager->die_on_login() to handle login errors better
joshcanhelp added a commit that referenced this pull request Mar 3, 2018
$client_id = $this->a0_options->get( 'client_id' );
$domain = $this->a0_options->get( 'domain' );
$logout_url = wp_logout_url( get_permalink() ) . '&SLO=1';

include WPA0_PLUGIN_DIR . 'templates/auth0-singlelogout-handler.php';
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed vars above were moved into templates/auth0-singlelogout-handler.php down below

if (err !== null) {
if(err.error ==='login_required') {
window.location = '<?php echo html_entity_decode( $logout_url ); ?>';
webAuth.checkSession( { 'responseType' : 'token', 'redirectUri' : window.location.href }, function ( err ) {
Copy link
Contributor Author

@joshcanhelp joshcanhelp Mar 5, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change might seem a little out-of-scope but this template file was pulling Lock options which was, in turn, generating a state nonce and trying to store it in cookies. checkSession only needs a couple of options and pulling all the Lock ones and then overriding one was confusing.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To me this looks as a good call. 👏

@joshcanhelp joshcanhelp added CH: Added and removed WIP labels Mar 5, 2018
/**
* @var string
*/
protected $uniqid = '';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is being set in the __construct() method (I guess the class instance constructor) there shouldn't be a need to set it to '' here.

window.location = '<?php echo html_entity_decode( $logout_url ); ?>';
webAuth.checkSession( { 'responseType' : 'token', 'redirectUri' : window.location.href }, function ( err ) {
if ( err && err.error ==='login_required' ) {
window.location = '<?php echo esc_url( wp_logout_url( get_permalink() ) . '&SLO=1' ); ?>';
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is the SLO=1 query param added at the end of the url?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Takes the redirect_to query param (the argument in wp_logout_url()) and redirects after running the logout process:

https://github.com/auth0/wp-auth0/blob/master/lib/WP_Auth0_LoginManager.php#L93

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't follow. This is an "internal" query param that you later use to know if you have to redirect?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Basically, yes. It sends it through the regular logout process, then that param tells the process to look for the redirect param.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uhm Ok. Sounds hacky and I'm not going to block you for this if it works. But it should probably be reviewed in the future 🐔

Copy link
Contributor Author

@joshcanhelp joshcanhelp Mar 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Logout process is getting a once-over in another PR for this same release. You'll be able to sleep through the night soon enough 💤

@joshcanhelp joshcanhelp changed the title [WIP] State handling during login process for both types State handling during login process for both types Mar 6, 2018
@@ -162,6 +149,12 @@ public function init_auth0() {
return;
}

// Check for valid state UUID
$state_decoded = json_decode( base64_decode( $this->query_vars( 'state' ) ), TRUE );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

what if state is missing from query_vars. How will the code behave?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Then empty( $state_decoded[ 'nonce' ] ) will be true and the login process will fail

Copy link
Contributor

@lbalmaceda lbalmaceda Mar 7, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you are saying this calls

json_decode( base64_decode( $this->query_vars( 'state' ) ), TRUE );

don't fail when the query_vars.state is missing/null/undefined, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Exactly. $this->query_vars( 'state' ) returns null if not found, base64_decode() returns false in that case, and json_decode() returns false. PHP's empty() returns true even if that key does not exist (no errors).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perfect, thanks.

$msg .= '<br/><br/>';
$msg .= '<a href="' . wp_login_url() . '">' . __( '← Login', 'wp-auth0' ) . '</a>';
wp_die( $msg );
$this->die_on_login( $e->getMessage(), $e->getCode() );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This 2 die_on_login calls only differ on the boolean you pass at the end.. This uses the default TRUE, meaning is "LOGIN_LINK" (idk what that means). The other passes FALSE, so its "LOGOUT_LINK" (again idk). How is that an exception type on the same "try logic" could tell you that?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you have an internal exception from when the user needs to log in / log out? In that case I think I understand now, and depending on the bool you are adding the link to log in / log out on the message.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That whole try block needs attention in another PR but, as I understand the intended flow, there are exceptions that are thrown during the login process, WP_Auth0_LoginFlowValidationException, and exceptions thrown once the login flow is complete but before you're actually logged in, WP_Auth0_BeforeLoginException. That bool determines what the messaging is.

/**
* @var int
*/
protected $cookieExpiresIn = MINUTE_IN_SECONDS;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where does this value comes from?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbalmaceda lbalmaceda self-requested a review March 7, 2018 22:01
@joshcanhelp joshcanhelp requested a review from cocojoe March 7, 2018 22:03
123456789012345678901234567890123456789012345678901234567890123456789012
Added a get_state method to WP_Auth0_LoginManager to get and parse the
state parameter as an object. Added 'state' to allowed query_vars.
*
* @return object|null
*/
protected function get_state() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@lbalmaceda - FYI, I just added this method and it's usage above (using this instead of always parsing the state parameter). It didn't invalidate your review but thought I would point it out.

Copy link
Member

@cocojoe cocojoe left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM in general, as always test thoroughly.

@joshcanhelp joshcanhelp merged commit 02c6bba into dev Mar 12, 2018
@joshcanhelp joshcanhelp deleted the fixed-handle-state-checking branch March 27, 2018 22:32
@joshcanhelp joshcanhelp mentioned this pull request Jun 5, 2018
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 19, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants