-
Notifications
You must be signed in to change notification settings - Fork 96
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
Conversation
9a0d68f
to
ad26af1
Compare
…rect; added WP_Auth0_LoginManager->die_on_login() to handle login errors better
ad26af1
to
13f2f38
Compare
… setting a cookie unecessarily
$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'; |
There was a problem hiding this comment.
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 ) { |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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. 👏
lib/WP_Auth0_State_Handler.php
Outdated
/** | ||
* @var string | ||
*/ | ||
protected $uniqid = ''; |
There was a problem hiding this comment.
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' ); ?>'; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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 🐔
There was a problem hiding this comment.
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 💤
lib/WP_Auth0_LoginManager.php
Outdated
@@ -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 ); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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).
There was a problem hiding this comment.
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() ); |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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; |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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() { |
There was a problem hiding this comment.
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.
There was a problem hiding this 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.
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:
WP_Auth0_State_Handler
class used to generate, store, and validate a state nonce using cookiesWP_Auth0_LoginManager->die_on_login()
method to handling error message display for login errorsauth0-singlelogout-handler.php
to not pull Lock options and skip anything related to state