From bb63442774f110151acdc9214b1269fa34de5fa2 Mon Sep 17 00:00:00 2001 From: SYLVAIN PAILLASSE Date: Sun, 12 Apr 2020 15:32:37 +0200 Subject: [PATCH] Add new setting for Password Reset policy (Azure AD B2C). --- .../openid-connect-generic-client-wrapper.php | 32 +++++++++++++++++++ includes/openid-connect-generic-client.php | 27 +++++++++++++++- .../openid-connect-generic-settings-page.php | 7 ++++ openid-connect-generic.php | 2 ++ 4 files changed, 67 insertions(+), 1 deletion(-) diff --git a/includes/openid-connect-generic-client-wrapper.php b/includes/openid-connect-generic-client-wrapper.php index e3774fee..28b052c8 100644 --- a/includes/openid-connect-generic-client-wrapper.php +++ b/includes/openid-connect-generic-client-wrapper.php @@ -103,6 +103,15 @@ function get_authentication_url(){ return $this->client->make_authentication_url(); } + /** + * Get the PasswordReset url from the client + * + * @return string + */ + function get_passwordreset_url(){ + return $this->client->make_passwordreset_url(); + } + /** * Handle retrieval and validation of refresh_token */ @@ -278,6 +287,29 @@ function authentication_request_callback() { $authentication_request = $client->validate_authentication_request( $_GET ); if ( is_wp_error( $authentication_request ) ){ + // Manage Password Reset case + if (strpos($authentication_request->error_data['no-code']['error_description'], 'AADB2C90118') === 0) { // The user has forgotten their password. + $this->logger->log( "AADB2C90118" ); + wp_redirect( $this->get_passwordreset_url() ); + exit; + } elseif (strpos($authentication_request->error_data['no-code']['error_description'], 'AADB2C90091') === 0) { // Cancel Password Reset & SignUp + $this->logger->log( "AADB2C90091" ); + // redirect back to the origin page if enabled + $redirect_url = isset( $_COOKIE[ $this->cookie_redirect_key ] ) ? esc_url_raw( $_COOKIE[ $this->cookie_redirect_key ] ) : false; + + if( $this->settings->redirect_user_back && !empty( $redirect_url ) ) { + do_action( 'openid-connect-generic-redirect-user-back', $redirect_url, $user ); + setcookie( $this->cookie_redirect_key, $redirect_url, 1, COOKIEPATH, COOKIE_DOMAIN, is_ssl() ); + $this->logger->log( "Redirect to redirect_user_back: {$redirect_url}" ); + wp_redirect( $redirect_url ); + } + // otherwise, go home! + else { + $this->logger->log( "Redirect to home: ".home_url() ); + wp_redirect( home_url() ); + } + exit; + } $this->error_redirect( $authentication_request ); } diff --git a/includes/openid-connect-generic-client.php b/includes/openid-connect-generic-client.php index 916ef04c..2959ef22 100644 --- a/includes/openid-connect-generic-client.php +++ b/includes/openid-connect-generic-client.php @@ -8,6 +8,7 @@ class OpenID_Connect_Generic_Client { private $endpoint_login; private $endpoint_userinfo; private $endpoint_token; + private $endpoint_passreset; // login flow "ajax" endpoint private $redirect_uri; @@ -24,16 +25,18 @@ class OpenID_Connect_Generic_Client { * @param $endpoint_login * @param $endpoint_userinfo * @param $endpoint_token + * @param $endpoint_passreset * @param $redirect_uri * @param $state_time_limit time states are valid in seconds */ - function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $redirect_uri, $state_time_limit){ + function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $endpoint_passreset, $redirect_uri, $state_time_limit){ $this->client_id = $client_id; $this->client_secret = $client_secret; $this->scope = $scope; $this->endpoint_login = $endpoint_login; $this->endpoint_userinfo = $endpoint_userinfo; $this->endpoint_token = $endpoint_token; + $this->endpoint_passreset = $endpoint_passreset; $this->redirect_uri = $redirect_uri; $this->state_time_limit = $state_time_limit; } @@ -60,6 +63,28 @@ function make_authentication_url() { return apply_filters( 'openid-connect-generic-auth-url', $url ); } + /** + * Create a single use PasswordReset url + * + * @return string + */ + function make_passwordreset_url() { + $separator = '?'; + if ( stripos( $this->endpoint_passreset, '?' ) !== FALSE ) { + $separator = '&'; + } + $url = sprintf( '%1$s%2$sresponse_type=code&scope=%3$s&client_id=%4$s&state=%5$s&redirect_uri=%6$s', + $this->endpoint_passreset, + $separator, + urlencode( $this->scope ), + urlencode( $this->client_id ), + $this->new_state(), + urlencode( $this->redirect_uri ) + ); + + return apply_filters( 'openid-connect-generic-auth-url', $url ); + } + /** * Validate the request for login authentication * diff --git a/includes/openid-connect-generic-settings-page.php b/includes/openid-connect-generic-settings-page.php index 53bb07c9..cacedcb6 100644 --- a/includes/openid-connect-generic-settings-page.php +++ b/includes/openid-connect-generic-settings-page.php @@ -89,6 +89,13 @@ function __construct( OpenID_Connect_Generic_Option_Settings $settings, OpenID_C 'type' => 'text', 'section' => 'client_settings', ), + 'endpoint_passreset' => array( + 'title' => __( 'Password Reset Endpoint URL' ), + 'description' => __( 'Identify provider password reset endpoint.' ), + 'example' => 'https://example.com/oauth2/authorize', + 'type' => 'text', + 'section' => 'client_settings', + ), 'endpoint_end_session' => array( 'title' => __( 'End Session Endpoint URL' ), 'description' => __( 'Identify provider logout endpoint.' ), diff --git a/openid-connect-generic.php b/openid-connect-generic.php index d182f0f3..1c016914 100644 --- a/openid-connect-generic.php +++ b/openid-connect-generic.php @@ -97,6 +97,7 @@ function init(){ $this->settings->endpoint_login, $this->settings->endpoint_userinfo, $this->settings->endpoint_token, + $this->settings->endpoint_passreset, $redirect_uri, $state_time_limit ); @@ -259,6 +260,7 @@ static public function bootstrap(){ 'endpoint_login' => '', 'endpoint_userinfo' => '', 'endpoint_token' => '', + 'endpoint_passreset' => '', 'endpoint_end_session' => '', // non-standard settings