From 7a60b8c5e1b00282ff3ef738224faa1b320bba54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bojan=20=C4=8Cekrli=C4=87?= Date: Thu, 11 Aug 2016 16:29:09 +0200 Subject: [PATCH] Lots of updates to this plugin. The plugin now has the following features: - It's possible to use a 3rd-party OAuth provider. Additional configuration has been added to configure the details - It's possible to link all 3rd-party logins to the same Wordpress user. Especially useful if you only need to have the users logged in but don't care much about their identities (e.g. useful if you use a plugin such as "Force Login") - If there's only one provider defined *AND* you disable the default login form of Wordpress, the user will be automatically redirected to this provider. This esentially eliminates the Wordpress login page and relies on the 3rd-party provider only. For example, if you enable only Facebook, clicking on "Login" will take the user directly to Facebook "authorize application" page. - Lots of small fixes; e.g. admin page now has full width input boxes, which make long URLs much easier to handle. --- login-custom.php | 12 ++++++-- register.php | 2 +- wp-oauth-settings.php | 71 ++++++++++++++++++++++++++++--------------- wp-oauth.php | 71 +++++++++++++++++++++++++++++++++++-------- 4 files changed, 114 insertions(+), 42 deletions(-) diff --git a/login-custom.php b/login-custom.php index 1b47b85..4e3b652 100644 --- a/login-custom.php +++ b/login-custom.php @@ -221,21 +221,27 @@ function get_oauth_identity($wpoa) { $oauth_identity = array(); $oauth_identity['provider'] = $_SESSION['WPOA']['PROVIDER']; /* + Response example from Keycloack { "name": "Admin User", "sub": "88dd0538-5f32-4222-af07-efe5cd809038", - "preferred_username": "admin@ibxgaming.com", + "preferred_username": "admin@example.com", "given_name": "Admin", "family_name": "User", "email": "admin@ibxgaming.com" } */ $objtype = get_option('wpoa_custom_api_identity_id'); + if ($objtype == null || $objtype == false || $objtype == '') { + $objtype = 'id'; + } + $oauth_identity['id'] = $result_obj[$objtype]; + $objtype = get_option('wpoa_custom_api_identity_preferred_username'); if ($objtype == null || $objtype == false || $objtype == '') { $objtype = 'preferred_username'; } - $oauth_identity['id'] = $result_obj[$objtype]; // PROVIDER SPECIFIC: Google returns the user's OAuth identity as id - //$oauth_identity['email'] = $result_obj['emails'][0]['value']; // PROVIDER SPECIFIC: Google returns an array of email addresses. To respect privacy we currently don't collect the user's email address. + $oauth_identity['preferred_username'] = $result_obj[$objtype]; + if (!$oauth_identity['id']) { // $wpoa->wpoa_end_login("Sorry, we couldn't log you in. User identity was not found: " . $_SESSION['WPOA']['ACCESS_TOKEN']); $wpoa->wpoa_end_login("Sorry, we could not log you in. User identity was not found. Please notify the admin or try again later."); diff --git a/register.php b/register.php index 8629068..aa983c7 100644 --- a/register.php +++ b/register.php @@ -1 +1 @@ -get_error_message(); header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } // now try to update the username to something more permanent and recognizable: $username = "user" . $user_id; $update_username_result = $wpdb->update($wpdb->users, array('user_login' => $username, 'user_nicename' => $username, 'display_name' => $username), array('ID' => $user_id)); $update_nickname_result = update_user_meta($user_id, 'nickname', $username); // apply the custom default user role: $role = get_option('wpoa_new_user_role'); $update_role_result = wp_update_user(array('ID' => $user_id, 'role' => $role)); // proceed if no errors were detected: if ($update_username_result == false || $update_nickname_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not rename the username during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } elseif ($update_role_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not assign default user role during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } else { // registration was successful, the user account was created, proceed to login the user automatically... // associate the wordpress user account with the now-authenticated third party account: $this->wpoa_link_account($user_id); // attempt to login the new user (this could be error prone): $creds = array(); $creds['user_login'] = $username; $creds['user_password'] = $password; $creds['remember'] = true; $user = wp_signon( $creds, false ); // send a notification e-mail to the admin and the new user (we can also build our own email if necessary): if (!get_option('wpoa_suppress_welcome_email')) { //wp_mail($username, "New User Registration", "Thank you for registering!\r\nYour username: " . $username . "\r\nYour password: " . $password, $headers); wp_new_user_notification( $user_id, $password ); } // finally redirect the user back to the page they were on and notify them of successful registration: $_SESSION["WPOA"]["RESULT"] = "You have been registered successfully!"; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } ?> \ No newline at end of file +get_error_message(); header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } // now try to update the username to something more permanent and recognizable: $username = "user" . $user_id; $update_username_result = $wpdb->update($wpdb->users, array('user_login' => $username, 'user_nicename' => $username, 'display_name' => $username), array('ID' => $user_id)); $update_nickname_result = update_user_meta($user_id, 'nickname', $username); // apply the custom default user role: $role = get_option('wpoa_new_user_role'); $update_role_result = wp_update_user(array('ID' => $user_id, 'role' => $role)); // proceed if no errors were detected: if ($update_username_result == false || $update_nickname_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not rename the username during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } elseif ($update_role_result == false) { // there was an error during registration, redirect and notify the user: $_SESSION["WPOA"]["RESULT"] = "Could not assign default user role during registration. Please contact an admin or try again later."; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } else { // registration was successful, the user account was created, proceed to login the user automatically... // associate the wordpress user account with the now-authenticated third party account: $this->wpoa_link_account($user_id); // attempt to login the new user (this could be error prone): $creds = array(); $creds['user_login'] = $username; $creds['user_password'] = $password; $creds['remember'] = true; $user = wp_signon( $creds, false ); // send a notification e-mail to the admin and the new user (we can also build our own email if necessary): if (!get_option('wpoa_suppress_welcome_email')) { //wp_mail($username, "New User Registration", "Thank you for registering!\r\nYour username: " . $username . "\r\nYour password: " . $password, $headers); wp_new_user_notification( $user_id, $password ); } // finally redirect the user back to the page they were on and notify them of successful registration: $_SESSION["WPOA"]["RESULT"] = "You have been registered successfully!"; header("Location: " . $_SESSION["WPOA"]["LAST_URL"]); exit; } ?> \ No newline at end of file diff --git a/wp-oauth-settings.php b/wp-oauth-settings.php index e403571..9973413 100644 --- a/wp-oauth-settings.php +++ b/wp-oauth-settings.php @@ -481,6 +481,20 @@ function wpoa_cc_ux() {

Specifies what user role will be assigned to newly registered users.

+ + + Link new users to the following WordPress user: [?] + + get_option('wpoa_new_user'), + 'include_selected' => true, + 'show_option_none' => '- disable -', + 'name' => 'wpoa_new_user' + )); ?> +

