summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2020-10-27 14:18:03 +0100
committerChristian Grothoff <christian@grothoff.org>2020-10-27 14:18:03 +0100
commit670b97c434d6bd5d3eab57d3497e45ead7746942 (patch)
treefaeb0a6ebd4d3179069d869b38dbabe28b361b90
parent0bfc2f4ef0216b92493e8485044686ea26142bf1 (diff)
downloadwoocommerce-taler-670b97c434d6bd5d3eab57d3497e45ead7746942.tar.gz
woocommerce-taler-670b97c434d6bd5d3eab57d3497e45ead7746942.tar.bz2
woocommerce-taler-670b97c434d6bd5d3eab57d3497e45ead7746942.zip
update plugin version
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/changelog.md43
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/composer.json123
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-client-wrapper.php582
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-client.php369
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-login-form.php149
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-option-logger.php178
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-option-settings.php179
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/includes/openid-connect-generic-settings-page.php509
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/openid-connect-generic.php210
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/readme.md43
-rw-r--r--[-rwxr-xr-x]daggerhart-openid-connect-generic/readme.txt36
-rw-r--r--server-build/my-simple-cdd/README5
12 files changed, 1603 insertions, 823 deletions
diff --git a/daggerhart-openid-connect-generic/changelog.md b/daggerhart-openid-connect-generic/changelog.md
index 4161c46..84c6295 100755..100644
--- a/daggerhart-openid-connect-generic/changelog.md
+++ b/daggerhart-openid-connect-generic/changelog.md
@@ -1,6 +1,47 @@
-
# OpenId Connect Generic Changelog
+3.8.0
+
+* Feature: @timnolte - Ability to use 6 new constants for setting client configuration instead of storing in the DB.
+* Improvement: @timnolte - NPM version requirements for development.
+* Improvement: @timnolte - Travis CI build fixes.
+* Improvement: @timnolte - GrumPHP configuration updates for code contributions.
+* Improvement: @timnolte - Refactored to meet WordPress coding standards.
+* Improvement: @timnolte - Refactored to provide localization.
+* Improvement: @timnolte - Refactored to provide a Docker-based local development environment.
+
+3.7.1
+
+* Fix: Release Version Number.
+
+3.7.0
+
+* Feature: @timnolte - Ability to enable/disable token refresh. Useful for IDPs that don't support token refresh.
+* Feature: @timnolte - Support custom redirect URL(`redirect_to`) with the authentication URL & login button shortcodes.
+ - Supports additional attribute overrides including login `button_text`, `endpoint_login`, `scope`, `redirect_uri`.
+
+3.6.0
+
+* Improvement: @RobjS - Improved error messages during login state failure.
+* Improvement: @RobjS - New developer filter for login form button URL.
+* Fix: @cs1m0n - Only increment username during new user creation if the "Link existing user" setting is enabled.
+* Fix: @xRy-42 - Allow periods and spaces in usernames to match what WordPress core allows.
+* Feature: @benochen - New setting named "Create user if does not exist" determines whether new users are created during login attempts.
+* Improvement: @flat235 - Username transliteration and normalization.
+
+3.5.1
+
+* Fix: @daggerhart - New approach to state management using transients.
+
+3.5.0
+
+* Readme fix: @thijskh - Fix syntax error in example openid-connect-generic-login-button-text
+* Feature: @slavicd - Allow override of the plugin by posting credentials to wp-login.php
+* Feature: @gassan - New action on use login
+* Fix: @daggerhart - Avoid double question marks in auth url query string
+* Fix: @drzraf - wp-cli bootstrap must not inhibit custom rewrite rules
+* Syntax change: @mullikine - Change PHP keywords to comply with PSR2
+
**3.4.1**
* Minor documentation update and additional error checking.
diff --git a/daggerhart-openid-connect-generic/composer.json b/daggerhart-openid-connect-generic/composer.json
index ea542b3..5b93c9e 100755..100644
--- a/daggerhart-openid-connect-generic/composer.json
+++ b/daggerhart-openid-connect-generic/composer.json
@@ -1,25 +1,102 @@
{
- "name": "daggerhart/openid-connect-generic",
- "type": "wordpress-plugin",
- "license": "GPL-2.0-only",
- "description": "OpenID Connect generic WordPress plugin.",
- "homepage": "https://github.com/daggerhart/openid-connect-generic",
- "authors": [
- {
- "name": "Jonathan Daggerhart",
- "email": "jonathan@daggerhart.com",
- "homepage": "https://github.com/daggerhart"
- }
- ],
- "keywords": [
- "wordpress",
- "openid"
- ],
- "support": {
- "issues": "https://github.com/daggerhart/openid-connect-generic/issues"
- },
- "require": {
- "php": ">=5.3.3",
- "composer/installers": "~1.0"
- }
+ "name": "daggerhart/openid-connect-generic",
+ "type": "wordpress-plugin",
+ "license": "GPL-2.0-only",
+ "description": "OpenID Connect generic WordPress plugin.",
+ "homepage": "https://github.com/daggerhart/openid-connect-generic",
+ "authors": [
+ {
+ "name": "Jonathan Daggerhart",
+ "email": "jonathan@daggerhart.com",
+ "homepage": "https://github.com/daggerhart"
+ },
+ {
+ "name": "Tim Nolte",
+ "email": "tim.nolte@ndigitals.com",
+ "homepage": "https://github.com/timnolte"
+ }
+ ],
+ "keywords": [
+ "wordpress",
+ "openid"
+ ],
+ "support": {
+ "issues": "https://github.com/daggerhart/openid-connect-generic/issues"
+ },
+ "config": {
+ "platform": {
+ "php": "7.3"
+ },
+ "optimize-autoloader": true
+ },
+ "repositories": [
+ {
+ "type": "git",
+ "url": "https://github.com/wordpress/wordpress-develop"
+ }
+ ],
+ "require": {
+ "php": ">=7.1.0",
+ "composer/installers": "~1.0"
+ },
+ "require-dev": {
+ "php": ">=7.1.0",
+ "squizlabs/php_codesniffer": "^3.3",
+ "wp-coding-standards/wpcs": "^2.2",
+ "phpcompatibility/php-compatibility": "^9.0",
+ "phpcompatibility/phpcompatibility-wp": "^2.1",
+ "phpmd/phpmd": "^2.6",
+ "phpunit/phpunit": "^7",
+ "phpstan/phpstan": "*",
+ "phpstan/extension-installer": "^1.0",
+ "szepeviktor/phpstan-wordpress": "*",
+ "php-stubs/wordpress-stubs": "~5.4.2",
+ "roave/security-advisories": "dev-master",
+ "mnsami/composer-custom-directory-installer": "~1.0",
+ "wordpress/wordpress": "~5.4.2",
+ "dealerdirect/phpcodesniffer-composer-installer": "~0.6",
+ "brain/monkey": "^2.4",
+ "mockery/mockery": "^1.3",
+ "phpro/grumphp": "~0.20",
+ "sensiolabs/security-checker": "^5.0",
+ "phpstan/phpstan-deprecation-rules": "^0.12"
+ },
+ "autoload-dev": {
+ "classmap": [
+ "wordpress/src/"
+ ]
+ },
+ "autoload": {
+ "classmap": [
+ "openid-connect-generic.php",
+ "includes/openid-connect-generic-client.php",
+ "includes/openid-connect-generic-client-wrapper.php",
+ "includes/openid-connect-generic-login-form.php",
+ "includes/openid-connect-generic-option-logger.php",
+ "includes/openid-connect-generic-option-settings.php",
+ "includes/openid-connect-generic-settings-page.php"
+ ]
+ },
+ "scripts": {
+ "install-codestandards": [
+ "Dealerdirect\\Composer\\Plugin\\Installers\\PHPCodeSniffer\\Plugin::run"
+ ],
+ "post-install-cmd": [
+ "@install-codestandards"
+ ],
+ "post-update-cmd": [
+ "@install-codestandards"
+ ],
+ "phpcs": "vendor/bin/phpcs",
+ "phpcbf": "vendor/bin/phpcbf",
+ "phpstan": "\"vendor/bin/phpstan\""
+ },
+ "extra": {
+ "installer-paths": {
+ "{$name}": [
+ "wordpress/wordpress"
+ ]
+ },
+ "phpcodesniffer-search-depth": 5
+ }
}
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-client-wrapper.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-client-wrapper.php
index 3823a3d..a407003 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-client-wrapper.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-client-wrapper.php
@@ -1,91 +1,136 @@
<?php
-
+/**
+ * Plugin OIDC/oAuth client warpper class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Authentication
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
+
+/**
+ * OpenID_Connect_Generic_Client_Wrapper class.
+ *
+ * Plugin OIDC/oAuth client wrapper class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Authentication
+ */
class OpenID_Connect_Generic_Client_Wrapper {
+ /**
+ * The client object instance.
+ *
+ * @var OpenID_Connect_Generic_Client
+ */
private $client;
- // settings object
+ /**
+ * The settings object instance.
+ *
+ * @var OpenID_Connect_Generic_Option_Settings
+ */
private $settings;
- // logger object
+ /**
+ * The logger object instance.
+ *
+ * @var OpenID_Connect_Generic_Option_Logger
+ */
private $logger;
- // token refresh info cookie key
+ /**
+ * The token refresh info cookie key.
+ *
+ * @var string
+ */
private $cookie_token_refresh_key = 'openid-connect-generic-refresh';
- // user redirect cookie key
+ /**
+ * The user redirect cookie key.
+ *
+ * @var string
+ */
public $cookie_redirect_key = 'openid-connect-generic-redirect';
- // WP_Error if there was a problem, or false if no error
+ /**
+ * The return error onject.
+ *
+ * @example WP_Error if there was a problem, or false if no error
+ *
+ * @var bool|WP_Error
+ */
private $error = false;
/**
- * Inject necessary objects and services into the client
+ * Inject necessary objects and services into the client.
*
- * @param \OpenID_Connect_Generic_Client $client
- * @param \OpenID_Connect_Generic_Option_Settings $settings
- * @param \OpenID_Connect_Generic_Option_Logger $logger
+ * @param OpenID_Connect_Generic_Client $client A plugin client object instance.
+ * @param OpenID_Connect_Generic_Option_Settings $settings A plugin settings object instance.
+ * @param OpenID_Connect_Generic_Option_Logger $logger A plugin logger object instance.
*/
- function __construct( OpenID_Connect_Generic_Client $client, OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ){
+ function __construct( OpenID_Connect_Generic_Client $client, OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
$this->client = $client;
$this->settings = $settings;
$this->logger = $logger;
}
/**
- * Hook the client into WP
+ * Hook the client into WordPress.
*
- * @param \OpenID_Connect_Generic_Client $client
- * @param \OpenID_Connect_Generic_Option_Settings $settings
- * @param \OpenID_Connect_Generic_Option_Logger $logger
+ * @param \OpenID_Connect_Generic_Client $client The plugin client instance.
+ * @param \OpenID_Connect_Generic_Option_Settings $settings The plugin settings instance.
+ * @param \OpenID_Connect_Generic_Option_Logger $logger The plugin logger instance.
*
* @return \OpenID_Connect_Generic_Client_Wrapper
*/
- static public function register( OpenID_Connect_Generic_Client $client, OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ){
+ static public function register( OpenID_Connect_Generic_Client $client, OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
$client_wrapper = new self( $client, $settings, $logger );
- // integrated logout
+ // Integrated logout.
if ( $settings->endpoint_end_session ) {
add_filter( 'allowed_redirect_hosts', array( $client_wrapper, 'update_allowed_redirect_hosts' ), 99, 1 );
add_filter( 'logout_redirect', array( $client_wrapper, 'get_end_session_logout_redirect_url' ), 99, 3 );
}
- // alter the requests according to settings
+ // Alter the requests according to settings.
add_filter( 'openid-connect-generic-alter-request', array( $client_wrapper, 'alter_request' ), 10, 3 );
if ( is_admin() ) {
- // use the ajax url to handle processing authorization without any html output
- // this callback will occur when then IDP returns with an authenticated value
+ /*
+ * Use the ajax url to handle processing authorization without any html output
+ * this callback will occur when then IDP returns with an authenticated value
+ */
add_action( 'wp_ajax_openid-connect-authorize', array( $client_wrapper, 'authentication_request_callback' ) );
add_action( 'wp_ajax_nopriv_openid-connect-authorize', array( $client_wrapper, 'authentication_request_callback' ) );
}
- if ( $settings->alternate_redirect_uri ){
- // provide an alternate route for authentication_request_callback
+ if ( $settings->alternate_redirect_uri ) {
+ // Provide an alternate route for authentication_request_callback.
add_rewrite_rule( '^openid-connect-authorize/?', 'index.php?openid-connect-authorize=1', 'top' );
add_rewrite_tag( '%openid-connect-authorize%', '1' );
add_action( 'parse_request', array( $client_wrapper, 'alternate_redirect_uri_parse_request' ) );
}
- // verify token for any logged in user
+ // Verify token for any logged in user.
if ( is_user_logged_in() ) {
- add_action( 'wp_loaded', array($client_wrapper, 'ensure_tokens_still_fresh'));
+ add_action( 'wp_loaded', array( $client_wrapper, 'ensure_tokens_still_fresh' ) );
}
return $client_wrapper;
}
/**
- * Implements WP action - parse_request
+ * Implements WordPress parse_request action.
*
- * @param $query
+ * @param WP_Query $query The WordPress query object.
*
* @return mixed
*/
- function alternate_redirect_uri_parse_request( $query ){
+ function alternate_redirect_uri_parse_request( $query ) {
if ( isset( $query->query_vars['openid-connect-authorize'] ) &&
- $query->query_vars['openid-connect-authorize'] === '1' )
- {
+ '1' === $query->query_vars['openid-connect-authorize'] ) {
$this->authentication_request_callback();
exit;
}
@@ -94,16 +139,29 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Get the authentication url from the client
+ * Get the authentication url from the client.
+ *
+ * @param array<string> $atts The optional attributes array when called via a shortcode.
*
* @return string
*/
- function get_authentication_url(){
- return $this->client->make_authentication_url();
+ function get_authentication_url( $atts = array() ) {
+
+ if ( ! empty( $atts['redirect_to'] ) ) {
+ // Set the request query parameter used to set the cookie redirect.
+ $_REQUEST['redirect_to'] = $atts['redirect_to'];
+ $login_form = new OpenID_Connect_Generic_Login_Form( $this->settings, $this );
+ $login_form->handle_redirect_cookie();
+ }
+
+ return $this->client->make_authentication_url( $atts );
+
}
/**
- * Handle retrieval and validation of refresh_token
+ * Handle retrieval and validation of refresh_token.
+ *
+ * @return void
*/
function ensure_tokens_still_fresh() {
if ( ! is_user_logged_in() ) {
@@ -116,27 +174,27 @@ class OpenID_Connect_Generic_Client_Wrapper {
$session = $manager->get( $token );
if ( ! isset( $session[ $this->cookie_token_refresh_key ] ) ) {
- // not an OpenID-based session
+ // Not an OpenID-based session.
return;
}
- $current_time = current_time( 'timestamp', true );
+ $current_time = time();
$refresh_token_info = $session[ $this->cookie_token_refresh_key ];
- $next_access_token_refresh_time = $refresh_token_info[ 'next_access_token_refresh_time' ];
+ $next_access_token_refresh_time = $refresh_token_info['next_access_token_refresh_time'];
if ( $current_time < $next_access_token_refresh_time ) {
return;
}
- $refresh_token = $refresh_token_info[ 'refresh_token' ];
- $refresh_expires = $refresh_token_info[ 'refresh_expires' ];
+ $refresh_token = $refresh_token_info['refresh_token'];
+ $refresh_expires = $refresh_token_info['refresh_expires'];
if ( ! $refresh_token || ( $refresh_expires && $current_time > $refresh_expires ) ) {
wp_logout();
if ( $this->settings->redirect_on_logout ) {
- $this->error_redirect( new WP_Error( 'access-token-expired', __( 'Session expired. Please login again.' ) ) );
+ $this->error_redirect( new WP_Error( 'access-token-expired', __( 'Session expired. Please login again.', 'daggerhart-openid-connect-generic' ) ) );
}
return;
@@ -160,40 +218,42 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Handle errors by redirecting the user to the login form
- * along with an error code
+ * Handle errors by redirecting the user to the login form along with an
+ * error code
*
- * @param $error WP_Error
+ * @param WP_Error $error A WordPress error object.
+ *
+ * @return void
*/
function error_redirect( $error ) {
$this->logger->log( $error );
- // redirect user back to login page
+ // Redirect user back to login page.
wp_redirect(
wp_login_url() .
'?login-error=' . $error->get_error_code() .
- '&message=' . urlencode( $error->get_error_message() )
+ '&message=' . urlencode( $error->get_error_message() )
);
exit;
}
/**
- * Get the current error state
+ * Get the current error state.
*
- * @return bool | WP_Error
+ * @return bool|WP_Error
*/
- function get_error(){
+ function get_error() {
return $this->error;
}
/**
- * Add the end_session endpoint to WP core's whitelist of redirect hosts
+ * Add the end_session endpoint to WordPress core's whitelist of redirect hosts.
*
- * @param array $allowed
+ * @param array<string> $allowed The allowed redirect host names.
*
- * @return array
+ * @return array<string>|bool
*/
- function update_allowed_redirect_hosts( array $allowed ) {
+ function update_allowed_redirect_hosts( $allowed ) {
$host = parse_url( $this->settings->endpoint_end_session, PHP_URL_HOST );
if ( ! $host ) {
return false;
@@ -204,9 +264,11 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Handle the logout redirect for end_session endpoint
+ * Handle the logout redirect for end_session endpoint.
*
- * @param $redirect_url
+ * @param string $redirect_url The requested redirect URL.
+ * @param string $requested_redirect_to The user login source URL, or configured user redirect URL.
+ * @param WP_User $user The logged in user object.
*
* @return string
*/
@@ -215,47 +277,47 @@ class OpenID_Connect_Generic_Client_Wrapper {
$query = parse_url( $url, PHP_URL_QUERY );
$url .= $query ? '&' : '?';
- // prevent redirect back to the IdP when logging out in auto mode
- if ( $this->settings->login_type === 'auto' && $redirect_url === 'wp-login.php?loggedout=true' ) {
+ // Prevent redirect back to the IDP when logging out in auto mode.
+ if ( 'auto' === $this->settings->login_type && 'wp-login.php?loggedout=true' === $redirect_url ) {
$redirect_url = '';
}
- $token_response = $user->get('openid-connect-generic-last-token-response');
- if (! $token_response ) {
- // happens if non-openid login was used
+ $token_response = $user->get( 'openid-connect-generic-last-token-response' );
+ if ( ! $token_response ) {
+ // Happens if non-openid login was used.
return $redirect_url;
- }
- else if ( ! parse_url( $redirect_url, PHP_URL_HOST ) ) {
- // convert to absolute url if needed. site_url() to be friendly with non-standard (Bedrock) layout
+ } else if ( ! parse_url( $redirect_url, PHP_URL_HOST ) ) {
+ // Convert to absolute url if needed, site_url() to be friendly with non-standard (Bedrock) layout.
$redirect_url = site_url( $redirect_url );
}
$claim = $user->get( 'openid-connect-generic-last-id-token-claim' );
- if ( isset( $claim['iss'] ) && $claim['iss'] == 'https://accounts.google.com' ) {
- /* Google revoke endpoint
- 1. expects the *access_token* to be passed as "token"
- 2. does not support redirection (post_logout_redirect_uri)
- So just redirect to regular WP logout URL.
- (we would *not* disconnect the user from any Google service even if he was
- initially disconnected to them) */
+ if ( isset( $claim['iss'] ) && 'https://accounts.google.com' == $claim['iss'] ) {
+ /*
+ * Google revoke endpoint
+ * 1. expects the *access_token* to be passed as "token"
+ * 2. does not support redirection (post_logout_redirect_uri)
+ * So just redirect to regular WP logout URL.
+ * (we would *not* disconnect the user from any Google service even
+ * if he was initially disconnected to them)
+ */
return $redirect_url;
- }
- else {
+ } else {
return $url . sprintf( 'id_token_hint=%s&post_logout_redirect_uri=%s', $token_response['id_token'], urlencode( $redirect_url ) );
}
}
/**
- * Modify outgoing requests according to settings
+ * Modify outgoing requests according to settings.
*
- * @param $request
- * @param $op
+ * @param array<mixed> $request The outgoing request array.
+ * @param string $operation The request operation name.
*
* @return mixed
*/
- function alter_request( $request, $op ) {
- if ( !empty( $this->settings->http_request_timeout ) && is_numeric( $this->settings->http_request_timeout ) ) {
+ function alter_request( $request, $operation ) {
+ if ( ! empty( $this->settings->http_request_timeout ) && is_numeric( $this->settings->http_request_timeout ) ) {
$request['timeout'] = intval( $this->settings->http_request_timeout );
}
@@ -268,43 +330,45 @@ class OpenID_Connect_Generic_Client_Wrapper {
/**
* Control the authentication and subsequent authorization of the user when
- * returning from the IDP.
+ * returning from the IDP.
+ *
+ * @return void
*/
function authentication_request_callback() {
$client = $this->client;
- // start the authentication flow
+ // Start the authentication flow.
$authentication_request = $client->validate_authentication_request( $_GET );
- if ( is_wp_error( $authentication_request ) ){
+ if ( is_wp_error( $authentication_request ) ) {
$this->error_redirect( $authentication_request );
}
- // retrieve the authentication code from the authentication request
+ // Retrieve the authentication code from the authentication request.
$code = $client->get_authentication_code( $authentication_request );
- if ( is_wp_error( $code ) ){
+ if ( is_wp_error( $code ) ) {
$this->error_redirect( $code );
}
- // attempting to exchange an authorization code for an authentication token
+ // Attempting to exchange an authorization code for an authentication token.
$token_result = $client->request_authentication_token( $code );
if ( is_wp_error( $token_result ) ) {
$this->error_redirect( $token_result );
}
- // get the decoded response from the authentication request result
+ // Get the decoded response from the authentication request result.
$token_response = $client->get_token_response( $token_result );
- // allow for other plugins to alter data before validation
+ // Allow for other plugins to alter data before validation.
$token_response = apply_filters( 'openid-connect-modify-token-response-before-validation', $token_response );
- if ( is_wp_error( $token_response ) ){
+ if ( is_wp_error( $token_response ) ) {
$this->error_redirect( $token_response );
}
- // ensure the that response contains required information
+ // Ensure the that response contains required information.
$valid = $client->validate_token_response( $token_response );
if ( is_wp_error( $valid ) ) {
@@ -312,44 +376,41 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * End authentication
- * -
- * Start Authorization
+ * The id_token is used to identify the authenticated user, e.g. for SSO.
+ * The access_token must be used to prove access rights to protected
+ * resources e.g. for the userinfo endpoint
*/
- // The id_token is used to identify the authenticated user, e.g. for SSO.
- // The access_token must be used to prove access rights to protected resources
- // e.g. for the userinfo endpoint
$id_token_claim = $client->get_id_token_claim( $token_response );
- // allow for other plugins to alter data before validation
+ // Allow for other plugins to alter data before validation.
$id_token_claim = apply_filters( 'openid-connect-modify-id-token-claim-before-validation', $id_token_claim );
- if ( is_wp_error( $id_token_claim ) ){
+ if ( is_wp_error( $id_token_claim ) ) {
$this->error_redirect( $id_token_claim );
}
- // validate our id_token has required values
+ // Validate our id_token has required values.
$valid = $client->validate_id_token_claim( $id_token_claim );
- if ( is_wp_error( $valid ) ){
+ if ( is_wp_error( $valid ) ) {
$this->error_redirect( $valid );
}
- // if userinfo endpoint is set, exchange the token_response for a user_claim
- if ( !empty( $this->settings->endpoint_userinfo ) && isset( $token_response['access_token'] )) {
+ // If userinfo endpoint is set, exchange the token_response for a user_claim.
+ if ( ! empty( $this->settings->endpoint_userinfo ) && isset( $token_response['access_token'] ) ) {
$user_claim = $client->get_user_claim( $token_response );
} else {
$user_claim = $id_token_claim;
}
- if ( is_wp_error( $user_claim ) ){
+ if ( is_wp_error( $user_claim ) ) {
$this->error_redirect( $user_claim );
}
- // validate our user_claim has required values
+ // Validate our user_claim has required values.
$valid = $client->validate_user_claim( $user_claim, $id_token_claim );
- if ( is_wp_error( $valid ) ){
+ if ( is_wp_error( $valid ) ) {
$this->error_redirect( $valid );
}
@@ -367,41 +428,37 @@ class OpenID_Connect_Generic_Client_Wrapper {
if ( is_wp_error( $user ) ) {
$this->error_redirect( $user );
}
+ } else {
+ $this->error_redirect( new WP_Error( 'identity-not-map-existing-user', __( 'User identity is not linked to an existing WordPress user.', 'daggerhart-openid-connect-generic' ), $user_claim ) );
}
- else {
- $this->error_redirect( new WP_Error( 'identity-not-map-existing-user', __( "User identity is not link to an existing WordPress user"), $user_claim ) );
- }
- }
- else {
- // allow plugins / themes to take action using current claims on existing user (e.g. update role)
+ } else {
+ // Allow plugins / themes to take action using current claims on existing user (e.g. update role).
do_action( 'openid-connect-generic-update-user-using-current-claim', $user, $user_claim );
}
- // validate the found / created user
+ // Validate the found / created user.
$valid = $this->validate_user( $user );
- if ( is_wp_error( $valid ) ){
+ if ( is_wp_error( $valid ) ) {
$this->error_redirect( $valid );
}
- // login the found / created user
- $this->login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity );
+ // Login the found / created user.
+ $this->login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity );
do_action( 'openid-connect-generic-user-logged-in', $user );
- // log our success
+ // Log our success.
$this->logger->log( "Successful login for: {$user->user_login} ({$user->ID})", 'login-success' );
- // redirect back to the origin page if enabled
+ // 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 ) ) {
+ 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() );
wp_redirect( $redirect_url );
- }
- // otherwise, go home!
- else {
+ } else { // Otherwise, go home!
wp_redirect( home_url() );
}
@@ -409,92 +466,102 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Validate the potential WP_User
+ * Validate the potential WP_User.
*
- * @param $user
+ * @param WP_User|WP_Error|false $user The user object.
*
- * @return true|\WP_Error
+ * @return true|WP_Error
*/
- function validate_user( $user ){
- // ensure our found user is a real WP_User
+ function validate_user( $user ) {
+ // Ensure the found user is a real WP_User.
if ( ! is_a( $user, 'WP_User' ) || ! $user->exists() ) {
- return new WP_Error( 'invalid-user', __( 'Invalid user' ), $user );
+ return new WP_Error( 'invalid-user', __( 'Invalid user.', 'daggerhart-openid-connect-generic' ), $user );
}
return true;
}
/**
- * Record user meta data, and provide an authorization cookie
+ * Record user meta data, and provide an authorization cookie.
*
- * @param $user
+ * @param WP_User $user The user object.
+ * @param array $token_response The token response.
+ * @param array $id_token_claim The ID token claim.
+ * @param array $user_claim The authenticated user claim.
+ * @param string $subject_identity The subject identity from the IDP.
+ *
+ * @return void
*/
- function login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity ){
- // hey, we made it!
- // let's remember the tokens for future reference
+ function login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity ) {
+ // Store the tokens for future reference.
update_user_meta( $user->ID, 'openid-connect-generic-last-token-response', $token_response );
update_user_meta( $user->ID, 'openid-connect-generic-last-id-token-claim', $id_token_claim );
update_user_meta( $user->ID, 'openid-connect-generic-last-user-claim', $user_claim );
- // Create the WP session, so we know its token
+ // Create the WP session, so we know its token.
$expiration = time() + apply_filters( 'auth_cookie_expiration', 2 * DAY_IN_SECONDS, $user->ID, false );
$manager = WP_Session_Tokens::get_instance( $user->ID );
$token = $manager->create( $expiration );
- // Save the refresh token in the session
+ // Save the refresh token in the session.
$this->save_refresh_token( $manager, $token, $token_response );
// you did great, have a cookie!
- wp_set_auth_cookie( $user->ID, false, '', $token);
+ wp_set_auth_cookie( $user->ID, false, '', $token );
do_action( 'wp_login', $user->user_login, $user );
}
/**
* Save refresh token to WP session tokens
*
- * @param $manager
- * @param $token
- * @param $token_response
+ * @param WP_Session_Tokens $manager A user session tokens manager.
+ * @param string $token The current users session token.
+ * @param array|WP_Error|null $token_response The authentication token response.
*/
function save_refresh_token( $manager, $token, $token_response ) {
- $session = $manager->get($token);
- $now = current_time( 'timestamp' , true );
- $session[$this->cookie_token_refresh_key] = array(
+ if ( ! $this->settings->token_refresh_enable ) {
+ return;
+ }
+ $session = $manager->get( $token );
+ $now = time();
+ $session[ $this->cookie_token_refresh_key ] = array(
'next_access_token_refresh_time' => $token_response['expires_in'] + $now,
- 'refresh_token' => isset( $token_response[ 'refresh_token' ] ) ? $token_response[ 'refresh_token' ] : false,
+ 'refresh_token' => isset( $token_response['refresh_token'] ) ? $token_response['refresh_token'] : false,
'refresh_expires' => false,
);
- if ( isset( $token_response[ 'refresh_expires_in' ] ) ) {
- $refresh_expires_in = $token_response[ 'refresh_expires_in' ];
- if ($refresh_expires_in > 0) {
- // leave enough time for the actual refresh request to go through
+ if ( isset( $token_response['refresh_expires_in'] ) ) {
+ $refresh_expires_in = $token_response['refresh_expires_in'];
+ if ( $refresh_expires_in > 0 ) {
+ // Leave enough time for the actual refresh request to go through.
$refresh_expires = $now + $refresh_expires_in - 5;
- $session[$this->cookie_token_refresh_key]['refresh_expires'] = $refresh_expires;
+ $session[ $this->cookie_token_refresh_key ]['refresh_expires'] = $refresh_expires;
}
}
- $manager->update($token, $session);
+ $manager->update( $token, $session );
return;
}
/**
* Get the user that has meta data matching a
*
- * @param $subject_identity
+ * @param string $subject_identity The IDP identity of the user.
*
- * @return false|\WP_User
+ * @return false|WP_User
*/
- function get_user_by_identity( $subject_identity ){
- // look for user by their openid-connect-generic-subject-identity value
- $user_query = new WP_User_Query( array(
- 'meta_query' => array(
- array(
- 'key' => 'openid-connect-generic-subject-identity',
- 'value' => $subject_identity,
- )
+ function get_user_by_identity( $subject_identity ) {
+ // Look for user by their openid-connect-generic-subject-identity value.
+ $user_query = new WP_User_Query(
+ array(
+ 'meta_query' => array(
+ array(
+ 'key' => 'openid-connect-generic-subject-identity',
+ 'value' => $subject_identity,
+ ),
+ ),
)
- ) );
+ );
- // if we found an existing users, grab the first one returned
+ // If we found an existing users, grab the first one returned.
if ( $user_query->get_total() > 0 ) {
$users = $user_query->get_results();
return $users[0];
@@ -504,49 +571,48 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Avoid user_login collisions by incrementing
+ * Avoid user_login collisions by incrementing.
*
- * @param $user_claim array
+ * @param array $user_claim The IDP authenticated user claim data.
*
- * @return string
+ * @return string|WP_Error|null
*/
private function get_username_from_claim( $user_claim ) {
- // allow settings to take first stab at username
- if ( !empty( $this->settings->identity_key ) && isset( $user_claim[ $this->settings->identity_key ] ) ) {
- $desired_username = $user_claim[ $this->settings->identity_key ];
- }
- else if ( isset( $user_claim['preferred_username'] ) && ! empty( $user_claim['preferred_username'] ) ) {
+
+ // @var string $desired_username
+ $desired_username = '';
+
+ // Allow settings to take first stab at username.
+ if ( ! empty( $this->settings->identity_key ) && isset( $user_claim[ $this->settings->identity_key ] ) ) {
+ $desired_username = $user_claim[ $this->settings->identity_key ];
+ } else if ( isset( $user_claim['preferred_username'] ) && ! empty( $user_claim['preferred_username'] ) ) {
$desired_username = $user_claim['preferred_username'];
- }
- else if ( isset( $user_claim['name'] ) && ! empty( $user_claim['name'] ) ) {
+ } else if ( isset( $user_claim['name'] ) && ! empty( $user_claim['name'] ) ) {
$desired_username = $user_claim['name'];
- }
- else if ( isset( $user_claim['email'] ) && ! empty( $user_claim['email'] ) ) {
+ } else if ( isset( $user_claim['email'] ) && ! empty( $user_claim['email'] ) ) {
$tmp = explode( '@', $user_claim['email'] );
$desired_username = $tmp[0];
- }
- else {
- // nothing to build a name from
- return new WP_Error( 'no-username', __( 'No appropriate username found' ), $user_claim );
+ } else {
+ // Nothing to build a name from.
+ return new WP_Error( 'no-username', __( 'No appropriate username found.', 'daggerhart-openid-connect-generic' ), $user_claim );
}
- // normalize the data a bit
- $transliterated_username = iconv( 'UTF-8', 'ASCII//TRANSLIT', $desired_username );
+ // Normalize the data a bit.
+ // @var string $transliterated_username The username converted to ASCII from UTF-8.
+ $transliterated_username = iconv( 'UTF-8', 'ASCII//TRANSLIT', $desired_username );
if ( empty( $transliterated_username ) ) {
- return new WP_Error( 'username-transliteration-failed', __( "Username $desired_username could not be transliterated" ), $desired_username );
+ return new WP_Error( 'username-transliteration-failed', sprintf( __( 'Username %1$s could not be transliterated.', 'daggerhart-openid-connect-generic' ), $desired_username ), $desired_username );
}
$normalized_username = strtolower( preg_replace( '/[^a-zA-Z0-9 _.\-@]/', '', $transliterated_username ) );
if ( empty( $normalized_username ) ) {
- return new WP_Error( 'username-normalization-failed', __( "Username $transliterated_username could not be normalized" ), $transliterated_username );
+ return new WP_Error( 'username-normalization-failed', sprintf( __( 'Username %1$s could not be normalized.', 'daggerhart-openid-connect-generic' ), $transliterated_username ), $transliterated_username );
}
- // copy the username for incrementing
- $username = $normalized_username;
+ // Copy the username for incrementing.
+ $username = ! empty( $normalized_username ) ? $normalized_username : null;
- if ( ! $this->settings->link_existing_users ) {
- // original user gets "name"
- // second user gets "name2"
- // etc
+ if ( ! $this->settings->link_existing_users && ! is_null( $username ) ) {
+ // @example Original user gets "name", second user gets "name2", etc.
$count = 1;
while ( username_exists( $username ) ) {
$count ++;
@@ -558,49 +624,60 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Get a nickname
+ * Get a nickname.
*
- * @param $user_claim array
+ * @param array $user_claim The IDP authenticated user claim data.
*
- * @return string
+ * @return string|WP_Error|null
*/
private function get_nickname_from_claim( $user_claim ) {
$desired_nickname = null;
- // allow settings to take first stab at nickname
- if ( !empty( $this->settings->nickname_key ) && isset( $user_claim[ $this->settings->nickname_key ] ) ) {
- $desired_nickname = $user_claim[ $this->settings->nickname_key ];
+ // Allow settings to take first stab at nickname.
+ if ( ! empty( $this->settings->nickname_key ) && isset( $user_claim[ $this->settings->nickname_key ] ) ) {
+ $desired_nickname = $user_claim[ $this->settings->nickname_key ];
}
+
+ if ( empty( $desired_nickname ) ) {
+ return new WP_Error( 'no-nickname', sprintf( __( 'No nickname found in user claim using key: %1$s.', 'daggerhart-openid-connect-generic' ), $this->settings->nickname_key ), $this->settings->nickname_key );
+ }
+
return $desired_nickname;
}
/**
* Build a string from the user claim according to the specified format.
*
- * @param $format string
- * @param $user_claim array
+ * @param string $format The format format of the user identity.
+ * @param array $user_claim The authorized user claim.
+ * @param bool $error_on_missing_key Whether to return and error on a missing key.
*
- * @return string
+ * @return string|WP_Error
*/
private function format_string_with_claim( $format, $user_claim, $error_on_missing_key = false ) {
$matches = null;
$string = '';
$i = 0;
if ( preg_match_all( '/\{[^}]*\}/u', $format, $matches, PREG_OFFSET_CAPTURE ) ) {
- foreach ( $matches[ 0 ] as $match ) {
- $key = substr($match[ 0 ], 1, -1);
- $string .= substr( $format, $i, $match[ 1 ] - $i );
+ foreach ( $matches[0] as $match ) {
+ $key = substr( $match[0], 1, -1 );
+ $string .= substr( $format, $i, $match[1] - $i );
if ( ! isset( $user_claim[ $key ] ) ) {
if ( $error_on_missing_key ) {
- return new WP_Error( 'incomplete-user-claim', __( 'User claim incomplete' ),
- array('message'=>'Unable to find key: '.$key.' in user_claim',
- 'hint'=>'Verify OpenID Scope includes a scope with the attributes you need',
- 'user_claim'=>$user_claim,
- 'format'=>$format) );
+ return new WP_Error(
+ 'incomplete-user-claim',
+ __( 'User claim incomplete.', 'daggerhart-openid-connect-generic' ),
+ array(
+ 'message' => 'Unable to find key: ' . $key . ' in user_claim',
+ 'hint' => 'Verify OpenID Scope includes a scope with the attributes you need',
+ 'user_claim' => $user_claim,
+ 'format' => $format,
+ )
+ );
}
} else {
$string .= $user_claim[ $key ];
}
- $i = $match[ 1 ] + strlen( $match[ 0 ] );
+ $i = $match[1] + strlen( $match[0] );
}
}
$string .= substr( $format, $i );
@@ -608,11 +685,12 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Get a displayname
+ * Get a displayname.
*
- * @param $user_claim array
+ * @param array $user_claim The authorized user claim.
+ * @param bool $error_on_missing_key Whether to return and error on a missing key.
*
- * @return string
+ * @return string|null|WP_Error
*/
private function get_displayname_from_claim( $user_claim, $error_on_missing_key = false ) {
if ( ! empty( $this->settings->displayname_format ) ) {
@@ -622,11 +700,12 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Get an email
+ * Get an email.
*
- * @param $user_claim array
+ * @param array $user_claim The authorized user claim.
+ * @param bool $error_on_missing_key Whether to return and error on a missing key.
*
- * @return string
+ * @return string|null|WP_Error
*/
private function get_email_from_claim( $user_claim, $error_on_missing_key = false ) {
if ( ! empty( $this->settings->email_format ) ) {
@@ -636,60 +715,59 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
/**
- * Create a new user from details in a user_claim
+ * Create a new user from details in a user_claim.
*
- * @param $subject_identity
- * @param $user_claim
+ * @param string $subject_identity The authenticated user's identity with the IDP.
+ * @param array $user_claim The authorized user claim.
*
* @return \WP_Error | \WP_User
*/
function create_new_user( $subject_identity, $user_claim ) {
$user_claim = apply_filters( 'openid-connect-generic-alter-user-claim', $user_claim );
- // default username & email to the subject identity
- $username = $subject_identity;
- $email = $subject_identity;
- $nickname = $subject_identity;
- $displayname = $subject_identity;
-
+ // Default username & email to the subject identity.
+ $username = $subject_identity;
+ $email = $subject_identity;
+ $nickname = $subject_identity;
+ $displayname = $subject_identity;
$values_missing = false;
- // allow claim details to determine username, email, nickname and displayname.
+ // Allow claim details to determine username, email, nickname and displayname.
$_email = $this->get_email_from_claim( $user_claim, true );
if ( is_wp_error( $_email ) ) {
$values_missing = true;
- } else if ( $_email !== null ) {
+ } else if ( ! is_null( $_email ) ) {
$email = $_email;
}
$_username = $this->get_username_from_claim( $user_claim );
if ( is_wp_error( $_username ) ) {
$values_missing = true;
- } else if ( $_username !== null ) {
+ } else if ( ! is_null( $_username ) ) {
$username = $_username;
}
$_nickname = $this->get_nickname_from_claim( $user_claim );
- if ( is_wp_error( $_nickname ) ) {
+ if ( is_null( $_nickname ) ) {
$values_missing = true;
- } else if ( $_nickname !== null) {
+ } else {
$nickname = $_nickname;
}
$_displayname = $this->get_displayname_from_claim( $user_claim, true );
if ( is_wp_error( $_displayname ) ) {
$values_missing = true;
- } else if ( $_displayname !== null ) {
+ } else if ( ! is_null( $_displayname ) ) {
$displayname = $_displayname;
}
- // attempt another request for userinfo if some values are missing
- if ( $values_missing && isset( $token_response['access_token'] ) && !empty( $this->settings->endpoint_userinfo) ) {
- $user_claim_result = $this->client->request_userinfo( $token_response['access_token'] );
+ // Attempt another request for userinfo if some values are missing.
+ if ( $values_missing && isset( $user_claim['access_token'] ) && ! empty( $this->settings->endpoint_userinfo ) ) {
+ $user_claim_result = $this->client->request_userinfo( $user_claim['access_token'] );
- // make sure we didn't get an error
+ // Make sure we didn't get an error.
if ( is_wp_error( $user_claim_result ) ) {
- return new WP_Error( 'bad-user-claim-result', __( 'Bad user claim result' ), $user_claim_result );
+ return new WP_Error( 'bad-user-claim-result', __( 'Bad user claim result.', 'daggerhart-openid-connect-generic' ), $user_claim_result );
}
$user_claim = json_decode( $user_claim_result['body'], true );
@@ -698,34 +776,34 @@ class OpenID_Connect_Generic_Client_Wrapper {
$_email = $this->get_email_from_claim( $user_claim, true );
if ( is_wp_error( $_email ) ) {
return $_email;
- } else if ( $_email !== null ) {
+ } else if ( ! is_null( $_email ) ) {
$email = $_email;
}
$_username = $this->get_username_from_claim( $user_claim );
if ( is_wp_error( $_username ) ) {
return $_username;
- } else if ( $_username !== null ) {
+ } else if ( ! is_null( $_username ) ) {
$username = $_username;
}
$_nickname = $this->get_nickname_from_claim( $user_claim );
if ( is_wp_error( $_nickname ) ) {
return $_nickname;
- } else if ( $_nickname === null) {
+ } else if ( is_null( $_nickname ) ) {
$nickname = $username;
}
$_displayname = $this->get_displayname_from_claim( $user_claim, true );
if ( is_wp_error( $_displayname ) ) {
return $_displayname;
- } else if ( $_displayname === null ) {
+ } else if ( is_null( $_displayname ) ) {
$displayname = $nickname;
}
- // before trying to create the user, first check if a user with the same email already exists
- if( $this->settings->link_existing_users ) {
- if ( $this->settings->identify_with_username) {
+ // Before trying to create the user, first check if a user with the same email already exists.
+ if ( $this->settings->link_existing_users ) {
+ if ( $this->settings->identify_with_username ) {
$uid = username_exists( $username );
} else {
$uid = email_exists( $email );
@@ -737,12 +815,14 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
}
- // allow other plugins / themes to determine authorization
- // of new accounts based on the returned user claim
+ /**
+ * Allow other plugins / themes to determine authorization of new accounts
+ * based on the returned user claim.
+ */
$create_user = apply_filters( 'openid-connect-generic-user-creation-test', true, $user_claim );
if ( ! $create_user ) {
- return new WP_Error( 'cannot-authorize', __( 'Can not authorize.' ), $create_user );
+ return new WP_Error( 'cannot-authorize', __( 'Can not authorize.', 'daggerhart-openid-connect-generic' ), $create_user );
}
$user_data = array(
@@ -751,29 +831,29 @@ class OpenID_Connect_Generic_Client_Wrapper {
'user_email' => $email,
'display_name' => $displayname,
'nickname' => $nickname,
- 'first_name' => isset( $user_claim[ 'given_name' ] ) ? $user_claim[ 'given_name' ]: '',
- 'last_name' => isset( $user_claim[ 'family_name' ] ) ? $user_claim[ 'family_name' ]: '',
+ 'first_name' => isset( $user_claim['given_name'] ) ? $user_claim['given_name'] : '',
+ 'last_name' => isset( $user_claim['family_name'] ) ? $user_claim['family_name'] : '',
);
$user_data = apply_filters( 'openid-connect-generic-alter-user-data', $user_data, $user_claim );
- // create the new user
+ // Create the new user.
$uid = wp_insert_user( $user_data );
- // make sure we didn't fail in creating the user
+ // Make sure we didn't fail in creating the user.
if ( is_wp_error( $uid ) ) {
- return new WP_Error( 'failed-user-creation', __( 'Failed user creation.' ), $uid );
+ return new WP_Error( 'failed-user-creation', __( 'Failed user creation.', 'daggerhart-openid-connect-generic' ), $uid );
}
- // retrieve our new user
+ // Retrieve our new user.
$user = get_user_by( 'id', $uid );
- // save some meta data about this new user for the future
+ // Save some meta data about this new user for the future.
add_user_meta( $user->ID, 'openid-connect-generic-subject-identity', (string) $subject_identity, true );
- // log the results
+ // Log the results.
$this->logger->log( "New user created: {$user->user_login} ($uid)", 'success' );
- // allow plugins / themes to take action on new user creation
+ // Allow plugins / themes to take action on new user creation.
do_action( 'openid-connect-generic-user-create', $user, $user_claim );
return $user;
@@ -782,19 +862,19 @@ class OpenID_Connect_Generic_Client_Wrapper {
/**
* Update an existing user with OpenID Connect meta data
*
- * @param $uid
- * @param $subject_identity
+ * @param int $uid The WordPress User ID.
+ * @param string $subject_identity The subject identity from the IDP.
*
- * @return \WP_Error | \WP_User
+ * @return WP_Error|WP_User
*/
function update_existing_user( $uid, $subject_identity ) {
- // add the OpenID Connect meta data
- update_user_meta( $uid, 'openid-connect-generic-subject-identity', (string) $subject_identity );
+ // Add the OpenID Connect meta data.
+ update_user_meta( $uid, 'openid-connect-generic-subject-identity', strval( $subject_identity ) );
- // allow plugins / themes to take action on user update
+ // Allow plugins / themes to take action on user update.
do_action( 'openid-connect-generic-user-update', $uid );
- // return our updated user
+ // Return our updated user.
return get_user_by( 'id', $uid );
}
}
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-client.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-client.php
index 100d3a1..11eceac 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-client.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-client.php
@@ -1,36 +1,117 @@
<?php
-
+/**
+ * Plugin OIDC/oAuth client class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Authentication
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
+
+/**
+ * OpenID_Connect_Generic_Client class.
+ *
+ * Plugin OIDC/oAuth client class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Authentication
+ */
class OpenID_Connect_Generic_Client {
+ /**
+ * The OIDC/oAuth client ID.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::client_id
+ *
+ * @var string
+ */
private $client_id;
+
+ /**
+ * The OIDC/oAuth client secret.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::client_secret
+ *
+ * @var string
+ */
private $client_secret;
+
+ /**
+ * The OIDC/oAuth scopes.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::scope
+ *
+ * @var string
+ */
private $scope;
+
+ /**
+ * The OIDC/oAuth authorization endpoint URL.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::endpoint_login
+ *
+ * @var string
+ */
private $endpoint_login;
+
+ /**
+ * The OIDC/oAuth User Information endpoint URL.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::endpoint_userinfo
+ *
+ * @var string
+ */
private $endpoint_userinfo;
+
+ /**
+ * The OIDC/oAuth token validation endpoint URL.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::endpoint_token
+ *
+ * @var string
+ */
private $endpoint_token;
- // login flow "ajax" endpoint
+ /**
+ * The login flow "ajax" endpoint URI.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::redirect_uri
+ *
+ * @var string
+ */
private $redirect_uri;
- // states are only valid for 3 minutes
+ /**
+ * The state time limit. States are only valid for 3 minutes.
+ *
+ * @see OpenID_Connect_Generic_Option_Settings::state_time_limit
+ *
+ * @var int
+ */
private $state_time_limit = 180;
- // logger object
+ /**
+ * The logger object instance.
+ *
+ * @var OpenID_Connect_Generic_Option_Logger
+ */
private $logger;
/**
- * Client constructor
- *
- * @param $client_id
- * @param $client_secret
- * @param $scope
- * @param $endpoint_login
- * @param $endpoint_userinfo
- * @param $endpoint_token
- * @param $redirect_uri
- * @param $state_time_limit time states are valid in seconds
+ * Client constructor.
+ *
+ * @param string $client_id @see OpenID_Connect_Generic_Option_Settings::client_id for description.
+ * @param string $client_secret @see OpenID_Connect_Generic_Option_Settings::client_secret for description.
+ * @param string $scope @see OpenID_Connect_Generic_Option_Settings::scope for description.
+ * @param string $endpoint_login @see OpenID_Connect_Generic_Option_Settings::endpoint_login for description.
+ * @param string $endpoint_userinfo @see OpenID_Connect_Generic_Option_Settings::endpoint_userinfo for description.
+ * @param string $endpoint_token @see OpenID_Connect_Generic_Option_Settings::endpoint_token for description.
+ * @param string $redirect_uri @see OpenID_Connect_Generic_Option_Settings::redirect_uri for description.
+ * @param int $state_time_limit @see OpenID_Connect_Generic_Option_Settings::state_time_limit for description.
+ * @param OpenID_Connect_Generic_Option_Logger $logger The plugin logging object instance.
*/
- function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $redirect_uri, $state_time_limit, $logger){
+ function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $redirect_uri, $state_time_limit, $logger ) {
$this->client_id = $client_id;
$this->client_secret = $client_secret;
$this->scope = $scope;
@@ -45,20 +126,29 @@ class OpenID_Connect_Generic_Client {
/**
* Create a single use authentication url
*
+ * @param array $atts An optional array of override/feature attributes.
+ *
* @return string
*/
- function make_authentication_url() {
+ function make_authentication_url( $atts = array() ) {
+
+ $endpoint_login = ( ! empty( $atts['endpoint_login'] ) ) ? $atts['endpoint_login'] : $this->endpoint_login;
+ $scope = ( ! empty( $atts['scope'] ) ) ? $atts['scope'] : $this->scope;
+ $client_id = ( ! empty( $atts['client_id'] ) ) ? $atts['client_id'] : $this->client_id;
+ $redirect_uri = ( ! empty( $atts['redirect_uri'] ) ) ? $atts['redirect_uri'] : $this->redirect_uri;
+
$separator = '?';
- if ( stripos( $this->endpoint_login, '?' ) !== FALSE ) {
+ if ( stripos( $this->endpoint_login, '?' ) !== 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_login,
+ $url = sprintf(
+ '%1$s%2$sresponse_type=code&scope=%3$s&client_id=%4$s&state=%5$s&redirect_uri=%6$s',
+ $endpoint_login,
$separator,
- rawurlencode( $this->scope ),
- rawurlencode( $this->client_id ),
+ rawurlencode( $scope ),
+ rawurlencode( $client_id ),
$this->new_state(),
- rawurlencode( $this->redirect_uri )
+ rawurlencode( $redirect_uri )
);
$this->logger->log( apply_filters( 'openid-connect-generic-auth-url', $url ), 'make_authentication_url' );
@@ -68,29 +158,29 @@ class OpenID_Connect_Generic_Client {
/**
* Validate the request for login authentication
*
- * @param $request
+ * @param array<string> $request The authentication request results.
*
- * @return array|\WP_Error
+ * @return array<string>|WP_Error
*/
- function validate_authentication_request( $request ){
- // look for an existing error of some kind
+ function validate_authentication_request( $request ) {
+ // Look for an existing error of some kind.
if ( isset( $request['error'] ) ) {
return new WP_Error( 'unknown-error', 'An unknown error occurred.', $request );
}
- // make sure we have a legitimate authentication code and valid state
+ // Make sure we have a legitimate authentication code and valid state.
if ( ! isset( $request['code'] ) ) {
return new WP_Error( 'no-code', 'No authentication code present in the request.', $request );
}
- // check the client request state
- if( ! isset( $request['state']) ) {
+ // Check the client request state.
+ if ( ! isset( $request['state'] ) ) {
do_action( 'openid-connect-generic-no-state-provided' );
- return new WP_Error( 'missing-state', __( 'Missing state.' ), $request );
+ return new WP_Error( 'missing-state', __( 'Missing state.', 'daggerhart-openid-connect-generic' ), $request );
}
if ( ! $this->check_state( $request['state'] ) ) {
- return new WP_Error( 'invalid-state', __( 'Invalid state.' ), $request );
+ return new WP_Error( 'invalid-state', __( 'Invalid state.', 'daggerhart-openid-connect-generic' ), $request );
}
return $request;
@@ -99,25 +189,29 @@ class OpenID_Connect_Generic_Client {
/**
* Get the authorization code from the request
*
- * @param $request array
+ * @param array<string>|WP_Error $request The authentication request results.
*
- * @return string|\WP_Error
+ * @return string|WP_Error
*/
- function get_authentication_code( $request ){
+ function get_authentication_code( $request ) {
+ if ( ! isset( $request['code'] ) ) {
+ return new WP_Error( 'missing-authentication-code', __( 'Missing authentication code.', 'daggerhart-openid-connect-generic' ), $request );
+ }
+
return $request['code'];
}
/**
- * Using the authorization_code, request an authentication token from the idp
+ * Using the authorization_code, request an authentication token from the IDP.
*
- * @param $code - authorization_code
+ * @param string|WP_Error $code The authorization code.
*
- * @return array|\WP_Error
+ * @return array<mixed>|WP_Error
*/
function request_authentication_token( $code ) {
- // Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy
- $parsed_url = parse_url($this->endpoint_token);
+ // Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy.
+ $parsed_url = parse_url( $this->endpoint_token );
$host = $parsed_url['host'];
$request = array(
@@ -129,18 +223,18 @@ class OpenID_Connect_Generic_Client {
'grant_type' => 'authorization_code',
'scope' => $this->scope,
),
- 'headers' => array( 'Host' => $host )
+ 'headers' => array( 'Host' => $host ),
);
- // allow modifications to the request
+ // Allow modifications to the request.
$request = apply_filters( 'openid-connect-generic-alter-request', $request, 'get-authentication-token' );
- // call the server and ask for a token
+ // Call the server and ask for a token.
$this->logger->log( $this->endpoint_token, 'request_authentication_token' );
$response = wp_remote_post( $this->endpoint_token, $request );
- if ( is_wp_error( $response ) ){
- $response->add( 'request_authentication_token' , __( 'Request for authentication token failed.' ) );
+ if ( is_wp_error( $response ) ) {
+ $response->add( 'request_authentication_token', __( 'Request for authentication token failed.', 'daggerhart-openid-connect-generic' ) );
}
return $response;
@@ -149,9 +243,9 @@ class OpenID_Connect_Generic_Client {
/**
* Using the refresh token, request new tokens from the idp
*
- * @param $refresh_token - refresh token previously obtained from token response.
+ * @param string $refresh_token The refresh token previously obtained from token response.
*
- * @return array|\WP_Error
+ * @return array|WP_Error
*/
function request_new_tokens( $refresh_token ) {
$request = array(
@@ -159,19 +253,19 @@ class OpenID_Connect_Generic_Client {
'refresh_token' => $refresh_token,
'client_id' => $this->client_id,
'client_secret' => $this->client_secret,
- 'grant_type' => 'refresh_token'
- )
+ 'grant_type' => 'refresh_token',
+ ),
);
- // allow modifications to the request
+ // Allow modifications to the request.
$request = apply_filters( 'openid-connect-generic-alter-request', $request, 'refresh-token' );
- // call the server and ask for new tokens
+ // Call the server and ask for new tokens.
$this->logger->log( $this->endpoint_token, 'request_new_tokens' );
$response = wp_remote_post( $this->endpoint_token, $request );
if ( is_wp_error( $response ) ) {
- $response->add( 'refresh_token' , __( 'Refresh token failed.' ) );
+ $response->add( 'refresh_token', __( 'Refresh token failed.', 'daggerhart-openid-connect-generic' ) );
}
return $response;
@@ -180,22 +274,28 @@ class OpenID_Connect_Generic_Client {
/**
* Extract and decode the token body of a token response
*
- * @param $token_result
- * @return array|mixed|object
+ * @param array<mixed>|WP_Error $token_result The token response.
+ *
+ * @return array<mixed>|WP_Error|null
*/
- function get_token_response( $token_result ){
- if ( ! isset( $token_result['body'] ) ){
- return new WP_Error( 'missing-token-body', __( 'Missing token body.' ), $token_result );
+ function get_token_response( $token_result ) {
+ if ( ! isset( $token_result['body'] ) ) {
+ return new WP_Error( 'missing-token-body', __( 'Missing token body.', 'daggerhart-openid-connect-generic' ), $token_result );
}
- // extract token response from token
+ // Extract the token response from token.
$token_response = json_decode( $token_result['body'], true );
- if ( isset( $token_response[ 'error' ] ) ) {
- $error = $token_response[ 'error' ];
+ // Check that the token response body was able to be parsed.
+ if ( is_null( $token_response ) ) {
+ return new WP_Error( 'invalid-token', __( 'Invalid token.', 'daggerhart-openid-connect-generic' ), $token_result );
+ }
+
+ if ( isset( $token_response['error'] ) ) {
+ $error = $token_response['error'];
$error_description = $error;
- if ( isset( $token_response[ 'error_description' ] ) ) {
- $error_description = $token_response[ 'error_description' ];
+ if ( isset( $token_response['error_description'] ) ) {
+ $error_description = $token_response['error_description'];
}
return new WP_Error( $error, $error_description, $token_result );
}
@@ -203,55 +303,55 @@ class OpenID_Connect_Generic_Client {
return $token_response;
}
-
/**
* Exchange an access_token for a user_claim from the userinfo endpoint
*
- * @param $access_token
+ * @param string $access_token The access token supplied from authentication user claim.
*
- * @return array|\WP_Error
+ * @return array|WP_Error
*/
function request_userinfo( $access_token ) {
- // allow modifications to the request
+ // Allow modifications to the request.
$request = apply_filters( 'openid-connect-generic-alter-request', array(), 'get-userinfo' );
- // section 5.3.1 of the spec recommends sending the access token using the authorization header
- // a filter may or may not have already added headers - make sure they exist then add the token
- if ( !array_key_exists( 'headers', $request ) || !is_array( $request['headers'] ) ) {
+ /*
+ * Section 5.3.1 of the spec recommends sending the access token using the authorization header
+ * a filter may or may not have already added headers - make sure they exist then add the token.
+ */
+ if ( ! array_key_exists( 'headers', $request ) || ! is_array( $request['headers'] ) ) {
$request['headers'] = array();
}
- $request['headers']['Authorization'] = 'Bearer '.$access_token;
+ $request['headers']['Authorization'] = 'Bearer ' . $access_token;
- // Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy
- $parsed_url = parse_url($this->endpoint_userinfo);
+ // Add Host header - required for when the openid-connect endpoint is behind a reverse-proxy.
+ $parsed_url = parse_url( $this->endpoint_userinfo );
$host = $parsed_url['host'];
- if ( !empty( $parsed_url['port'] ) ) {
- $host.= ":{$parsed_url['port']}";
+ if ( ! empty( $parsed_url['port'] ) ) {
+ $host .= ":{$parsed_url['port']}";
}
$request['headers']['Host'] = $host;
- // attempt the request including the access token in the query string for backwards compatibility
+ // Attempt the request including the access token in the query string for backwards compatibility.
$this->logger->log( $this->endpoint_userinfo, 'request_userinfo' );
$response = wp_remote_post( $this->endpoint_userinfo, $request );
- if ( is_wp_error( $response ) ){
- $response->add( 'request_userinfo' , __( 'Request for userinfo failed.' ) );
+ if ( is_wp_error( $response ) ) {
+ $response->add( 'request_userinfo', __( 'Request for userinfo failed.', 'daggerhart-openid-connect-generic' ) );
}
return $response;
}
/**
- * Generate a new state, save it as a transient,
- * and return the state hash.
+ * Generate a new state, save it as a transient, and return the state hash.
*
* @return string
*/
function new_state() {
- // new state w/ timestamp
+ // New state w/ timestamp.
$state = md5( mt_rand() . microtime( true ) );
set_transient( 'openid-connect-generic-state--' . $state, $state, $this->state_time_limit );
@@ -261,7 +361,7 @@ class OpenID_Connect_Generic_Client {
/**
* Check the existence of a given state transient.
*
- * @param $state
+ * @param string $state The state hash to validate.
*
* @return bool
*/
@@ -280,21 +380,23 @@ class OpenID_Connect_Generic_Client {
do_action( 'openid-connect-generic-state-expired', $state );
}
- return !!$valid;
+ return ! ! $valid;
}
/**
- * Ensure that the token meets basic requirements
+ * Ensure that the token meets basic requirements.
*
- * @param $token_response
+ * @param array $token_response The token response.
*
- * @return bool|\WP_Error
+ * @return bool|WP_Error
*/
- function validate_token_response( $token_response ){
- // we need to ensure 2 specific items exist with the token response in order
- // to proceed with confidence: id_token and token_type == 'Bearer'
+ function validate_token_response( $token_response ) {
+ /*
+ * Ensure 2 specific items exist with the token response in order
+ * to proceed with confidence: id_token and token_type == 'Bearer'
+ */
if ( ! isset( $token_response['id_token'] ) ||
- ! isset( $token_response['token_type'] ) || strcasecmp( $token_response['token_type'], 'Bearer' )
+ ! isset( $token_response['token_type'] ) || strcasecmp( $token_response['token_type'], 'Bearer' )
) {
return new WP_Error( 'invalid-token-response', 'Invalid token response', $token_response );
}
@@ -303,74 +405,74 @@ class OpenID_Connect_Generic_Client {
}
/**
- * Extract the id_token_claim from the token_response
+ * Extract the id_token_claim from the token_response.
*
- * @param $token_response
+ * @param array $token_response The token response.
*
- * @return array|\WP_Error
+ * @return array|WP_Error
*/
- function get_id_token_claim( $token_response ){
- // name sure we have an id_token
+ function get_id_token_claim( $token_response ) {
+ // Validate there is an id_token.
if ( ! isset( $token_response['id_token'] ) ) {
- return new WP_Error( 'no-identity-token', __( 'No identity token' ), $token_response );
+ return new WP_Error( 'no-identity-token', __( 'No identity token.', 'daggerhart-openid-connect-generic' ), $token_response );
}
- // break apart the id_token in the response for decoding
+ // Break apart the id_token in the response for decoding.
$tmp = explode( '.', $token_response['id_token'] );
if ( ! isset( $tmp[1] ) ) {
- return new WP_Error( 'missing-identity-token', __( 'Missing identity token' ), $token_response );
+ return new WP_Error( 'missing-identity-token', __( 'Missing identity token.', 'daggerhart-openid-connect-generic' ), $token_response );
}
- // Extract the id_token's claims from the token
+ // Extract the id_token's claims from the token.
$id_token_claim = json_decode(
base64_decode(
- str_replace( // because token is encoded in base64 URL (and not just base64)
- array('-', '_'),
- array('+', '/'),
+ str_replace( // Because token is encoded in base64 URL (and not just base64).
+ array( '-', '_' ),
+ array( '+', '/' ),
$tmp[1]
)
- )
- , true
+ ),
+ true
);
return $id_token_claim;
}
/**
- * Ensure the id_token_claim contains the required values
+ * Ensure the id_token_claim contains the required values.
*
- * @param $id_token_claim
+ * @param array $id_token_claim The ID token claim.
*
- * @return bool|\WP_Error
+ * @return bool|WP_Error
*/
- function validate_id_token_claim( $id_token_claim ){
+ function validate_id_token_claim( $id_token_claim ) {
if ( ! is_array( $id_token_claim ) ) {
- return new WP_Error( 'bad-id-token-claim', __( 'Bad ID token claim' ), $id_token_claim );
+ return new WP_Error( 'bad-id-token-claim', __( 'Bad ID token claim.', 'daggerhart-openid-connect-generic' ), $id_token_claim );
}
- // make sure we can find our identification data and that it has a value
+ // Validate the identification data and it's value.
if ( ! isset( $id_token_claim['sub'] ) || empty( $id_token_claim['sub'] ) ) {
- return new WP_Error( 'no-subject-identity', __( 'No subject identity' ), $id_token_claim );
+ return new WP_Error( 'no-subject-identity', __( 'No subject identity.', 'daggerhart-openid-connect-generic' ), $id_token_claim );
}
return true;
}
/**
- * Attempt to exchange the access_token for a user_claim
+ * Attempt to exchange the access_token for a user_claim.
*
- * @param $token_response
+ * @param array $token_response The token response.
*
- * @return array|mixed|object|\WP_Error
+ * @return array|WP_Error|null
*/
- function get_user_claim( $token_response ){
- // send a userinfo request to get user claim
+ function get_user_claim( $token_response ) {
+ // Send a userinfo request to get user claim.
$user_claim_result = $this->request_userinfo( $token_response['access_token'] );
- // make sure we didn't get an error, and that the response body exists
+ // Make sure we didn't get an error, and that the response body exists.
if ( is_wp_error( $user_claim_result ) || ! isset( $user_claim_result['body'] ) ) {
- return new WP_Error( 'bad-claim', __( 'Bad user claim' ), $user_claim_result );
+ return new WP_Error( 'bad-claim', __( 'Bad user claim.', 'daggerhart-openid-connect-generic' ), $user_claim_result );
}
$user_claim = json_decode( $user_claim_result['body'], true );
@@ -382,49 +484,50 @@ class OpenID_Connect_Generic_Client {
* Make sure the user_claim has all required values, and that the subject
* identity matches of the id_token matches that of the user_claim.
*
- * @param $user_claim
- * @param $id_token_claim
+ * @param array $user_claim The authenticated user claim.
+ * @param array $id_token_claim The ID token claim.
*
- * @return \WP_Error
+ * @return bool|WP_Error
*/
function validate_user_claim( $user_claim, $id_token_claim ) {
- // must be an array
- if ( ! is_array( $user_claim ) ){
- return new WP_Error( 'invalid-user-claim', __( 'Invalid user claim' ), $user_claim );
+ // Validate the user claim.
+ if ( ! is_array( $user_claim ) ) {
+ return new WP_Error( 'invalid-user-claim', __( 'Invalid user claim.', 'daggerhart-openid-connect-generic' ), $user_claim );
}
- // allow for errors from the IDP
+ // Allow for errors from the IDP.
if ( isset( $user_claim['error'] ) ) {
- $message = __( 'Error from the IDP' );
- if ( !empty( $user_claim['error_description'] ) ) {
+ $message = __( 'Error from the IDP.', 'daggerhart-openid-connect-generic' );
+ if ( ! empty( $user_claim['error_description'] ) ) {
$message = $user_claim['error_description'];
}
return new WP_Error( 'invalid-user-claim-' . $user_claim['error'], $message, $user_claim );
}
- // make sure the id_token sub === user_claim sub, according to spec
- if ( $id_token_claim['sub' ] !== $user_claim['sub'] ) {
- return new WP_Error( 'incorrect-user-claim', __( 'Incorrect user claim' ), func_get_args() );
+ // Make sure the id_token sub equals the user_claim sub, according to spec.
+ if ( $id_token_claim['sub'] !== $user_claim['sub'] ) {
+ return new WP_Error( 'incorrect-user-claim', __( 'Incorrect user claim.', 'daggerhart-openid-connect-generic' ), func_get_args() );
}
- // allow for other plugins to alter the login success
+ // Allow for other plugins to alter the login success.
$login_user = apply_filters( 'openid-connect-generic-user-login-test', true, $user_claim );
if ( ! $login_user ) {
- return new WP_Error( 'unauthorized', __( 'Unauthorized access' ), $login_user );
+ return new WP_Error( 'unauthorized', __( 'Unauthorized access.', 'daggerhart-openid-connect-generic' ), $login_user );
}
return true;
}
/**
- * Retrieve the subject identity from the id_token
+ * Retrieve the subject identity from the id_token.
*
- * @param $id_token_claim array
+ * @param array $id_token_claim The ID token claim.
*
* @return mixed
*/
- function get_subject_identity( $id_token_claim ){
+ function get_subject_identity( $id_token_claim ) {
return $id_token_claim['sub'];
}
+
}
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-login-form.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-login-form.php
index 25c48a2..a4a13db 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-login-form.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-login-form.php
@@ -1,89 +1,120 @@
<?php
-
+/**
+ * Login form and login button handlong class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Login
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
+
+/**
+ * OpenID_Connect_Generic_Login_Form class.
+ *
+ * Login form and login button handlong.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Login
+ */
class OpenID_Connect_Generic_Login_Form {
+ /**
+ * Plugin settings object.
+ *
+ * @var OpenID_Connect_Generic_Option_Settings
+ */
private $settings;
+
+ /**
+ * Plugin client wrapper instance.
+ *
+ * @var OpenID_Connect_Generic_Client_Wrapper
+ */
private $client_wrapper;
/**
- * @param $settings
- * @param $client_wrapper
+ * The class constructor.
+ *
+ * @param OpenID_Connect_Generic_Option_Settings $settings A plugin settings object instance.
+ * @param OpenID_Connect_Generic_Client_Wrapper $client_wrapper A plugin client wrapper object instance.
*/
- function __construct( $settings, $client_wrapper ){
+ function __construct( $settings, $client_wrapper ) {
$this->settings = $settings;
$this->client_wrapper = $client_wrapper;
- // maybe set redirect cookie on formular page
- add_action('login_form_login', [$this, 'handle_redirect_cookie']);
+ // Handle setting the redirect cookie on a formu page.
+ add_action( 'login_form_login', array( $this, 'handle_redirect_cookie' ) );
}
/**
- * @param $settings
- * @param $client_wrapper
+ * Create an instance of the OpenID_Connect_Generic_Login_Form class.
*
- * @return \OpenID_Connect_Generic_Login_Form
+ * @param OpenID_Connect_Generic_Option_Settings $settings A plugin settings object instance.
+ * @param OpenID_Connect_Generic_Client_Wrapper $client_wrapper A plugin client wrapper object instance.
+ *
+ * @return void
*/
- static public function register( $settings, $client_wrapper ){
+ static public function register( $settings, $client_wrapper ) {
$login_form = new self( $settings, $client_wrapper );
- // alter the login form as dictated by settings
+ // Alter the login form as dictated by settings.
add_filter( 'login_message', array( $login_form, 'handle_login_page' ), 99 );
- // allow extensions to also hook the login form
- do_action ( 'openid-connect-generic-register-login-form', $login_form );
+ // Allow extensions to hook the login form.
+ do_action( 'openid-connect-generic-register-login-form', $login_form );
- // add a shortcode for the login button
+ // Add a shortcode for the login button.
add_shortcode( 'openid_connect_generic_login_button', array( $login_form, 'make_login_button' ) );
$login_form->handle_redirect_login_type_auto();
-
- return $login_form;
}
/**
- * Auto Login redirect
+ * Auto Login redirect.
+ *
+ * @return void
*/
- function handle_redirect_login_type_auto()
- {
- if ( $GLOBALS['pagenow'] == 'wp-login.php'
- && ( $this->settings->login_type == 'auto' || ! empty( $_GET['force_redirect'] ) )
- && ( ! isset( $_GET[ 'action' ] ) || $_GET[ 'action' ] !== 'logout' )
- && ! isset( $_POST['wp-submit'] ) )
- {
- if ( ! isset( $_GET['login-error'] ) ) {
- $this->handle_redirect_cookie();
+ function handle_redirect_login_type_auto() {
+
+ if ( 'wp-login.php' == $GLOBALS['pagenow']
+ && ( 'auto' == $this->settings->login_type || ! empty( $_GET['force_redirect'] ) )
+ && ( ! isset( $_GET['action'] ) || 'logout' !== $_GET['action'] )
+ && ! isset( $_POST['wp-submit'] ) ) {
+ if ( ! isset( $_GET['login-error'] ) ) {
+ $this->handle_redirect_cookie();
wp_redirect( $this->client_wrapper->get_authentication_url() );
exit;
- }
- else {
+ } else {
add_action( 'login_footer', array( $this, 'remove_login_form' ), 99 );
}
}
+
}
/**
- * Handle login related redirects
+ * Handle login related redirects.
+ *
+ * @return void
*/
- function handle_redirect_cookie()
- {
- if ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'logout' ) {
+ function handle_redirect_cookie() {
+ if ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' == $GLOBALS['pagenow'] && isset( $_GET['action'] ) && 'logout' === $_GET['action'] ) {
return;
}
- // record the URL of this page if set to redirect back to origin page
- if ( $this->settings->redirect_user_back )
- {
- $redirect_expiry = current_time('timestamp') + DAY_IN_SECONDS;
+ // Record the URL of this page if set to redirect back to origin page.
+ if ( $this->settings->redirect_user_back ) {
+ $redirect_expiry = current_time( 'timestamp' ) + DAY_IN_SECONDS;
- // default redirect to the homepage
+ // Default redirect to the homepage.
$redirect_url = home_url( esc_url( add_query_arg( null, null ) ) );
- if ( $GLOBALS['pagenow'] == 'wp-login.php' ) {
- // if using the login form, default redirect to the admin dashboard
+ if ( isset( $GLOBALS['pagenow'] ) && 'wp-login.php' == $GLOBALS['pagenow'] ) {
+ // If using the login form, default redirect to the admin dashboard.
$redirect_url = admin_url();
if ( isset( $_REQUEST['redirect_to'] ) ) {
- $redirect_url = esc_url_raw( $_REQUEST[ 'redirect_to' ] );
+ $redirect_url = esc_url_raw( $_REQUEST['redirect_to'] );
}
}
@@ -94,9 +125,10 @@ class OpenID_Connect_Generic_Login_Form {
}
/**
- * Implements filter login_message
+ * Implements filter login_message.
+ *
+ * @param string $message The text message to display on the login page.
*
- * @param $message
* @return string
*/
function handle_login_page( $message ) {
@@ -105,15 +137,17 @@ class OpenID_Connect_Generic_Login_Form {
$message .= $this->make_error_output( $_GET['login-error'], $_GET['message'] );
}
- // login button is appended to existing messages in case of error
+ // Login button is appended to existing messages in case of error.
$message .= $this->make_login_button();
+
return $message;
}
/**
- * Display an error message to the user
+ * Display an error message to the user.
*
- * @param $error_code
+ * @param string $error_code The error code.
+ * @param string $error_message The error message test.
*
* @return string
*/
@@ -122,21 +156,29 @@ class OpenID_Connect_Generic_Login_Form {
ob_start();
?>
<div id="login_error">
- <strong><?php _e( 'ERROR'); ?>: </strong>
- <?php print esc_html($error_message); ?>
+ <strong><?php printf( __( 'ERROR (%1$s)', 'daggerhart-openid-connect-generic' ), $error_code ); ?>: </strong>
+ <?php print esc_html( $error_message ); ?>
</div>
<?php
return ob_get_clean();
}
/**
- * Create a login button (link)
+ * Create a login button (link).
+ *
+ * @param array $atts Array of optional attributes to override login buton
+ * functionality when used by shortcode.
*
* @return string
*/
- function make_login_button() {
- $text = apply_filters( 'openid-connect-generic-login-button-text', __( 'Login with OpenID Connect' ) );
- $href = apply_filters( 'openid-connect-generic-login-button-url', $this->client_wrapper->get_authentication_url() );
+ function make_login_button( $atts = array() ) {
+ $button_text = __( 'Login with OpenID Connect', 'daggerhart-openid-connect-generic' );
+ if ( ! empty( $atts['button_text'] ) ) {
+ $button_text = $atts['button_text'];
+ }
+
+ $text = apply_filters( 'openid-connect-generic-login-button-text', $button_text );
+ $href = $this->client_wrapper->get_authentication_url( $atts );
ob_start();
?>
@@ -147,8 +189,10 @@ class OpenID_Connect_Generic_Login_Form {
return ob_get_clean();
}
- /*
+ /**
* Removes the login form from the HTML DOM
+ *
+ * @return void
*/
function remove_login_form() {
?>
@@ -161,4 +205,5 @@ class OpenID_Connect_Generic_Login_Form {
</script>
<?php
}
+
}
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-logger.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-logger.php
index 3ea7b1d..d61e539 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-logger.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-logger.php
@@ -1,90 +1,132 @@
<?php
/**
- * Simple class for logging messages to the options table
+ * Plugin logging class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Logging
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
+
+/**
+ * OpenID_Connect_Generic_Option_Logger class.
+ *
+ * Simple class for logging messages to the options table.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Logging
*/
class OpenID_Connect_Generic_Option_Logger {
- // wp option name/key
+ /**
+ * Thw WordPress option name/key.
+ *
+ * @var string
+ */
private $option_name;
- // default message type
+ /**
+ * The default message type.
+ *
+ * @var string
+ */
private $default_message_type;
- // the number of items to keep in the log
+ /**
+ * The number of items to keep in the log.
+ *
+ * @var int
+ */
private $log_limit;
- // whether or not the
+ /**
+ * Whether or not logging is enabled.
+ *
+ * @var bool
+ */
private $logging_enabled;
- // internal cache of logs
+ /**
+ * Internal cache of logs.
+ *
+ * @var array
+ */
private $logs;
/**
- * Setup the logger according to the needs of the instance
+ * Setup the logger according to the needs of the instance.
*
- * @param string $option_name
- * @param string $default_message_type
- * @param bool|TRUE $logging_enabled
- * @param int $log_limit
+ * @param string $option_name The plugin log WordPress option name.
+ * @param string $default_message_type The log message type.
+ * @param bool|TRUE $logging_enabled Whether logging is enabled.
+ * @param int $log_limit The log entry limit.
*/
- function __construct( $option_name, $default_message_type = 'none', $logging_enabled = true, $log_limit = 1000 ){
+ function __construct( $option_name, $default_message_type = 'none', $logging_enabled = true, $log_limit = 1000 ) {
$this->option_name = $option_name;
$this->default_message_type = $default_message_type;
- $this->logging_enabled = (bool) $logging_enabled;
- $this->log_limit = (int) $log_limit;
+ $this->logging_enabled = boolval( $logging_enabled );
+ $this->log_limit = intval( $log_limit );
}
/**
- * Subscribe logger to a set of filters
+ * Subscribe logger to a set of filters.
*
- * @param $filter_names
- * @param int $priority
+ * @param array|string $filter_names The array, or string, of the name(s) of an filter(s) to hook the logger into.
+ * @param int $priority The WordPress filter priority level.
+ *
+ * @return void
*/
- function log_filters( $filter_names, $priority = 10 ){
+ function log_filters( $filter_names, $priority = 10 ) {
if ( ! is_array( $filter_names ) ) {
$filter_names = array( $filter_names );
}
- foreach ( $filter_names as $filter ){
+ foreach ( $filter_names as $filter ) {
add_filter( $filter, array( $this, 'log_hook' ), $priority );
}
}
/**
- * Subscribe logger to a set of actions
+ * Subscribe logger to a set of actions.
+ *
+ * @param array|string $action_names The array, or string, of the name(s) of an action(s) to hook the logger into.
+ * @param int $priority The WordPress action priority level.
*
- * @param $action_names
- * @param $priority
+ * @return void
*/
- function log_actions( $action_names, $priority ){
+ function log_actions( $action_names, $priority ) {
if ( ! is_array( $action_names ) ) {
$action_names = array( $action_names );
}
- foreach ( $action_names as $action ){
+ foreach ( $action_names as $action ) {
add_filter( $action, array( $this, 'log_hook' ), $priority );
}
}
/**
- * Log the data
+ * Log the data.
+ *
+ * @param mixed $arg1 The hook argument.
*
- * @param null $arg1
- * @return null
+ * @return mixed
*/
- function log_hook( $arg1 = null ){
+ function log_hook( $arg1 = null ) {
$this->log( func_get_args(), current_filter() );
return $arg1;
}
/**
- * Save an array of data to the logs
+ * Save an array of data to the logs.
+ *
+ * @param mixed $data The data to be logged.
+ * @param mixed $type The type of log message.
*
- * @param $data mixed
* @return bool
*/
public function log( $data, $type = null ) {
- if ( (bool) $this->logging_enabled ) {
+ if ( boolval( $this->logging_enabled ) ) {
$logs = $this->get_logs();
$logs[] = $this->make_message( $data, $type );
$logs = $this->upkeep_logs( $logs );
@@ -95,12 +137,12 @@ class OpenID_Connect_Generic_Option_Logger {
}
/**
- * Retrieve all log messages
+ * Retrieve all log messages.
*
* @return array
*/
public function get_logs() {
- if ( is_null( $this->logs ) ) {
+ if ( empty( $this->logs ) ) {
$this->logs = get_option( $this->option_name, array() );
}
@@ -108,41 +150,40 @@ class OpenID_Connect_Generic_Option_Logger {
}
/**
- * Get the name of the option where this log is stored
+ * Get the name of the option where this log is stored.
*
* @return string
*/
- public function get_option_name(){
+ public function get_option_name() {
return $this->option_name;
}
/**
- * Create a message array containing the data and other information
+ * Create a message array containing the data and other information.
*
- * @param $data mixed
- * @param $type
+ * @param mixed $data The log message data.
+ * @param mixed $type The log message type.
*
* @return array
*/
- private function make_message( $data, $type ){
- // determine the type of message
+ private function make_message( $data, $type ) {
+ // Determine the type of message.
if ( empty( $type ) ) {
- $this->default_message_type;
+ $type = $this->default_message_type;
- if ( is_array( $data ) && isset( $data['type'] ) ){
+ if ( is_array( $data ) && isset( $data['type'] ) ) {
$type = $data['type'];
- }
- else if ( is_wp_error( $data ) ){
+ } else if ( is_wp_error( $data ) ) {
$type = $data->get_error_code();
}
}
- // construct our message
+ // Construct the message.
$message = array(
'type' => $type,
'time' => time(),
'user_ID' => get_current_user_id(),
- 'uri' => preg_replace('/code=([^&]+)/i', 'code=', $_SERVER['REQUEST_URI']),
+ 'uri' => preg_replace( '/code=([^&]+)/i', 'code=', $_SERVER['REQUEST_URI'] ),
'data' => $data,
);
@@ -150,54 +191,59 @@ class OpenID_Connect_Generic_Option_Logger {
}
/**
- * Keep our log count under the limit
+ * Keep the log count under the limit.
+ *
+ * @param array $logs The plugin logs.
*
- * @param $message array - extra data about the message
* @return array
*/
private function upkeep_logs( $logs ) {
$items_to_remove = count( $logs ) - $this->log_limit;
- if ( $items_to_remove > 0 ){
- // keep only the last $log_limit messages from the end
- $logs = array_slice( $logs, ( $items_to_remove * -1) );
+ if ( $items_to_remove > 0 ) {
+ // Only keep the last $log_limit messages from the end.
+ $logs = array_slice( $logs, ( $items_to_remove * -1 ) );
}
return $logs;
}
/**
- * Save the log messages
+ * Save the log messages.
+ *
+ * @param array $logs The array of log messages.
*
- * @param $logs
* @return bool
*/
- private function save_logs( $logs ){
- // save our logs
+ private function save_logs( $logs ) {
+ // Save the logs.
$this->logs = $logs;
return update_option( $this->option_name, $logs, false );
}
/**
- * Clear all log messages
+ * Clear all log messages.
+ *
+ * @return void
*/
- public function clear_logs(){
+ public function clear_logs() {
$this->save_logs( array() );
}
/**
- * Get a simple html table of all the logs
+ * Get a simple html table of all the logs.
+ *
+ * @param array $logs The array of log messages.
*
- * @param array $logs
* @return string
*/
- public function get_logs_table( $logs = array() ){
+ public function get_logs_table( $logs = array() ) {
if ( empty( $logs ) ) {
$logs = $this->get_logs();
}
$logs = array_reverse( $logs );
- ini_set( 'xdebug.var_display_max_depth', -1 );
+ ini_set( 'xdebug.var_display_max_depth', '-1' );
ob_start();
?>
@@ -216,19 +262,19 @@ class OpenID_Connect_Generic_Option_Logger {
<tr>
<td class="col-details">
<div>
- <label><?php _e( 'Type' ); ?>: </label>
+ <label><?php _e( 'Type', 'daggerhart-openid-connect-generic' ); ?>: </label>
<?php print $log['type']; ?>
</div>
<div>
- <label><?php _e( 'Date' ); ?>: </label>
- <?php print date( 'Y-m-d H:i:s', $log['time'] ); ?>
+ <label><?php _e( 'Date', 'daggerhart-openid-connect-generic' ); ?>: </label>
+ <?php print gmdate( 'Y-m-d H:i:s', $log['time'] ); ?>
</div>
<div>
- <label><?php _e( 'User' ); ?>: </label>
+ <label><?php _e( 'User', 'daggerhart-openid-connect-generic' ); ?>: </label>
<?php print ( get_userdata( $log['user_ID'] ) ) ? get_userdata( $log['user_ID'] )->user_login : '0'; ?>
</div>
<div>
- <label><?php _e( 'URI ' ); ?>: </label>
+ <label><?php _e( 'URI ', 'daggerhart-openid-connect-generic' ); ?>: </label>
<?php print $log['uri']; ?>
</div>
</td>
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-settings.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-settings.php
index 7b9b9a0..7b6ec2a 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-settings.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-option-settings.php
@@ -1,60 +1,207 @@
<?php
/**
- * Class OpenId_Connect_Generic_Option_Settings
+ * WordPress options handling class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Settings
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
+
+/**
+ * OpenId_Connect_Generic_Option_Settings class.
+ *
+ * WordPress options handling.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Settings
+ *
+ * Legacy Settings:
+ *
+ * @property string $ep_login The login endpoint.
+ * @property string $ep_token The token endpoint.
+ * @property string $ep_userinfo The userinfo endpoint.
+ *
+ * OAuth Client Settings:
+ *
+ * @property string $login_type How the client (login form) should provide login options.
+ * @property string $client_id The ID the client will be recognized as when connecting the to Identity provider server.
+ * @property string $client_secret The secret key the IDP server expects from the client.
+ * @property string $scope The list of scopes this client should access.
+ * @property string $endpoint_login The IDP authorization endpoint URL.
+ * @property string $endpoint_userinfo The IDP User information endpoint URL.
+ * @property string $endpoint_token The IDP token validation endpoint URL.
+ * @property string $endpoint_end_session The IDP logout endpoint URL.
+ *
+ * Non-standard Settings:
+ *
+ * @property bool $no_sslverify The flag to enable/disable SSL verification during authorization.
+ * @property int $http_request_timeout The timeout for requests made to the IDP. Default value is 5.
+ * @property string $identity_key The key in the user claim array to find the user's identification data.
+ * @property string $nickname_key The key in the user claim array to find the user's nickname.
+ * @property string $email_format The key(s) in the user claim array to formulate the user's email address.
+ * @property string $displayname_format The key(s) in the user claim array to formulate the user's display name.
+ * @property bool $identify_with_username The flag which indicates how the user's identity will be determined.
+ * @property int $state_time_limit The valid time limit of the state, in seconds. Defaults to 180 seconds.
+ *
+ * Plugin Settings:
+ *
+ * @property bool $enforce_privacy The flag to indicates whether a user us required to be authenticated to access the site.
+ * @property bool $alternate_redirect_uri The flag to indicate whether to use the alternative redirect URI.
+ * @property bool $token_refresh_enable The flag whether to support refresh tokens by IDPs.
+ * @property bool $link_existing_users The flag to indicate whether to link to existing WordPress-only accounts or greturn an error.
+ * @property bool $create_if_does_not_exist The flag to indicate whether to create new users or not.
+ * @property bool $redirect_user_back The flag to indicate whether to redirect the user back to the page on which they started.
+ * @property bool $redirect_on_logout The flag to indicate whether to redirect to the login screen on session expiration.
+ * @property bool $enable_logging The flag to enable/disable logging.
+ * @property int $log_limit The maximum number of log entries to keep.
*/
class OpenID_Connect_Generic_Option_Settings {
- // wp option name/key
+ /**
+ * WordPress option name/key.
+ *
+ * @var string
+ */
private $option_name;
- // stored option values array
+ /**
+ * Stored option values array.
+ *
+ * @var array<mixed>
+ */
private $values;
- // default plugin settings values
+ /**
+ * Default plugin settings values.
+ *
+ * @var array<mixed>
+ */
private $default_settings;
/**
- * @param $option_name
- * @param array $default_settings
- * @param bool|TRUE $granular_defaults
+ * List of settings that can be defined by environment variables.
+ *
+ * @var array<string,string>
*/
- function __construct( $option_name, $default_settings = array(), $granular_defaults = true ){
+ private $environment_settings = array(
+ 'client_id' => 'OIDC_CLIENT_ID',
+ 'client_secret' => 'OIDC_CLIENT_SECRET',
+ 'endpoint_login' => 'OIDC_ENDPOINT_LOGIN_URL',
+ 'endpoint_userinfo' => 'OIDC_ENDPOINT_USERINFO_URL',
+ 'endpoint_token' => 'OIDC_ENDPOINT_TOKEN_URL',
+ 'endpoint_end_session' => 'OIDC_ENDPOINT_LOGOUT_URL',
+ );
+
+ /**
+ * The class constructor.
+ *
+ * @param string $option_name The option name/key.
+ * @param array<mixed> $default_settings The default plugin settings values.
+ * @param bool $granular_defaults The granular defaults.
+ */
+ function __construct( $option_name, $default_settings = array(), $granular_defaults = true ) {
$this->option_name = $option_name;
$this->default_settings = $default_settings;
- $this->values = get_option( $this->option_name, $this->default_settings );
+ $this->values = array();
+
+ if ( ! empty( $this->option_name ) ) {
+ $this->values = (array) get_option( $this->option_name, $this->default_settings );
+ }
+
+ // For each defined environment variable/constant be sure the settings key is set.
+ foreach ( $this->environment_settings as $key => $constant ) {
+ if ( defined( $constant ) ) {
+ $this->__set( $key, constant( $constant ) );
+ }
+ }
if ( $granular_defaults ) {
$this->values = array_replace_recursive( $this->default_settings, $this->values );
}
}
- function __get( $key ){
+ /**
+ * Magic getter for settings.
+ *
+ * @param string $key The array key/option name.
+ *
+ * @return mixed
+ */
+ function __get( $key ) {
if ( isset( $this->values[ $key ] ) ) {
return $this->values[ $key ];
}
}
- function __set( $key, $value ){
+ /**
+ * Magic setter for settings.
+ *
+ * @param string $key The array key/option name.
+ * @param mixed $value The option value.
+ *
+ * @return void
+ */
+ function __set( $key, $value ) {
$this->values[ $key ] = $value;
}
- function __isset( $key ){
+ /**
+ * Magic method to check is an attribute isset.
+ *
+ * @param string $key The array key/option name.
+ *
+ * @return bool
+ */
+ function __isset( $key ) {
return isset( $this->values[ $key ] );
}
- function __unset( $key ){
- unset( $this->values[ $key ]);
+ /**
+ * Magic method to clear an attribute.
+ *
+ * @param string $key The array key/option name.
+ *
+ * @return void
+ */
+ function __unset( $key ) {
+ unset( $this->values[ $key ] );
}
- function get_values(){
+ /**
+ * Get the plugin settings array.
+ *
+ * @return array
+ */
+ function get_values() {
return $this->values;
}
+ /**
+ * Get the plugin WordPress options name.
+ *
+ * @return string
+ */
function get_option_name() {
return $this->option_name;
}
- function save(){
+ /**
+ * Save the plugin options to the WordPress options table.
+ *
+ * @return void
+ */
+ function save() {
+
+ // For each defined environment variable/constant be sure it isn't saved to the database.
+ foreach ( $this->environment_settings as $key => $constant ) {
+ if ( defined( $constant ) ) {
+ $this->__unset( $key );
+ }
+ }
+
update_option( $this->option_name, $this->values );
+
}
}
diff --git a/daggerhart-openid-connect-generic/includes/openid-connect-generic-settings-page.php b/daggerhart-openid-connect-generic/includes/openid-connect-generic-settings-page.php
index 5178521..197052e 100755..100644
--- a/daggerhart-openid-connect-generic/includes/openid-connect-generic-settings-page.php
+++ b/daggerhart-openid-connect-generic/includes/openid-connect-generic-settings-page.php
@@ -1,35 +1,205 @@
<?php
+/**
+ * Plugin Admin settings page class.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Settings
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ */
/**
- * Class OpenID_Connect_Generic_Settings_Page.
+ * OpenID_Connect_Generic_Settings_Page class.
+ *
* Admin settings page.
+ *
+ * @package OpenID_Connect_Generic
+ * @category Settings
*/
class OpenID_Connect_Generic_Settings_Page {
- // local copy of the settings provided by the base plugin
+ /**
+ * Local copy of the settings provided by the base plugin.
+ *
+ * @var OpenID_Connect_Generic_Option_Settings
+ */
private $settings;
- // The controlled list of settings & associated
- // defined during construction for i18n reasons
+ /**
+ * Instance of the plugin logger.
+ *
+ * @var OpenID_Connect_Generic_Option_Logger
+ */
+ private $logger;
+
+ /**
+ * The controlled list of settings & associated defined during
+ * construction for i18n reasons.
+ *
+ * @var array
+ */
private $settings_fields = array();
- // options page slug
+ /**
+ * Options page slug.
+ *
+ * @var string
+ */
private $options_page_name = 'openid-connect-generic-settings';
- // options page settings group name
+ /**
+ * Options page settings group name.
+ *
+ * @var string
+ */
private $settings_field_group;
/**
- * @param OpenID_Connect_Generic_Option_Settings $settings
- * @param OpenID_Connect_Generic_Option_Logger $logger
+ * Settings page class constructor.
+ *
+ * @param OpenID_Connect_Generic_Option_Settings $settings The plugin settings object.
+ * @param OpenID_Connect_Generic_Option_Logger $logger The plugin logging class object.
*/
function __construct( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
+
$this->settings = $settings;
$this->logger = $logger;
$this->settings_field_group = $this->settings->get_option_name() . '-group';
- /*
- * Simple settings fields simply have:
+ $fields = $this->get_settings_fields();
+
+ // Some simple pre-processing.
+ foreach ( $fields as $key => &$field ) {
+ $field['key'] = $key;
+ $field['name'] = $this->settings->get_option_name() . '[' . $key . ']';
+ }
+
+ // Allow alterations of the fields.
+ $this->settings_fields = $fields;
+ }
+
+ /**
+ * Hook the settings page into WordPress.
+ *
+ * @param OpenID_Connect_Generic_Option_Settings $settings A plugin settings object instance.
+ * @param OpenID_Connect_Generic_Option_Logger $logger A plugin logger object instance.
+ *
+ * @return void
+ */
+ static public function register( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
+ $settings_page = new self( $settings, $logger );
+
+ // Add our options page the the admin menu.
+ add_action( 'admin_menu', array( $settings_page, 'admin_menu' ) );
+
+ // Register our settings.
+ add_action( 'admin_init', array( $settings_page, 'admin_init' ) );
+ }
+
+ /**
+ * Implements hook admin_menu to add our options/settings page to the
+ * dashboard menu.
+ *
+ * @return void
+ */
+ public function admin_menu() {
+ add_options_page(
+ __( 'OpenID Connect - Generic Client', 'daggerhart-openid-connect-generic' ),
+ __( 'OpenID Connect Client', 'daggerhart-openid-connect-generic' ),
+ 'manage_options',
+ $this->options_page_name,
+ array( $this, 'settings_page' )
+ );
+ }
+
+ /**
+ * Implements hook admin_init to register our settings.
+ *
+ * @return void
+ */
+ public function admin_init() {
+ register_setting(
+ $this->settings_field_group,
+ $this->settings->get_option_name(),
+ array(
+ $this,
+ 'sanitize_settings',
+ )
+ );
+
+ add_settings_section(
+ 'client_settings',
+ __( 'Client Settings', 'daggerhart-openid-connect-generic' ),
+ array( $this, 'client_settings_description' ),
+ $this->options_page_name
+ );
+
+ add_settings_section(
+ 'user_settings',
+ __( 'WordPress User Settings', 'daggerhart-openid-connect-generic' ),
+ array( $this, 'user_settings_description' ),
+ $this->options_page_name
+ );
+
+ add_settings_section(
+ 'authorization_settings',
+ __( 'Authorization Settings', 'daggerhart-openid-connect-generic' ),
+ array( $this, 'authorization_settings_description' ),
+ $this->options_page_name
+ );
+
+ add_settings_section(
+ 'log_settings',
+ __( 'Log Settings', 'daggerhart-openid-connect-generic' ),
+ array( $this, 'log_settings_description' ),
+ $this->options_page_name
+ );
+
+ // Preprocess fields and add them to the page.
+ foreach ( $this->settings_fields as $key => $field ) {
+ // Make sure each key exists in the settings array.
+ if ( ! isset( $this->settings->{ $key } ) ) {
+ $this->settings->{ $key } = null;
+ }
+
+ // Determine appropriate output callback.
+ switch ( $field['type'] ) {
+ case 'checkbox':
+ $callback = 'do_checkbox';
+ break;
+
+ case 'select':
+ $callback = 'do_select';
+ break;
+
+ case 'text':
+ default:
+ $callback = 'do_text_field';
+ break;
+ }
+
+ // Add the field.
+ add_settings_field(
+ $key,
+ $field['title'],
+ array( $this, $callback ),
+ $this->options_page_name,
+ $field['section'],
+ $field
+ );
+ }
+ }
+
+ /**
+ * Get the plugin settings fields definition.
+ *
+ * @return array
+ */
+ private function get_settings_fields() {
+
+ /**
+ * Simple settings fields have:
*
* - title
* - description
@@ -39,291 +209,197 @@ class OpenID_Connect_Generic_Settings_Page {
*/
$fields = array(
'login_type' => array(
- 'title' => __( 'Login Type' ),
- 'description' => __( 'Select how the client (login form) should provide login options.' ),
+ 'title' => __( 'Login Type', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Select how the client (login form) should provide login options.', 'daggerhart-openid-connect-generic' ),
'type' => 'select',
'options' => array(
- 'button' => __( 'OpenID Connect button on login form' ),
- 'auto' => __( 'Auto Login - SSO' ),
+ 'button' => __( 'OpenID Connect button on login form', 'daggerhart-openid-connect-generic' ),
+ 'auto' => __( 'Auto Login - SSO', 'daggerhart-openid-connect-generic' ),
),
'section' => 'client_settings',
),
'client_id' => array(
- 'title' => __( 'Client ID' ),
- 'description' => __( 'The ID this client will be recognized as when connecting the to Identity provider server.' ),
+ 'title' => __( 'Client ID', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'The ID this client will be recognized as when connecting the to Identity provider server.', 'daggerhart-openid-connect-generic' ),
'example' => 'my-wordpress-client-id',
'type' => 'text',
+ 'disabled' => defined( 'OIDC_CLIENT_ID' ),
'section' => 'client_settings',
),
'client_secret' => array(
- 'title' => __( 'Client Secret Key' ),
- 'description' => __( 'Arbitrary secret key the server expects from this client. Can be anything, but should be very unique.' ),
+ 'title' => __( 'Client Secret Key', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Arbitrary secret key the server expects from this client. Can be anything, but should be very unique.', 'daggerhart-openid-connect-generic' ),
'type' => 'text',
+ 'disabled' => defined( 'OIDC_CLIENT_SECRET' ),
'section' => 'client_settings',
),
'scope' => array(
- 'title' => __( 'OpenID Scope' ),
- 'description' => __( 'Space separated list of scopes this client should access.' ),
+ 'title' => __( 'OpenID Scope', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Space separated list of scopes this client should access.', 'daggerhart-openid-connect-generic' ),
'example' => 'email profile openid offline_access',
'type' => 'text',
'section' => 'client_settings',
),
'endpoint_login' => array(
- 'title' => __( 'Login Endpoint URL' ),
- 'description' => __( 'Identify provider authorization endpoint.' ),
+ 'title' => __( 'Login Endpoint URL', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Identify provider authorization endpoint.', 'daggerhart-openid-connect-generic' ),
'example' => 'https://example.com/oauth2/authorize',
'type' => 'text',
+ 'disabled' => defined( 'OIDC_ENDPOINT_LOGIN_URL' ),
'section' => 'client_settings',
),
'endpoint_userinfo' => array(
- 'title' => __( 'Userinfo Endpoint URL' ),
- 'description' => __( 'Identify provider User information endpoint.' ),
+ 'title' => __( 'Userinfo Endpoint URL', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Identify provider User information endpoint.', 'daggerhart-openid-connect-generic' ),
'example' => 'https://example.com/oauth2/UserInfo',
'type' => 'text',
+ 'disabled' => defined( 'OIDC_ENDPOINT_USERINFO_URL' ),
'section' => 'client_settings',
),
'endpoint_token' => array(
- 'title' => __( 'Token Validation Endpoint URL' ),
- 'description' => __( 'Identify provider token endpoint.' ),
+ 'title' => __( 'Token Validation Endpoint URL', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Identify provider token endpoint.', 'daggerhart-openid-connect-generic' ),
'example' => 'https://example.com/oauth2/token',
'type' => 'text',
+ 'disabled' => defined( 'OIDC_ENDPOINT_TOKEN_URL' ),
'section' => 'client_settings',
),
'endpoint_end_session' => array(
- 'title' => __( 'End Session Endpoint URL' ),
- 'description' => __( 'Identify provider logout endpoint.' ),
+ 'title' => __( 'End Session Endpoint URL', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Identify provider logout endpoint.', 'daggerhart-openid-connect-generic' ),
'example' => 'https://example.com/oauth2/logout',
'type' => 'text',
+ 'disabled' => defined( 'OIDC_ENDPOINT_LOGOUT_URL' ),
'section' => 'client_settings',
),
'identity_key' => array(
- 'title' => __( 'Identity Key' ),
- 'description' => __( 'Where in the user claim array to find the user\'s identification data. Possible standard values: preferred_username, name, or sub. If you\'re having trouble, use "sub".' ),
+ 'title' => __( 'Identity Key', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Where in the user claim array to find the user\'s identification data. Possible standard values: preferred_username, name, or sub. If you\'re having trouble, use "sub".', 'daggerhart-openid-connect-generic' ),
'example' => 'preferred_username',
'type' => 'text',
'section' => 'client_settings',
),
'no_sslverify' => array(
- 'title' => __( 'Disable SSL Verify' ),
- 'description' => __( 'Do not require SSL verification during authorization. The OAuth extension uses curl to make the request. By default CURL will generally verify the SSL certificate to see if its valid an issued by an accepted CA. This setting disabled that verification.<br><strong>Not recommended for production sites.</strong>' ),
+ 'title' => __( 'Disable SSL Verify', 'daggerhart-openid-connect-generic' ),
+ 'description' => sprintf( __( 'Do not require SSL verification during authorization. The OAuth extension uses curl to make the request. By default CURL will generally verify the SSL certificate to see if its valid an issued by an accepted CA. This setting disabled that verification.%1$sNot recommended for production sites.%2$s', 'daggerhart-openid-connect-generic' ), '<br><strong>', '</strong>' ),
'type' => 'checkbox',
'section' => 'client_settings',
),
'http_request_timeout' => array(
- 'title' => __( 'HTTP Request Timeout' ),
- 'description' => __( 'Set the timeout for requests made to the IDP. Default value is 5.' ),
+ 'title' => __( 'HTTP Request Timeout', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Set the timeout for requests made to the IDP. Default value is 5.', 'daggerhart-openid-connect-generic' ),
'example' => 30,
'type' => 'text',
'section' => 'client_settings',
),
'enforce_privacy' => array(
- 'title' => __( 'Enforce Privacy' ),
- 'description' => __( 'Require users be logged in to see the site.' ),
+ 'title' => __( 'Enforce Privacy', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Require users be logged in to see the site.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'authorization_settings',
),
'alternate_redirect_uri' => array(
- 'title' => __( 'Alternate Redirect URI' ),
- 'description' => __( 'Provide an alternative redirect route. Useful if your server is causing issues with the default admin-ajax method. You must flush rewrite rules after changing this setting. This can be done by saving the Permalinks settings page.' ),
+ 'title' => __( 'Alternate Redirect URI', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Provide an alternative redirect route. Useful if your server is causing issues with the default admin-ajax method. You must flush rewrite rules after changing this setting. This can be done by saving the Permalinks settings page.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'authorization_settings',
),
'nickname_key' => array(
- 'title' => __( 'Nickname Key' ),
- 'description' => __( 'Where in the user claim array to find the user\'s nickname. Possible standard values: preferred_username, name, or sub.' ),
+ 'title' => __( 'Nickname Key', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Where in the user claim array to find the user\'s nickname. Possible standard values: preferred_username, name, or sub.', 'daggerhart-openid-connect-generic' ),
'example' => 'preferred_username',
'type' => 'text',
'section' => 'client_settings',
),
'email_format' => array(
- 'title' => __( 'Email Formatting' ),
- 'description' => __( 'String from which the user\'s email address is built. Specify "{email}" as long as the user claim contains an email claim.' ),
+ 'title' => __( 'Email Formatting', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'String from which the user\'s email address is built. Specify "{email}" as long as the user claim contains an email claim.', 'daggerhart-openid-connect-generic' ),
'example' => '{email}',
'type' => 'text',
'section' => 'client_settings',
),
'displayname_format' => array(
- 'title' => __( 'Display Name Formatting' ),
- 'description' => __( 'String from which the user\'s display name is built.' ),
+ 'title' => __( 'Display Name Formatting', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'String from which the user\'s display name is built.', 'daggerhart-openid-connect-generic' ),
'example' => '{given_name} {family_name}',
'type' => 'text',
'section' => 'client_settings',
),
'identify_with_username' => array(
- 'title' => __( 'Identify with User Name' ),
- 'description' => __( 'If checked, the user\'s identity will be determined by the user name instead of the email address.' ),
+ 'title' => __( 'Identify with User Name', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'If checked, the user\'s identity will be determined by the user name instead of the email address.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'client_settings',
),
'state_time_limit' => array(
- 'title' => __( 'State time limit' ),
- 'description' => __( 'State valid time in seconds. Defaults to 180' ),
+ 'title' => __( 'State time limit', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'State valid time in seconds. Defaults to 180', 'daggerhart-openid-connect-generic' ),
'type' => 'number',
'section' => 'client_settings',
),
+ 'token_refresh_enable' => array(
+ 'title' => __( 'Enable Refresh Token', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'If checked, support refresh tokens used to obtain access tokens from supported IDPs.', 'daggerhart-openid-connect-generic' ),
+ 'type' => 'checkbox',
+ 'section' => 'client_settings',
+ ),
'link_existing_users' => array(
- 'title' => __( 'Link Existing Users' ),
- 'description' => __( 'If a WordPress account already exists with the same identity as a newly-authenticated user over OpenID Connect, login as that user instead of generating an error.' ),
+ 'title' => __( 'Link Existing Users', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'If a WordPress account already exists with the same identity as a newly-authenticated user over OpenID Connect, login as that user instead of generating an error.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'user_settings',
),
'create_if_does_not_exist' => array(
- 'title' => __( 'Create user if does not exist' ),
- 'description' => __( 'If the user identity is not link to an existing Wordpress user, it is created. If this setting is not enabled and if the user authenticates with an account which is not link to an existing Wordpress user then the authentication failed' ),
+ 'title' => __( 'Create user if does not exist', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'If the user identity is not link to an existing Wordpress user, it is created. If this setting is not enabled and if the user authenticates with an account which is not link to an existing Wordpress user then the authentication failed', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'user_settings',
),
'redirect_user_back' => array(
- 'title' => __( 'Redirect Back to Origin Page' ),
- 'description' => __( 'After a successful OpenID Connect authentication, this will redirect the user back to the page on which they clicked the OpenID Connect login button. This will cause the login process to proceed in a traditional WordPress fashion. For example, users logging in through the default wp-login.php page would end up on the WordPress Dashboard and users logging in through the WooCommerce "My Account" page would end up on their account page.' ),
+ 'title' => __( 'Redirect Back to Origin Page', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'After a successful OpenID Connect authentication, this will redirect the user back to the page on which they clicked the OpenID Connect login button. This will cause the login process to proceed in a traditional WordPress fashion. For example, users logging in through the default wp-login.php page would end up on the WordPress Dashboard and users logging in through the WooCommerce "My Account" page would end up on their account page.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'user_settings',
),
'redirect_on_logout' => array(
- 'title' => __( 'Redirect to the login screen session is expired' ),
- 'description' => __( 'When enabled, this will automatically redirect the user back to the WordPress login page if their access token has expired.' ),
+ 'title' => __( 'Redirect to the login screen when session is expired', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'When enabled, this will automatically redirect the user back to the WordPress login page if their access token has expired.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'user_settings',
),
'enable_logging' => array(
- 'title' => __( 'Enable Logging' ),
- 'description' => __( 'Very simple log messages for debugging purposes.' ),
+ 'title' => __( 'Enable Logging', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Very simple log messages for debugging purposes.', 'daggerhart-openid-connect-generic' ),
'type' => 'checkbox',
'section' => 'log_settings',
),
'log_limit' => array(
- 'title' => __( 'Log Limit' ),
- 'description' => __( 'Number of items to keep in the log. These logs are stored as an option in the database, so space is limited.' ),
+ 'title' => __( 'Log Limit', 'daggerhart-openid-connect-generic' ),
+ 'description' => __( 'Number of items to keep in the log. These logs are stored as an option in the database, so space is limited.', 'daggerhart-openid-connect-generic' ),
'type' => 'number',
'section' => 'log_settings',
),
);
- $fields = apply_filters( 'openid-connect-generic-settings-fields', $fields );
-
- // some simple pre-processing
- foreach ( $fields as $key => &$field ) {
- $field['key'] = $key;
- $field['name'] = $this->settings->get_option_name() . '[' . $key . ']';
- }
+ return apply_filters( 'openid-connect-generic-settings-fields', $fields );
- // allow alterations of the fields
- $this->settings_fields = $fields;
}
/**
- * @param \OpenID_Connect_Generic_Option_Settings $settings
- * @param \OpenID_Connect_Generic_Option_Logger $logger
+ * Sanitization callback for settings/option page.
*
- * @return \OpenID_Connect_Generic_Settings_Page
- */
- static public function register( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ){
- $settings_page = new self( $settings, $logger );
-
- // add our options page the the admin menu
- add_action( 'admin_menu', array( $settings_page, 'admin_menu' ) );
-
- // register our settings
- add_action( 'admin_init', array( $settings_page, 'admin_init' ) );
-
- return $settings_page;
- }
-
- /**
- * Implements hook admin_menu to add our options/settings page to the
- * dashboard menu
- */
- public function admin_menu() {
- add_options_page(
- __( 'OpenID Connect - Generic Client' ),
- __( 'OpenID Connect Client' ),
- 'manage_options',
- $this->options_page_name,
- array( $this, 'settings_page' ) );
- }
-
- /**
- * Implements hook admin_init to register our settings
- */
- public function admin_init() {
- register_setting( $this->settings_field_group, $this->settings->get_option_name(), array(
- $this,
- 'sanitize_settings'
- ) );
-
- add_settings_section( 'client_settings',
- __( 'Client Settings' ),
- array( $this, 'client_settings_description' ),
- $this->options_page_name
- );
-
- add_settings_section( 'user_settings',
- __( 'WordPress User Settings' ),
- array( $this, 'user_settings_description' ),
- $this->options_page_name
- );
-
- add_settings_section( 'authorization_settings',
- __( 'Authorization Settings' ),
- array( $this, 'authorization_settings_description' ),
- $this->options_page_name
- );
-
- add_settings_section( 'log_settings',
- __( 'Log Settings' ),
- array( $this, 'log_settings_description' ),
- $this->options_page_name
- );
-
- // preprocess fields and add them to the page
- foreach ( $this->settings_fields as $key => $field ) {
- // make sure each key exists in the settings array
- if ( ! isset( $this->settings->{ $key } ) ) {
- $this->settings->{ $key } = null;
- }
-
- // determine appropriate output callback
- switch ( $field['type'] ) {
- case 'checkbox':
- $callback = 'do_checkbox';
- break;
-
- case 'select':
- $callback = 'do_select';
- break;
-
- case 'text':
- default:
- $callback = 'do_text_field';
- break;
- }
-
- // add the field
- add_settings_field( $key, $field['title'],
- array( $this, $callback ),
- $this->options_page_name,
- $field['section'],
- $field
- );
- }
- }
-
- /**
- * Sanitization callback for settings/option page
- *
- * @param $input - submitted settings values
+ * @param array $input The submitted settings values.
*
* @return array
*/
public function sanitize_settings( $input ) {
$options = array();
- // loop through settings fields to control what we're saving
+ // Loop through settings fields to control what we're saving.
foreach ( $this->settings_fields as $key => $field ) {
if ( isset( $input[ $key ] ) ) {
$options[ $key ] = sanitize_text_field( trim( $input[ $key ] ) );
- }
- else {
+ } else {
$options[ $key ] = '';
}
}
@@ -332,12 +408,14 @@ class OpenID_Connect_Generic_Settings_Page {
}
/**
- * Output the options/settings page
+ * Output the options/settings page.
+ *
+ * @return void
*/
public function settings_page() {
$redirect_uri = admin_url( 'admin-ajax.php?action=openid-connect-authorize' );
- if ( $this->settings->alternate_redirect_uri ){
+ if ( $this->settings->alternate_redirect_uri ) {
$redirect_uri = site_url( '/openid-connect-authorize' );
}
?>
@@ -350,30 +428,30 @@ class OpenID_Connect_Generic_Settings_Page {
do_settings_sections( $this->options_page_name );
submit_button();
- // simple debug to view settings array
+ // Simple debug to view settings array.
if ( isset( $_GET['debug'] ) ) {
var_dump( $this->settings->get_values() );
}
?>
</form>
- <h4><?php _e( 'Notes' ); ?></h4>
+ <h4><?php _e( 'Notes', 'daggerhart-openid-connect-generic' ); ?></h4>
<p class="description">
- <strong><?php _e( 'Redirect URI' ); ?></strong>
+ <strong><?php _e( 'Redirect URI', 'daggerhart-openid-connect-generic' ); ?></strong>
<code><?php print $redirect_uri; ?></code>
</p>
<p class="description">
- <strong><?php _e( 'Login Button Shortcode' ); ?></strong>
+ <strong><?php _e( 'Login Button Shortcode', 'daggerhart-openid-connect-generic' ); ?></strong>
<code>[openid_connect_generic_login_button]</code>
</p>
<p class="description">
- <strong><?php _e( 'Authentication URL Shortcode' ); ?></strong>
+ <strong><?php _e( 'Authentication URL Shortcode', 'daggerhart-openid-connect-generic' ); ?></strong>
<code>[openid_connect_generic_auth_url]</code>
</p>
<?php if ( $this->settings->enable_logging ) { ?>
- <h2><?php _e( 'Logs' ); ?></h2>
+ <h2><?php _e( 'Logs', 'daggerhart-openid-connect-generic' ); ?></h2>
<div id="logger-table-wrapper">
<?php print $this->logger->get_logs_table(); ?>
</div>
@@ -384,47 +462,56 @@ class OpenID_Connect_Generic_Settings_Page {
}
/**
- * Output a standard text field
+ * Output a standard text field.
+ *
+ * @param array $field The settings field definition array.
*
- * @param $field
+ * @return void
*/
public function do_text_field( $field ) {
?>
<input type="<?php print esc_attr( $field['type'] ); ?>"
- id="<?php print esc_attr( $field['key'] ); ?>"
- class="large-text"
- name="<?php print esc_attr( $field['name'] ); ?>"
- value="<?php print esc_attr( $this->settings->{ $field['key'] } ); ?>">
+ <?php echo ( ! empty( $field['disabled'] ) && boolval( $field['disabled'] ) ) ? ' disabled' : ''; ?>
+ id="<?php print esc_attr( $field['key'] ); ?>"
+ class="large-text<?php echo ( ! empty( $field['disabled'] ) && boolval( $field['disabled'] ) ) ? ' disabled' : ''; ?>"
+ name="<?php print esc_attr( $field['name'] ); ?>"
+ value="<?php print esc_attr( $this->settings->{ $field['key'] } ); ?>">
<?php
$this->do_field_description( $field );
}
/**
- * Output a checkbox for a boolean setting
- * - hidden field is default value so we don't have to check isset() on save
+ * Output a checkbox for a boolean setting.
+ * - hidden field is default value so we don't have to check isset() on save.
+ *
+ * @param array $field The settings field definition array.
*
- * @param $field
+ * @return void
*/
public function do_checkbox( $field ) {
?>
<input type="hidden" name="<?php print esc_attr( $field['name'] ); ?>" value="0">
<input type="checkbox"
- id="<?php print esc_attr( $field['key'] ); ?>"
- name="<?php print esc_attr( $field['name'] ); ?>"
- value="1"
+ id="<?php print esc_attr( $field['key'] ); ?>"
+ name="<?php print esc_attr( $field['name'] ); ?>"
+ value="1"
<?php checked( $this->settings->{ $field['key'] }, 1 ); ?>>
<?php
$this->do_field_description( $field );
}
/**
- * @param $field
+ * Output a select control.
+ *
+ * @param array $field The settings field definition array.
+ *
+ * @return void
*/
function do_select( $field ) {
$current_value = isset( $this->settings->{ $field['key'] } ) ? $this->settings->{ $field['key'] } : '';
?>
<select name="<?php print esc_attr( $field['name'] ); ?>">
- <?php foreach ( $field['options'] as $value => $text ): ?>
+ <?php foreach ( $field['options'] as $value => $text ) : ?>
<option value="<?php print esc_attr( $value ); ?>" <?php selected( $value, $current_value ); ?>><?php print esc_html( $text ); ?></option>
<?php endforeach; ?>
</select>
@@ -433,35 +520,57 @@ class OpenID_Connect_Generic_Settings_Page {
}
/**
- * Simply output the field description, and example if present
+ * Output the field description, and example if present.
+ *
+ * @param array $field The settings field definition array.
*
- * @param $field
+ * @return void
*/
public function do_field_description( $field ) {
?>
<p class="description">
<?php print $field['description']; ?>
<?php if ( isset( $field['example'] ) ) : ?>
- <br/><strong><?php _e( 'Example' ); ?>: </strong>
+ <br/><strong><?php _e( 'Example', 'daggerhart-openid-connect-generic' ); ?>: </strong>
<code><?php print $field['example']; ?></code>
<?php endif; ?>
</p>
<?php
}
+ /**
+ * Output the 'Client Settings' plugin setting section description.
+ *
+ * @return void
+ */
public function client_settings_description() {
- _e( 'Enter your OpenID Connect identity provider settings' );
+ _e( 'Enter your OpenID Connect identity provider settings.', 'daggerhart-openid-connect-generic' );
}
+ /**
+ * Output the 'WordPress User Settings' plugin setting section description.
+ *
+ * @return void
+ */
public function user_settings_description() {
- _e( 'Modify the interaction between OpenID Connect and WordPress users' );
+ _e( 'Modify the interaction between OpenID Connect and WordPress users.', 'daggerhart-openid-connect-generic' );
}
+ /**
+ * Output the 'Authorization Settings' plugin setting section description.
+ *
+ * @return void
+ */
public function authorization_settings_description() {
- _e( 'Control the authorization mechanics of the site' );
+ _e( 'Control the authorization mechanics of the site.', 'daggerhart-openid-connect-generic' );
}
+ /**
+ * Output the 'Log Settings' plugin setting section description.
+ *
+ * @return void
+ */
public function log_settings_description() {
- _e( 'Log information about login attempts through OpenID Connect Generic' );
+ _e( 'Log information about login attempts through OpenID Connect Generic.', 'daggerhart-openid-connect-generic' );
}
}
diff --git a/daggerhart-openid-connect-generic/openid-connect-generic.php b/daggerhart-openid-connect-generic/openid-connect-generic.php
index e755b8c..020fc88 100755..100644
--- a/daggerhart-openid-connect-generic/openid-connect-generic.php
+++ b/daggerhart-openid-connect-generic/openid-connect-generic.php
@@ -1,13 +1,30 @@
<?php
-/*
-Plugin Name: OpenID Connect Generic
-Plugin URI: https://github.com/daggerhart/openid-connect-generic
-Description: Connect to an OpenID Connect generic client using Authorization Code Flow
-Version: 3.6.0
-Author: daggerhart
-Author URI: http://www.daggerhart.com
-License: GPLv2 Copyright (c) 2015 daggerhart
-*/
+/**
+ * OpenID Connect Generic Client
+ *
+ * This plugin provides the ability to authenticate users with Identity
+ * Providers using the OpenID Connect OAuth2 API with Authorization Code Flow.
+ *
+ * @package OpenID_Connect_Generic
+ * @category General
+ * @author Jonathan Daggerhart <jonathan@daggerhart.com>
+ * @copyright 2015-2020 daggerhart
+ * @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
+ * @link https://github.com/daggerhart
+ *
+ * @wordpress-plugin
+ * Plugin Name: OpenID Connect Generic
+ * Plugin URI: https://github.com/daggerhart/openid-connect-generic
+ * Description: Connect to an OpenID Connect generic client using Authorization Code Flow, with fixes for WC integration.
+ * Version: 3.8.0-grothoff
+ * Author: daggerhart-grothoff
+ * Author URI: http://www.daggerhart.com
+ * Text Domain: daggerhart-openid-connect-generic
+ * Domain Path: /languages
+ * License: GPL-2.0+
+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
+ * GitHub Plugin URI: https://github.com/daggerhart/openid-connect-generic
+ */
/*
Notes
@@ -48,50 +65,80 @@ Notes
*/
+/**
+ * OpenID_Connect_Generic class.
+ *
+ * Defines plugin initialization functionality.
+ *
+ * @package OpenID_Connect_Generic
+ * @category General
+ */
class OpenID_Connect_Generic {
- // plugin version
- const VERSION = '3.6.0';
- // plugin settings
+ /**
+ * Plugin version.
+ *
+ * @var
+ */
+ const VERSION = '3.8.0';
+
+ /**
+ * Plugin settings.
+ *
+ * @var OpenID_Connect_Generic_Option_Settings
+ */
private $settings;
- // plugin logs
+ /**
+ * Plugin logs.
+ *
+ * @var OpenID_Connect_Generic_Option_Logger
+ */
private $logger;
- // openid connect generic client
+ /**
+ * Openid Connect Generic client
+ *
+ * @var OpenID_Connect_Generic_Client
+ */
private $client;
- // settings admin page
- private $settings_page;
-
- // login form adjustments
- private $login_form;
+ /**
+ * Client wrapper.
+ *
+ * @var OpenID_Connect_Generic_Client_Wrapper
+ */
+ private $client_wrapper;
/**
* Setup the plugin
*
- * @param OpenID_Connect_Generic_Option_Settings $settings
- * @param OpenID_Connect_Generic_Option_Logger $logger
+ * @param OpenID_Connect_Generic_Option_Settings $settings The settings object.
+ * @param OpenID_Connect_Generic_Option_Logger $logger The loggin object.
+ *
+ * @return void
*/
- function __construct( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ){
+ function __construct( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
$this->settings = $settings;
$this->logger = $logger;
}
/**
- * WP Hook 'init'
+ * WordPress Hook 'init'.
+ *
+ * @return void
*/
- function init(){
+ function init() {
$redirect_uri = admin_url( 'admin-ajax.php?action=openid-connect-authorize' );
- if ( $this->settings->alternate_redirect_uri ){
+ if ( $this->settings->alternate_redirect_uri ) {
$redirect_uri = site_url( '/openid-connect-authorize' );
}
$state_time_limit = 180;
- if ($this->settings->state_time_limit) {
- $state_time_limit = intval($this->settings->state_time_limit);
+ if ( $this->settings->state_time_limit ) {
+ $state_time_limit = intval( $this->settings->state_time_limit );
}
$this->client = new OpenID_Connect_Generic_Client(
@@ -111,57 +158,61 @@ class OpenID_Connect_Generic {
return;
}
- $this->login_form = OpenID_Connect_Generic_Login_Form::register( $this->settings, $this->client_wrapper );
+ OpenID_Connect_Generic_Login_Form::register( $this->settings, $this->client_wrapper );
- // add a shortcode to get the auth url
+ // Add a shortcode to get the auth URL.
add_shortcode( 'openid_connect_generic_auth_url', array( $this->client_wrapper, 'get_authentication_url' ) );
- // add actions to our scheduled cron jobs
- add_action( 'openid-connect-generic-cron-daily', [ $this, 'cron_states_garbage_collection'] );
+ // Add actions to our scheduled cron jobs.
+ add_action( 'openid-connect-generic-cron-daily', array( $this, 'cron_states_garbage_collection' ) );
$this->upgrade();
- if ( is_admin() ){
- $this->settings_page = OpenID_Connect_Generic_Settings_Page::register( $this->settings, $this->logger );
+ if ( is_admin() ) {
+ OpenID_Connect_Generic_Settings_Page::register( $this->settings, $this->logger );
}
}
/**
* Check if privacy enforcement is enabled, and redirect users that aren't
* logged in.
+ *
+ * @return void
*/
function enforce_privacy_redirect() {
if ( $this->settings->enforce_privacy && ! is_user_logged_in() ) {
- // our client endpoint relies on the wp admind ajax endpoint
- if ( ! defined( 'DOING_AJAX') || ! DOING_AJAX || ! isset( $_GET['action'] ) || $_GET['action'] != 'openid-connect-authorize' ) {
+ // The client endpoint relies on the wp admind ajax endpoint.
+ if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX || ! isset( $_GET['action'] ) || 'openid-connect-authorize' != $_GET['action'] ) {
auth_redirect();
}
}
}
/**
- * Enforce privacy settings for rss feeds
+ * Enforce privacy settings for rss feeds.
*
- * @param $content
+ * @param string $content The content.
*
* @return mixed
*/
- function enforce_privacy_feeds( $content ){
+ function enforce_privacy_feeds( $content ) {
if ( $this->settings->enforce_privacy && ! is_user_logged_in() ) {
- $content = 'Private site';
+ $content = __( 'Private site', 'daggerhart-openid-connect-generic' );
}
return $content;
}
/**
* Handle plugin upgrades
+ *
+ * @return void
*/
- function upgrade(){
+ function upgrade() {
$last_version = get_option( 'openid-connect-generic-plugin-version', 0 );
$settings = $this->settings;
if ( version_compare( self::VERSION, $last_version, '>' ) ) {
- // upgrade required
+ // An upgrade is required.
self::setup_cron_jobs();
// @todo move this to another file for upgrade scripts
@@ -174,7 +225,7 @@ class OpenID_Connect_Generic {
$settings->save();
}
- // update the stored version number
+ // Update the stored version number.
update_option( 'openid-connect-generic-plugin-version', self::VERSION );
}
}
@@ -182,21 +233,25 @@ class OpenID_Connect_Generic {
/**
* Expire state transients by attempting to access them and allowing the
* transient's own mechanisms to delete any that have expired.
+ *
+ * @return void
*/
function cron_states_garbage_collection() {
global $wpdb;
$states = $wpdb->get_col( "SELECT `option_name` FROM {$wpdb->options} WHERE `option_name` LIKE '_transient_openid-connect-generic-state--%'" );
- if ( !empty( $states ) ) {
+ if ( ! empty( $states ) ) {
foreach ( $states as $state ) {
- $transient = str_replace("_transient_", "", $state);
- get_transient( $transient );
+ $transient = str_replace( '_transient_', '', $state );
+ get_transient( $transient );
}
}
}
/**
* Ensure cron jobs are added to the schedule.
+ *
+ * @return void
*/
static public function setup_cron_jobs() {
if ( ! wp_next_scheduled( 'openid-connect-generic-cron-daily' ) ) {
@@ -206,6 +261,8 @@ class OpenID_Connect_Generic {
/**
* Activation hook.
+ *
+ * @return void
*/
static public function activation() {
self::setup_cron_jobs();
@@ -213,31 +270,34 @@ class OpenID_Connect_Generic {
/**
* Deactivation hook.
+ *
+ * @return void
*/
static public function deactivation() {
wp_clear_scheduled_hook( 'openid-connect-generic-cron-daily' );
}
/**
- * Simple autoloader
+ * Simple autoloader.
*
- * @param $class
+ * @param string $class The class name.
+ *
+ * @return void
*/
static public function autoload( $class ) {
$prefix = 'OpenID_Connect_Generic_';
- if ( stripos($class, $prefix) !== 0 ) {
+ if ( stripos( $class, $prefix ) !== 0 ) {
return;
}
$filename = $class . '.php';
- // internal files are all lowercase and use dashes in filenames
+ // Internal files are all lowercase and use dashes in filenames.
if ( false === strpos( $filename, '\\' ) ) {
$filename = strtolower( str_replace( '_', '-', $filename ) );
- }
- else {
- $filename = str_replace('\\', DIRECTORY_SEPARATOR, $filename);
+ } else {
+ $filename = str_replace( '\\', DIRECTORY_SEPARATOR, $filename );
}
$filepath = dirname( __FILE__ ) . '/includes/' . $filename;
@@ -248,26 +308,33 @@ class OpenID_Connect_Generic {
}
/**
- * Instantiate the plugin and hook into WP
+ * Instantiate the plugin and hook into WordPress.
+ *
+ * @return void
*/
- static public function bootstrap(){
+ static public function bootstrap() {
+ /**
+ * This is a documented valid call for spl_autoload_register.
+ *
+ * @link https://www.php.net/manual/en/function.spl-autoload-register.php#71155
+ */
spl_autoload_register( array( 'OpenID_Connect_Generic', 'autoload' ) );
$settings = new OpenID_Connect_Generic_Option_Settings(
'openid_connect_generic_settings',
- // default settings values
+ // Default settings values.
array(
- // oauth client settings
- 'login_type' => 'button',
- 'client_id' => '',
- 'client_secret' => '',
- 'scope' => '',
- 'endpoint_login' => '',
- 'endpoint_userinfo' => '',
- 'endpoint_token' => '',
- 'endpoint_end_session' => '',
-
- // non-standard settings
+ // OAuth client settings.
+ 'login_type' => 'button',
+ 'client_id' => defined( 'OIDC_CLIENT_ID' ) ? OIDC_CLIENT_ID : '',
+ 'client_secret' => defined( 'OIDC_CLIENT_SECRET' ) ? OIDC_CLIENT_SECRET : '',
+ 'scope' => '',
+ 'endpoint_login' => defined( 'OIDC_ENDPOINT_LOGIN_URL' ) ? OIDC_ENDPOINT_LOGIN_URL : '',
+ 'endpoint_userinfo' => defined( 'OIDC_ENDPOINT_USERINFO_URL' ) ? OIDC_ENDPOINT_USERINFO_URL : '',
+ 'endpoint_token' => defined( 'OIDC_ENDPOINT_TOKEN_URL' ) ? OIDC_ENDPOINT_TOKEN_URL : '',
+ 'endpoint_end_session' => defined( 'OIDC_ENDPOINT_LOGOUT_URL' ) ? OIDC_ENDPOINT_LOGOUT_URL : '',
+
+ // Non-standard settings.
'no_sslverify' => 0,
'http_request_timeout' => 5,
'identity_key' => 'preferred_username',
@@ -276,9 +343,10 @@ class OpenID_Connect_Generic {
'displayname_format' => '',
'identify_with_username' => false,
- // plugin settings
+ // Plugin settings.
'enforce_privacy' => 0,
'alternate_redirect_uri' => 0,
+ 'token_refresh_enable' => 1,
'link_existing_users' => 0,
'create_if_does_not_exist' => 1,
'redirect_user_back' => 0,
@@ -294,15 +362,15 @@ class OpenID_Connect_Generic {
add_action( 'init', array( $plugin, 'init' ) );
- // privacy hooks
+ // Privacy hooks.
add_action( 'template_redirect', array( $plugin, 'enforce_privacy_redirect' ), 0 );
add_filter( 'the_content_feed', array( $plugin, 'enforce_privacy_feeds' ), 999 );
- add_filter( 'the_excerpt_rss', array( $plugin, 'enforce_privacy_feeds' ), 999 );
+ add_filter( 'the_excerpt_rss', array( $plugin, 'enforce_privacy_feeds' ), 999 );
add_filter( 'comment_text_rss', array( $plugin, 'enforce_privacy_feeds' ), 999 );
}
}
OpenID_Connect_Generic::bootstrap();
-register_activation_hook( __FILE__, [ 'OpenID_Connect_Generic', 'activation' ] );
-register_deactivation_hook( __FILE__, [ 'OpenID_Connect_Generic', 'deactivation' ] );
+register_activation_hook( __FILE__, array( 'OpenID_Connect_Generic', 'activation' ) );
+register_deactivation_hook( __FILE__, array( 'OpenID_Connect_Generic', 'deactivation' ) );
diff --git a/daggerhart-openid-connect-generic/readme.md b/daggerhart-openid-connect-generic/readme.md
index 5bf8c0c..5575267 100755..100644
--- a/daggerhart-openid-connect-generic/readme.md
+++ b/daggerhart-openid-connect-generic/readme.md
@@ -21,6 +21,7 @@ Much of the documentation can be found on the Settings > OpenID Connect Generic
- [Frequently Asked Questions](#frequently-asked-questions)
- [What is the client's Redirect URI?](#what-is-the-clients-redirect-uri)
- [Can I change the client's Redirect URI?](#can-i-change-the-clients-redirect-uri)
+- [Configuration Environment Variables/Constants](#configuration-environment-variables-constants)
- [Hooks](#hooks)
- [Filters](#filters)
- [openid-connect-generic-alter-request](#openid-connect-generic-alter-request)
@@ -36,6 +37,7 @@ Much of the documentation can be found on the Settings > OpenID Connect Generic
- [openid-connect-generic-user-update](#openid-connect-generic-user-update)
- [openid-connect-generic-update-user-using-current-claim](#openid-connect-generic-update-user-using-current-claim)
- [openid-connect-generic-redirect-user-back](#openid-connect-generic-redirect-user-back)
+ - [openid-connect-generic-register-login-form](#openid-connect-generic-register-login-form)
## Installation
@@ -73,6 +75,15 @@ On the settings page for this plugin (Dashboard > Settings > OpenID Connect Gene
**Alternate Redirect URI**. When checked, the plugin will use the Redirect URI
`https://example.com/openid-connect-authorize`.
+## Configuration Environment Variables/Constants
+
+- Client ID: `OIDC_CLIENT_ID`
+- Client Secret Key: `OIDC_CLIENT_SECRET`
+- Login Endpoint URL: `OIDC_ENDPOINT_LOGIN_URL`
+- Userinfo Endpoint URL: `OIDC_ENDPOINT_USERINFO_URL`
+- Token Validation Endpoint URL: `OIDC_ENDPOINT_TOKEN_URL`
+- End Session Endpoint URL: `OIDC_ENDPOINT_LOGOUT_URL`
+
## Hooks
This plugin provides a number of hooks to allow for a significant amount of customization of the plugin operations from
@@ -356,6 +367,38 @@ add_action('openid-connect-generic-redirect-user-back', function( $redirect_url,
}, 10, 2);
```
+
+#### `openid-connect-generic-register-login-form`
+
+Allow user to add the login form to various pages, such as WooCommerce's checkout page. It will fire
+whenever the plugin is loaded and pass the login form to the callback.
+
+Provides 1 argument: the login form instance.
+
+```
+add_action ('openid-connect-generic-register-login-form',
+ function ( $login_form ) {
+
+ // show login form at the shopping cart (if not logged in)
+ add_action( 'woocommerce_before_checkout_billing_form',
+ function () use ( $login_form ) {
+ $user = wp_get_current_user ();
+ if (0 == $user->ID) {
+ // ID 0 is used to indicate user is not logged in.
+ // Re-use filter logic to generate login page
+ print ( $login_form->handle_login_page ('') );
+ }
+ });
+
+ // Add action to set cookie to redirect back to current
+ // (checkout) page after OIDC provided the data
+ add_action( 'woocommerce_before_checkout_billing_form',
+ array( $login_form, 'handle_redirect_cookie' ) );
+
+ }
+);
+```
+
### User Meta Data
This plugin stores meta data about the user for both practical and debugging purposes.
diff --git a/daggerhart-openid-connect-generic/readme.txt b/daggerhart-openid-connect-generic/readme.txt
index 93da2f8..39da427 100755..100644
--- a/daggerhart-openid-connect-generic/readme.txt
+++ b/daggerhart-openid-connect-generic/readme.txt
@@ -1,10 +1,11 @@
=== OpenID Connect Generic Client ===
-Contributors: daggerhart
+Contributors: daggerhart, tnolte
Donate link: http://www.daggerhart.com/
-Tags: security, login, oauth2, openidconnect, apps, authentication, autologin, sso
-Requires at least: 4
-Tested up to: 5.2.2
-Stable tag: trunk
+Tags: security, login, oauth2, openidconnect, apps, authentication, autologin, sso
+Requires at least: 4.9
+Tested up to: 5.4.2
+Stable tag: 3.8.0
+Requires PHP: 5.6
License: GPLv2 or later
License URI: http://www.gnu.org/licenses/gpl-2.0.html
@@ -14,7 +15,7 @@ A simple client that provides SSO or opt-in authentication against a generic OAu
This plugin allows to authenticate users against OpenID Connect OAuth2 API with Authorization Code Flow.
Once installed, it can be configured to automatically authenticate users (SSO), or provide a "Login with OpenID Connect"
-button on the login form. After consent has been obtained, an existing user is automatically logged into WordPress, while
+button on the login form. After consent has been obtained, an existing user is automatically logged into WordPress, while
new users are created in WordPress database.
Much of the documentation can be found on the Settings > OpenID Connect Generic dashboard page.
@@ -50,6 +51,23 @@ On the settings page for this plugin (Dashboard > Settings > OpenID Connect Gene
== Changelog ==
+= 3.8.0 =
+
+* Feature: @timnolte - Ability to use 6 new constants for setting client configuration instead of storing in the DB.
+* Improvement: @timnolte - Plugin development & contribution updates.
+* Improvement: @timnolte - Refactored to meet WordPress coding standards.
+* Improvement: @timnolte - Refactored to provide localization.
+
+= 3.7.1 =
+
+* Fix: Release Version Number.
+
+= 3.7.0 =
+
+* Feature: @timnolte - Ability to enable/disable token refresh. Useful for IDPs that don't support token refresh.
+* Feature: @timnolte - Support custom redirect URL(`redirect_to`) with the authentication URL & login button shortcodes.
+ - Supports additional attribute overrides including login `button_text`, `endpoint_login`, `scope`, `redirect_uri`.
+
= 3.6.0 =
* Improvement: @RobjS - Improved error messages during login state failure.
@@ -108,7 +126,7 @@ On the settings page for this plugin (Dashboard > Settings > OpenID Connect Gene
= 3.1.0 =
-* Feature: @rwasef1830 - Refresh tokens
+* Feature: @rwasef1830 - Refresh tokens
* Feature: @rwasef1830 - Integrated logout support with end_session endpoint
* Feature: May use an alternate redirect_uri that doesn't rely on admin-ajax
* Feature: @ahatherly - Support for IDP behind reverse proxy
@@ -125,8 +143,8 @@ On the settings page for this plugin (Dashboard > Settings > OpenID Connect Gene
= 3.0.7 =
-* Bug fix: @wgengarelly - When requesting userinfo, send the access token using the Authorization header field as recommended in
-section 5.3.1 of the specs.
+* Bug fix: @wgengarelly - When requesting userinfo, send the access token using the Authorization header field as recommended in
+section 5.3.1 of the specs.
= 3.0.6 =
diff --git a/server-build/my-simple-cdd/README b/server-build/my-simple-cdd/README
index 2cc2043..7749add 100644
--- a/server-build/my-simple-cdd/README
+++ b/server-build/my-simple-cdd/README
@@ -43,7 +43,10 @@ Finally, boot the final image using:
$ ./run-system.sh
-The root password will be set to "wootaler" initially.
+The 'root' password will be set to 'wootaler' initially.
+
+The 'admin' password for WooCommerce (running on port 9999)
+will be 'admin-pass'.
Upon first boot, you need to wait for a bit for the systemd
service firstboot-wootaler.service to complete. You may