diff --git a/WP_Auth0.php b/WP_Auth0.php
index 0b5696fe..7f8af345 100644
--- a/WP_Auth0.php
+++ b/WP_Auth0.php
@@ -2,7 +2,7 @@
/**
* Plugin Name: Wordpress Auth0 Integration
* Description: Implements the Auth0 Single Sign On solution into Wordpress
- * Version: 1.2.5
+ * Version: 1.2.6
* Author: Auth0
* Author URI: https://auth0.com
*/
@@ -12,10 +12,10 @@
define('WPA0_PLUGIN_URL', trailingslashit(plugin_dir_url(__FILE__) ));
define('WPA0_LANG', 'wp-auth0');
define('AUTH0_DB_VERSION', 2);
-define('WPA0_VERSION', '1.2.5');
+define('WPA0_VERSION', '1.2.6');
class WP_Auth0 {
- public static function init(){
+ public static function init(){
spl_autoload_register(array(__CLASS__, 'autoloader'));
// WP_Auth0_Referer_Check::init();
@@ -63,6 +63,7 @@ public static function init(){
add_action( 'wp_footer', array( __CLASS__, 'a0_render_message' ) );
}
+ WP_Auth0_UsersRepo::init();
WP_Auth0_Settings_Section::init();
WP_Auth0_Admin::init();
WP_Auth0_ErrorLog::init();
@@ -99,7 +100,7 @@ public static function isJWTConfigured() {
JWT_AUTH_Options::get('aud') == WP_Auth0_Options::get('client_id') &&
JWT_AUTH_Options::get('secret') == WP_Auth0_Options::get('client_secret') &&
JWT_AUTH_Options::get('secret_base64_encoded') &&
- JWT_AUTH_Options::get('override_user_repo') == 'WP_Auth0_UsersRepo' &&
+ WP_Auth0_Options::get('jwt_auth_integration') &&
JWT_AUTH_Options::get('jwt_attribute') == 'sub'
);
@@ -387,7 +388,7 @@ public static function init_auth0(){
}
$userinfo = json_decode( $response['body'] );
- if (self::login_user($userinfo, $data)) {
+ if (self::login_user($userinfo, $data->id_token)) {
if ($stateFromGet !== null && isset($stateFromGet->interim) && $stateFromGet->interim) {
include WPA0_PLUGIN_DIR . 'templates/login-interim.php';
exit();
@@ -455,23 +456,6 @@ private static function findAuth0User($id) {
return $user;
}
- private static function insertAuth0User($userinfo, $user_id) {
- global $wpdb;
- $wpdb->insert(
- $wpdb->auth0_user,
- array(
- 'auth0_id' => $userinfo->user_id,
- 'wp_id' => $user_id,
- 'auth0_obj' => serialize($userinfo)
- ),
- array(
- '%s',
- '%d',
- '%s'
- )
- );
- }
-
public static function insertAuth0Error($section, $wp_error) {
if ($wp_error instanceof WP_Error) {
@@ -519,11 +503,11 @@ public static function delete_user ($user_id) {
$wpdb->delete( $wpdb->auth0_user, array( 'wp_id' => $user_id), array( '%d' ) );
}
- private static function dieWithVerifyEmail($userinfo, $data) {
+ private static function dieWithVerifyEmail($userinfo, $id_token) {
ob_start();
$domain = WP_Auth0_Options::get( 'domain' );
- $token = $data->id_token;
+ $token = $id_token;
$email = $userinfo->email;
$connection = $userinfo->identities[0]->connection;
$userId = $userinfo->user_id;
@@ -534,7 +518,7 @@ private static function dieWithVerifyEmail($userinfo, $data) {
wp_die($html);
}
- private static function login_user( $userinfo, $data ){
+ public static function login_user( $userinfo, $id_token ){
// If the userinfo has no email or an unverified email, and in the options we require a verified email
// notify the user he cant login until he does so.
$requires_verified_email = WP_Auth0_Options::get( 'requires_verified_email' );
@@ -548,10 +532,8 @@ private static function login_user( $userinfo, $data ){
wp_die($msg);
}
-
-
if (!$userinfo->email_verified) {
- self::dieWithVerifyEmail($userinfo, $data);
+ self::dieWithVerifyEmail($userinfo, $id_token);
}
}
@@ -564,69 +546,31 @@ private static function login_user( $userinfo, $data ){
wp_set_auth_cookie( $user->ID );
return true;
} else {
- // If the user doesn't exist we need to either create a new one, or asign him to an existing one
- $isDatabaseUser = false;
- foreach ($userinfo->identities as $identity) {
- if ($identity->provider == "auth0") {
- $isDatabaseUser = true;
- }
- }
- $joinUser = null;
- // If the user has a verified email or is a database user try to see if there is
- // a user to join with. The isDatabase is because we don't want to allow database
- // user creation if there is an existing one with no verified email
-
- if (isset($userinfo->email) && ((isset($userinfo->email_verified) && $userinfo->email_verified) || $isDatabaseUser)) {
- $joinUser = get_user_by( 'email', $userinfo->email );
- }
- // $auto_provisioning = WP_Auth0_Options::get('auto_provisioning');
- // $allow_signup = WP_Auth0_Options::is_wp_registration_enabled() || $auto_provisioning;
- $allow_signup = WP_Auth0_Options::is_wp_registration_enabled();
+ try {
+ $creator = new WP_Auth0_UserCreator();
+ $user_id = $creator->create($userinfo, $id_token);
- if (!is_null($joinUser) && $joinUser instanceof WP_User) {
- // If we are here, we have a potential join user
- // Don't allow creation or assignation of user if the email is not verified, that would
- // be hijacking
- if (!$userinfo->email_verified) {
- self::dieWithVerifyEmail($userinfo, $data);
- }
- $user_id = $joinUser->ID;
- } elseif ($allow_signup) {
- // If we are here, we need to create the user
- $user_id = WP_Auth0_Users::create_user($userinfo);
-
- // Check if user was created
-
- if( is_wp_error($user_id) ) {
- $msg = __('Error: Could not create user.', WPA0_LANG);
- $msg = ' ' . $user_id->get_error_message();
- $msg .= '
';
- $msg .= '' . __('← Go back', WPA0_LANG) . '';
- wp_die($msg);
-
- }elseif($user_id == -2){
- $msg = __('Error: Could not create user. The registration process were rejected. Please verify that your account is whitelisted for this system.', WPA0_LANG);
- $msg .= '
';
- $msg .= '' . __('← Go back', WPA0_LANG) . '';
-
- wp_die($msg);
- }elseif ($user_id <0){
- $msg = __('Error: Could not create user.', WPA0_LANG);
- $msg .= '
';
- $msg .= '' . __('← Go back', WPA0_LANG) . '';
- wp_die($msg);
- }
- } else {
+ wp_set_auth_cookie( $user_id );
+ }
+ catch (WP_Auth0_CouldNotCreateUserException $e) {
+ $msg = __('Error: Could not create user.', WPA0_LANG);
+ $msg = ' ' . $e->getMessage();
+ $msg .= '
';
+ $msg .= '' . __('← Go back', WPA0_LANG) . '';
+ wp_die($msg);
+ }
+ catch (WP_Auth0_RegistrationNotEnabledException $e) {
$msg = __('Error: Could not create user. The registration process is not available.', WPA0_LANG);
$msg .= '
';
$msg .= '' . __('← Go back', WPA0_LANG) . '';
wp_die($msg);
}
- // If we are here we should have a valid $user_id with a new user or an existing one
- // log him in, and update the auth0_user table
- self::insertAuth0User($userinfo, $user_id);
- wp_set_auth_cookie( $user_id );
+ catch (WP_Auth0_EmailNotVerifiedException $e) {
+ self::dieWithVerifyEmail($e->userinfo, $e->id_token);
+ }
+
+
return true;
}
}
@@ -787,6 +731,7 @@ private static function autoloader($class){
$paths[] = $path;
$paths[] = $path.'lib/';
+ $paths[] = $path.'lib/exceptions/';
foreach($paths as $p)
foreach($exts as $ext){
diff --git a/lib/WP_Auth0_Admin.php b/lib/WP_Auth0_Admin.php
index 0dab80b9..13764150 100755
--- a/lib/WP_Auth0_Admin.php
+++ b/lib/WP_Auth0_Admin.php
@@ -72,7 +72,7 @@ public static function init_admin(){
/* ------------------------- ADVANCED ------------------------- */
- self::init_option_section('Advanced', array(
+ $advancedOptions = array(
array('id' => 'wpa0_dict', 'name' => 'Translation', 'function' => 'render_dict'),
array('id' => 'wpa0_username_style', 'name' => 'Username style', 'function' => 'render_username_style'),
@@ -89,7 +89,16 @@ public static function init_admin(){
array('id' => 'wpa0_extra_conf', 'name' => 'Extra settings', 'function' => 'render_extra_conf'),
array('id' => 'wpa0_cdn_url', 'name' => 'Widget URL', 'function' => 'render_cdn_url'),
- ));
+ );
+
+
+
+ if (WP_Auth0::isJWTAuthEnabled()) {
+ $advancedOptions[] = array('id' => 'wpa0_jwt_auth_integration', 'name' => 'Enable JWT Auth integration', 'function' => 'render_jwt_auth_integration');
+ }
+
+ self::init_option_section('Advanced', $advancedOptions);
+
register_setting(WP_Auth0_Options::OPTIONS_NAME, WP_Auth0_Options::OPTIONS_NAME, array(__CLASS__, 'input_validator'));
}
@@ -107,6 +116,11 @@ public static function render_remember_last_login () {
echo '';
echo '
' . __('Request for SSO data and enable Last time you signed in with[...] message.', WPA0_LANG) . '' . __('More info', WPA0_LANG) . '';
}
+ public static function render_jwt_auth_integration () {
+ $v = absint(WP_Auth0_Options::get( 'jwt_auth_integration' ));
+ echo '';
+ echo '
' . __('This will enable the JWT Auth\'s Users Repository override.', WPA0_LANG) . '';
+ }
public static function create_account_message(){
echo '
' @@ -301,6 +315,7 @@ public static function input_validator( $input ){ $input['requires_verified_email'] = (isset($input['requires_verified_email']) ? 1 : 0); $input['wordpress_login_enabled'] = (isset($input['wordpress_login_enabled']) ? 1 : 0); + $input['jwt_auth_integration'] = (isset($input['jwt_auth_integration']) ? 1 : 0); $input['allow_signup'] = (isset($input['allow_signup']) ? 1 : 0); $input['auth0_implicit_workflow'] = (isset($input['auth0_implicit_workflow']) ? 1 : 0); diff --git a/lib/WP_Auth0_Api_Client.php b/lib/WP_Auth0_Api_Client.php index 6b53e639..e39ee90e 100644 --- a/lib/WP_Auth0_Api_Client.php +++ b/lib/WP_Auth0_Api_Client.php @@ -63,4 +63,17 @@ public static function get_user_info($domain, $access_token) { } + public static function get_user($domain, $jwt, $user_id) { + $endpoint = "https://$domain/api/v2/users/" . urlencode($user_id); + + $headers = self::get_info_headers(); + + $headers['Authorization'] = "Bearer $jwt"; + + return wp_remote_get( $endpoint , array( + 'headers' => $headers + )); + + } + } \ No newline at end of file diff --git a/lib/WP_Auth0_Configure_JWTAUTH.php b/lib/WP_Auth0_Configure_JWTAUTH.php index 8ee033fe..49416b9a 100644 --- a/lib/WP_Auth0_Configure_JWTAUTH.php +++ b/lib/WP_Auth0_Configure_JWTAUTH.php @@ -31,12 +31,11 @@ public static function render_settings_page(){ protected static function setupjwt() { if(WP_Auth0::isJWTAuthEnabled()) { - global $wpdb; - JWT_AUTH_Options::set('aud', WP_Auth0_Options::get('client_id')); JWT_AUTH_Options::set('secret', WP_Auth0_Options::get('client_secret')); JWT_AUTH_Options::set('secret_base64_encoded', true); JWT_AUTH_Options::set('override_user_repo', 'WP_Auth0_UsersRepo'); + WP_Auth0_Options::set('jwt_auth_integration', true); } } diff --git a/lib/WP_Auth0_Options.php b/lib/WP_Auth0_Options.php index 4bdbdff2..91b8787d 100755 --- a/lib/WP_Auth0_Options.php +++ b/lib/WP_Auth0_Options.php @@ -61,6 +61,7 @@ private static function defaults(){ 'custom_css' => '', 'auth0_implicit_workflow' => false, 'gravatar' => true, + 'jwt_auth_integration' => false, // 'auto_provisioning' => true, 'default_login_redirection' => home_url(), ); diff --git a/lib/WP_Auth0_UserCreator.php b/lib/WP_Auth0_UserCreator.php new file mode 100644 index 00000000..c2f1f728 --- /dev/null +++ b/lib/WP_Auth0_UserCreator.php @@ -0,0 +1,86 @@ +email) || isset($jwt->nickname)) + && isset($jwt->identities) + ); + + } + + public function create($userinfo, $token) { + + // If the user doesn't exist we need to either create a new one, or asign him to an existing one + $isDatabaseUser = false; + foreach ($userinfo->identities as $identity) { + if ($identity->provider == "auth0") { + $isDatabaseUser = true; + } + } + $joinUser = null; + // If the user has a verified email or is a database user try to see if there is + // a user to join with. The isDatabase is because we don't want to allow database + // user creation if there is an existing one with no verified email + + if (isset($userinfo->email) && ((isset($userinfo->email_verified) && $userinfo->email_verified) || $isDatabaseUser)) { + $joinUser = get_user_by( 'email', $userinfo->email ); + } + + // $auto_provisioning = WP_Auth0_Options::get('auto_provisioning'); + // $allow_signup = WP_Auth0_Options::is_wp_registration_enabled() || $auto_provisioning; + $allow_signup = WP_Auth0_Options::is_wp_registration_enabled(); + + if (!is_null($joinUser) && $joinUser instanceof WP_User) { + // If we are here, we have a potential join user + // Don't allow creation or assignation of user if the email is not verified, that would + // be hijacking + if (!$userinfo->email_verified) { + throw new WP_Auth0_EmailNotVerifiedException($userinfo, $token); + } + $user_id = $joinUser->ID; + } elseif ($allow_signup) { + // If we are here, we need to create the user + $user_id = WP_Auth0_Users::create_user($userinfo); + + // Check if user was created + + if( is_wp_error($user_id) ) { + throw new WP_Auth0_CouldNotCreateUserException($user_id->get_error_message()); + }elseif($user_id == -2){ + throw new WP_Auth0_CouldNotCreateUserException('Could not create user. The registration process were rejected. Please verify that your account is whitelisted for this system.'); + }elseif ($user_id <0){ + throw new WP_Auth0_CouldNotCreateUserException(); + } + } else { + throw new WP_Auth0_RegistrationNotEnabledException(); + } + + // If we are here we should have a valid $user_id with a new user or an existing one + // log him in, and update the auth0_user table + self::insertAuth0User($userinfo, $user_id); + + return $user_id; + + } + + public function insertAuth0User($userinfo, $user_id) { + global $wpdb; + $wpdb->insert( + $wpdb->auth0_user, + array( + 'auth0_id' => $userinfo->user_id, + 'wp_id' => $user_id, + 'auth0_obj' => serialize($userinfo) + ), + array( + '%s', + '%d', + '%s' + ) + ); + } + +} \ No newline at end of file diff --git a/lib/WP_Auth0_UsersRepo.php b/lib/WP_Auth0_UsersRepo.php index 75d25fe4..85425c39 100644 --- a/lib/WP_Auth0_UsersRepo.php +++ b/lib/WP_Auth0_UsersRepo.php @@ -2,7 +2,14 @@ class WP_Auth0_UsersRepo { - public static function getUser($jwt) { + public static function init() { + if (WP_Auth0_Options::get('jwt_auth_integration') == 1) { + add_filter( 'wp_jwt_auth_get_user', array( __CLASS__, 'getUser' ), 0,2); + } + } + + public static function getUser($jwt, $encodedJWT) { + global $wpdb; $sql = 'SELECT u.* @@ -13,14 +20,44 @@ public static function getUser($jwt) { $userRow = $wpdb->get_row($wpdb->prepare($sql, $jwt->sub)); if (is_null($userRow)) { + + $domain = WP_Auth0_Options::get( 'domain' ); + + $response = WP_Auth0_Api_Client::get_user($domain, $encodedJWT, $jwt->sub); + + if ($response['response']['code'] != 200) return null; + + $creator = new WP_Auth0_UserCreator(); + + if ($creator->tokenHasRequiredScopes($jwt)) { + $auth0User = $jwt; + } + else { + $auth0User = json_decode($response['body']); + } + + try { + $user_id = $creator->create($auth0User,$encodedJWT); + + return new WP_User($user_id); + } + catch (WP_Auth0_CouldNotCreateUserException $e) { + return null; + } + catch (WP_Auth0_RegistrationNotEnabledException $e) { + return null; + } + return null; }elseif($userRow instanceof WP_Error ) { self::insertAuth0Error('findAuth0User',$userRow); return null; + }else{ + $user = new WP_User(); + $user->init($userRow); + return $user; } - $user = new WP_User(); - $user->init($userRow); - return $user; + } diff --git a/lib/exceptions/WP_Auth0_CouldNotCreateUserException.php b/lib/exceptions/WP_Auth0_CouldNotCreateUserException.php new file mode 100644 index 00000000..bf6264c2 --- /dev/null +++ b/lib/exceptions/WP_Auth0_CouldNotCreateUserException.php @@ -0,0 +1,3 @@ +userinfo = $userinfo; + $this->id_token = $id_token; + } + +} \ No newline at end of file diff --git a/lib/exceptions/WP_Auth0_RegistrationNotEnabledException.php b/lib/exceptions/WP_Auth0_RegistrationNotEnabledException.php new file mode 100644 index 00000000..204e2870 --- /dev/null +++ b/lib/exceptions/WP_Auth0_RegistrationNotEnabledException.php @@ -0,0 +1,3 @@ +