If you disable registrations on your web site, you can link all new users to the same WordPress user this way. If you deselect this option, a new user will be created for every 3rd-party login.

+ + + @@ -502,14 +516,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -543,28 +557,28 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> OAuth Server Endpoint: - ' /> + ' /> Login Button Text: - ' /> + ' /> @@ -599,14 +613,14 @@ function wpoa_cc_ux() { App ID: - ' /> + ' /> App Secret: - ' /> + ' /> @@ -639,14 +653,14 @@ function wpoa_cc_ux() { API Key: - ' /> + ' /> Secret Key: - ' /> + ' /> @@ -679,14 +693,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -719,14 +733,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -758,14 +772,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -798,14 +812,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -846,14 +860,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -888,14 +902,14 @@ function wpoa_cc_ux() { Client ID: - ' /> + ' /> Client Secret: - ' /> + ' /> @@ -934,14 +948,14 @@ function wpoa_cc_ux() { Key: - ' /> + ' /> Secret: - ' /> + ' /> @@ -1022,12 +1036,19 @@ function wpoa_cc_ux() { - UserInfo element (usually 'id' or 'username'): + UserInfo element for unique ID (usually 'id' or 'username'): ' /> + + UserInfo element for preffered username (usually 'username' or 'preferred_username'): + + ' /> + + +

diff --git a/wp-oauth.php b/wp-oauth.php index f6906d3..21f1162 100644 --- a/wp-oauth.php +++ b/wp-oauth.php @@ -24,6 +24,19 @@ // set a version that we can use for performing plugin updates, this should always match the plugin version: const PLUGIN_VERSION = "0.4.1.1"; + static $WPOA_LOGIN_PROVIDERS = array( + "google" => "Google", + "facebook" => "Facebook", + "linkedin" => "LinkedIn", + "github" => "GitHub", + "itembase" => "itembase", + "reddit" => "Reddit", + "windowslive" => "Windows Live", + "paypal" => "PayPal", + "instagram" => "Instagram", + "battlenet" => "Battlenet", + "custom" => "Other" + ); // singleton class pattern: protected static $instance = NULL; @@ -81,6 +94,7 @@ public static function get_instance() { ), 'wpoa_suppress_welcome_email' => 0, // 0, 1 'wpoa_new_user_role' => 'contributor', // role + 'wpoa_new_user' => null, // default new user 'wpoa_google_api_enabled' => 0, // 0, 1 'wpoa_google_api_id' => '', // any string 'wpoa_google_api_secret' => '', // any string @@ -120,6 +134,7 @@ public static function get_instance() { 'wpoa_custom_api_token_url' => '', // any string 'wpoa_custom_api_user_url' => '', // any string 'wpoa_custom_api_identity_id' => '', // any string + 'wpoa_custom_api_identity_preferred_username' => '', // any string 'wpoa_oauth_server_api_enabled' => 0, // 0, 1 'wpoa_oauth_server_api_id' => '', // any string 'wpoa_oauth_server_api_secret' => '', // any string @@ -219,9 +234,13 @@ function wpoa_restore_default_settings_notice() { // initialize the plugin's functionality by hooking into wordpress: function init() { + // restore default settings if necessary; this might get toggled by the admin or forced by a new version of the plugin: if (get_option("wpoa_restore_default_settings")) {$this->wpoa_restore_default_settings();} // hook the query_vars and template_redirect so we can stay within the wordpress context no matter what (avoids having to use wp-load.php) + + $this->wpoa_login_redirect_if_single_provider(); + add_filter('query_vars', array($this, 'wpoa_qvar_triggers')); add_action('template_redirect', array($this, 'wpoa_qvar_handlers')); // hook scripts and styles for frontend pages: @@ -370,6 +389,27 @@ function wpoa_qvar_triggers($vars) { return $vars; } + // Redirect users to the provider if there's only single provider (and login form is disabled) + function wpoa_login_redirect_if_single_provider() { + if ( $_SERVER['REQUEST_METHOD'] == 'GET' && (is_page( 'login' ) || $GLOBALS['pagenow'] === 'wp-login.php' || in_array( $_SERVER['PHP_SELF'], array( '/wp-login.php', '/wp-register.php' ) )) ) { + // We're on the login page! + // Check if we only have one provider + $count = 0; + $provider = ""; + foreach (self::$WPOA_LOGIN_PROVIDERS as $key => $value) { + if (get_option("wpoa_" . $key . "_api_enabled")) { + $count = $count + 1; + $provider = $key; + } + } + if ( $count == 1 && get_option("wpoa_hide_wordpress_login_form") == 1) { + $_SESSION['WPOA']['PROVIDER'] = $provider; + $this->wpoa_include_connector($provider); + return; + } + } + } + // handle the querystring triggers: function wpoa_qvar_handlers() { if (get_query_var('connect')) { @@ -420,6 +460,7 @@ function wpoa_login_user($oauth_identity) { $_SESSION["WPOA"]["USER_ID"] = $oauth_identity["id"]; // try to find a matching wordpress user for the now-authenticated user's oauth identity: $matched_user = $this->wpoa_match_wordpress_user($oauth_identity); + $mapped_user = false; // handle the matched user if there is one: if ( $matched_user ) { // there was a matching wordpress user account, log it in now: @@ -430,6 +471,18 @@ function wpoa_login_user($oauth_identity) { do_action( 'wp_login', $user_login, $matched_user ); // after login, redirect to the user's last location $this->wpoa_end_login("Logged in successfully!"); + $mapped_user = true; + } else if(get_option("wpoa_new_user")!=null && get_option("wpoa_new_user") != '' && get_option("wpoa_new_user") != -1 && get_userdata(get_option("wpoa_new_user")) != false) { + $_SESSION["WPOA"]["USER_ID"] = get_option("wpoa_new_user"); + + $user_id = $_SESSION["WPOA"]["USER_ID"]; + $user_login = get_userdata($user_id)->user_login; + wp_set_current_user( $user_id, $user_login ); + wp_set_auth_cookie( $user_id ); + do_action( 'wp_login', $user_login, $matched_user ); + // after login, redirect to the user's last location + $this->wpoa_end_login("Logged in successfully as " . $user_login . "!"); + $mapped_user = true; } // handle the already logged in user if there is one: if ( is_user_logged_in() ) { @@ -442,8 +495,9 @@ function wpoa_login_user($oauth_identity) { $this->wpoa_end_login("Your account was linked successfully with your third party authentication provider."); } // handle the logged out user or no matching user (register the user): - if ( !is_user_logged_in() && !$matched_user ) { + if ( !is_user_logged_in() && !$mapped_user ) { // this person is not logged into a wordpress account and has no third party authentications registered, so proceed to register the wordpress user: + $_SESSION["WPOA"]["PREFERRED_USERNAME"] = $oauth_identity["preferred_username"]; include 'register.php'; } // we shouldn't be here, but just in case... @@ -726,19 +780,10 @@ function wpoa_login_buttons($icon_set, $button_prefix) { 'button_prefix' => $button_prefix, ); // generate the login buttons for available providers: - // TODO: don't hard-code the buttons/providers here, we want to be able to add more providers without having to update this function... $html = ""; - $html .= $this->wpoa_login_button("google", "Google", $atts); - $html .= $this->wpoa_login_button("facebook", "Facebook", $atts); - $html .= $this->wpoa_login_button("linkedin", "LinkedIn", $atts); - $html .= $this->wpoa_login_button("github", "GitHub", $atts); - $html .= $this->wpoa_login_button("itembase", "itembase", $atts); - $html .= $this->wpoa_login_button("reddit", "Reddit", $atts); - $html .= $this->wpoa_login_button("windowslive", "Windows Live", $atts); - $html .= $this->wpoa_login_button("paypal", "PayPal", $atts); - $html .= $this->wpoa_login_button("instagram", "Instagram", $atts); - $html .= $this->wpoa_login_button("battlenet", "Battlenet", $atts); - $html .= $this->wpoa_login_button("custom", "Other", $atts); + foreach (self::$WPOA_LOGIN_PROVIDERS as $key => $value) { + $html .= $this->wpoa_login_button($key, $value, $atts); + } $html .= $this->wpoa_login_button( 'oauth_server' , get_option( 'wpoa_oauth_server_api_button_text' ), $atts ); if ($html == '') { $html .= 'Sorry, no login providers have been enabled.';