Initial Coding Standards & Static Analysis Chanages.

* Adds WordPress coding standards configuration.
* Adds WordPress/PHP static analysis configuration.
* Adds Git hooks to enforce checks and ensure quality on commits.
* Adds initial local Docker development environment setup.
isekai
Tim Nolte 4 years ago
parent bfa31bf983
commit 79f45e7f89
No known key found for this signature in database
GPG Key ID: 33E7CA1AD448F3B3

@ -0,0 +1,24 @@
# This file is for unifying the coding style for different editors and IDEs
# editorconfig.org
# WordPress Coding Standards
# https://make.wordpress.org/core/handbook/coding-standards/
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
trim_trailing_whitespace = true
indent_style = tab
[*.yml,*.yml.dist]
indent_style = space
indent_size = 2
[*.md]
trim_trailing_whitespace = false
[{*.txt,wp-config-sample.php}]
end_of_line = crlf

54
.gitignore vendored

@ -1,2 +1,52 @@
vendor/**/*
composer.lock
# Numerous always-ignore extensions
*.diff
*.err
*.orig
*.log
*.rej
*.swo
*.swp
*.vi
*~
*.sass-cache
# Local Development files/folders.
.env
phpcs.xml
phpstan.neon
phpunit.xml
# OS or Editor folders
.DS_Store
Thumbs.db
.cache
tags.*
.project
.settings
.tmproj
*.esproj
nbproject
*.sublime-project
*.sublime-workspace
.idea
clover.xml
# Dreamweaver added files
_notes
dwsync.xml
# Komodo
*.komodoproject
.komodotools
# Folders to ignore
.hg
.svn
.CVS
intermediate
.idea
cache
node_modules
vendor
dist
wordpress

@ -0,0 +1,118 @@
# Travis CI Configuration File
# Tell Travis CI which distro to use
dist: trusty
sudo: false
# Tell Travis CI we're using PHP
language: php
# Tell Travis CI which notifications to send
notifications:
email:
on_success: never
on_failure: change
# whitelist branches for the "push" build check
branches:
only:
- main
- /^dev\-release\/.*$/
- /^feature\/.*$/
- /^fix\/.*$/
# Git clone depth
# By default Travis CI clones repositories to a depth of 50 commits
git:
depth: 1
cache:
directories:
- vendor
- $HOME/.composer/cache
# Define a matrix of additional build configurations
# The versions listed above will automatically create our first configuration,
# so it doesn't need to be re-defined below.
matrix:
fast_finish: true
include:
- name: Coding Standards
php: 7.3
env: WP_MODE=single WP_VERSION=5.4.* PHP_LINT=1 COVERAGE=1
- name: Static Code Analysis
php: 7.3
env: WP_MODE=single WP_VERSION=5.4.* PHP_ANALYZE=1
- name: Latest Stable
php: 7.3
env: WP_MODE=single WP_VERSION=5.4.* PHP_UNIT=1
- name: Preferred Minimum requirements
php: 7.2
env: WP_MODE=single WP_VERSION=5.3.* PHP_UNIT=1
- name: Minimum requirements
php: 7.1
env: WP_MODE=single WP_VERSION=5.2.* PHP_UNIT=1
- name: Bleeding Edge
php: 7.4
env: WP_MODE=single WP_VERSION=dev-master PHP_UNIT=1
- name: Multisite Compatibility
php: 7.3
env: WP_MODE=multi WP_VERSION=5.4.* PHP_UNIT=1
allow_failures:
- name: Bleeding Edge
addons:
apt:
packages:
- nodejs
before_install:
- npm install -g npm@6.14
- npm install -g grunt-cli
- composer require "wordpress/wordpress:${WP_VERSION}" --dev --prefer-source --no-update
install:
- composer update --prefer-source --no-interaction --dev
- npm install
before_script:
- export PATH="$HOME/.composer/vendor/bin:$PATH"
# Setup WordPress coding standards
- |
if [[ "$PHP_LINT" == "1" ]]; then
composer global require wp-coding-standards/wpcs
fi
# Setup unit testing environment
- |
if [[ "$PHP_UNIT" == "1" ]]; then
# bash scripts/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
if [[ $TRAVIS_PHP_VERSION == "7.4" ]]; then
composer global require "phpunit/php-code-coverage=dev-master"
composer global require "sebastian/global-state:dev-master"
composer global require "phpunit/phpunit=dev-master"
else
composer global require "phpunit/phpunit=7.*"
fi
fi
script:
- |
if [[ "$PHP_LINT" == "1" ]]; then
if [[ "$WP_MODE" == "single" ]]; then WP_MULTISITE=0 npm run lint; fi
fi
- |
if [[ "$PHP_ANALYZE" == "1" ]]; then
if [[ "$WP_MODE" == "single" ]]; then WP_MULTISITE=0 npm run analyze; fi
fi
- |
if [[ "$PHP_UNIT" == "1" ]]; then
if [[ "$WP_MODE" == "multi" ]]; then WP_MULTISITE=1 npm run test; fi
if [[ "$WP_MODE" == "single" ]]; then WP_MULTISITE=0 npm run test; fi
fi
after_success:
- |
if [[ "$COVERAGE" == "1" ]]; then
bash <(curl -s https://codecov.io/bash)
fi

@ -0,0 +1,17 @@
{
"core": "./wordpress/build",
"mappings": {
"wp-content/mu-plugins": "./tools/local-env/mu-plugins",
"wp-content/plugins/daggerhart-openid-connect-generic": "."
},
"config": {
"PHP_INI_MEMORY_LIMIT": "512M",
"WP_MEMORY_LIMIT": "512M",
"WP_DEBUG": true,
"WP_DEBUG_LOG": true,
"WP_DEBUG_DISPLAY": true,
"SCRIPT_DEBUG": true,
"SMTP_HOST": "mailhog",
"SMTP_PORT": 1025
}
}

@ -0,0 +1,200 @@
module.exports = function (grunt) {
require('load-grunt-tasks')(grunt);
// Project configuration.
grunt.initConfig({
pkg: grunt.file.readJSON('package.json'),
composerBin: 'vendor/bin',
shell: {
phpcs: {
options: {
stdout: true
},
command: '<%= composerBin %>/phpcs'
},
phpcbf: {
options: {
stdout: true
},
command: '<%= composerBin %>/phpcbf'
},
phpstan: {
options: {
stdout: true
},
command: '<%= composerBin %>/phpstan analyze .'
},
phpunit: {
options: {
stdout: true
},
command: '<%= composerBin %>/phpunit'
},
},
gitinfo: {
commands: {
'local.tag.current.name': ['name-rev', '--tags', '--name-only', 'HEAD'],
'local.tag.current.nameLong': ['describe', '--tags', '--long']
}
},
clean: {
main: ['dist'], //Clean up build folder
i18n: ['languages/*.mo', 'languages/*.pot']
},
copy: {
// Copy the plugin to a versioned release directory
main: {
src: [
'**',
'!*.xml', '!*.log', //any config/log files
'!node_modules/**', '!Gruntfile.js', '!package.json', '!package-lock.json', //npm/Grunt
'!assets/**', //wp-org assets
'!dist/**', //build directory
'!.git/**', //version control
'!tests/**', '!scripts/**', '!phpunit.xml', '!phpunit.xml.dist', //unit testing
'!vendor/**', '!composer.lock', '!composer.phar', '!composer.json', //composer
'!wordpress/**',
'!.*', '!**/*~', //hidden files
'!CONTRIBUTING.md',
'!README.md',
'!phpcs.xml', '!phpcs.xml.dist', '!phpstan.neon.dist', '!grumphp.yml.dist', // CodeSniffer Configuration.
'!docker-compose.override.yml', // Local Docker Development configuration.
'!codecov.yml', // Code coverage configuration.
'!tools/**', // Local Development/Build tools configuration.
],
dest: 'dist/',
options: {
processContentExclude: ['**/*.{png,gif,jpg,ico,mo}'],
processContent: function (content, srcpath) {
if (srcpath == 'readme.txt' || srcpath == 'openid-connect-generic.php') {
if (grunt.config.get('gitinfo').local.tag.current.name !== 'undefined') {
content = content.replace('{{version}}', grunt.config.get('gitinfo').local.tag.current.name);
} else {
content = content.replace('{{version}}', grunt.config.get('gitinfo').local.tag.current.nameLong);
}
}
return content;
},
},
}
},
addtextdomain: {
options: {
textdomain: 'daggerhart-openid-connect-generic', // Project text domain.
},
update_all_domains: {
options: {
updateDomains: true
},
src: ['*.php', '**/*.php', '!node_modules/**', '!tests/**', '!scripts/**', '!wordpress/**']
},
},
wp_readme_to_markdown: {
dest: {
files: {
'README.md': 'readme.txt'
}
},
},
makepot: {
target: {
options: {
domainPath: '/languages', // Where to save the POT file.
exclude: [
'node_modules/.*', //npm
'assets/.*', //wp-org assets
'dist/.*', //build directory
'.git/.*', //version control
'tests/.*', 'scripts/.*', //unit testing
'vendor/.*', //composer
'wordpress/.*',
], // List of files or directories to ignore.
mainFile: 'openid-connect-generic.php', // Main project file.
potFilename: 'openid-connect-generic.pot', // Name of the POT file.
potHeaders: {
poedit: true, // Includes common Poedit headers.
'x-poedit-keywordslist': true // Include a list of all possible gettext functions.
}, // Headers to add to the generated POT file.
type: 'wp-plugin', // Type of project (wp-plugin or wp-theme).
updateTimestamp: true, // Whether the POT-Creation-Date should be updated without other changes.
updatePoFiles: true // Whether to update PO files in the same directory as the POT file.
}
}
},
po2mo: {
plugin: {
src: 'languages/*.po',
expand: true
}
},
checkrepo: {
deploy: {
tagged: true, // Check that the last commit (HEAD) is tagged
clean: true // Check that working directory is clean
}
},
checktextdomain: {
options: {
text_domain: 'daggerhart-openid-connect-generic',
keywords: [
'__:1,2d',
'_e:1,2d',
'_x:1,2c,3d',
'esc_html__:1,2d',
'esc_html_e:1,2d',
'esc_html_x:1,2c,3d',
'esc_attr__:1,2d',
'esc_attr_e:1,2d',
'esc_attr_x:1,2c,3d',
'_ex:1,2c,3d',
'_x:1,2c,3d',
'_n:1,2,4d',
'_nx:1,2,4c,5d',
'_n_noop:1,2,3d',
'_nx_noop:1,2,3c,4d'
],
},
files: {
src: [
'**/*.php',
'!node_modules/**',
'!dist/**',
'!tests/**',
'!vendor/**',
'!wordpress/**',
'!*~',
],
expand: true,
},
},
});
grunt.registerTask('phpcs', ['shell:phpcs']);
grunt.registerTask('phpcbf', ['shell:phpcbf']);
grunt.registerTask('phpstan', ['shell:phpstan']);
grunt.registerTask('phpunit', ['shell:phpunit']);
grunt.registerTask('i18n', ['addtextdomain', 'makepot', 'po2mo']);
grunt.registerTask('readme', ['wp_readme_to_markdown']);
grunt.registerTask('test', ['checktextdomain', 'phpcs']);
grunt.registerTask('build', ['gitinfo', 'test', 'clean', 'i18n', 'readme', 'copy']);
//grunt.registerTask( 'deploy', [ 'checkbranch:master', 'checkrepo', 'build' ] );
grunt.registerTask('deploy', ['checkrepo', 'build']);
};

@ -23,8 +23,79 @@
"support": {
"issues": "https://github.com/daggerhart/openid-connect-generic/issues"
},
"config": {
"platform": {
"php": "7.1"
},
"optimize-autoloader": true
},
"repositories": [
{
"type": "git",
"url": "https://github.com/wordpress/wordpress-develop"
}
],
"require": {
"php": ">=5.6.0",
"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.0",
"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": "*",
"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.16.2",
"sensiolabs/security-checker": "^5.0",
"phpstan/phpstan-deprecation-rules": "^0.12.4"
},
"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
}
}

4214
composer.lock generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,75 @@
version: '3.7'
services:
wordpress-develop:
depends_on:
- php
- mailhog
environment:
LOCAL_DIR: ${LOCAL_DIR-src}
SMTP_HOST: ${SMTP_HOST-mailhog}
SMTP_PORT: ${SMTP_PORT-1025}
volumes:
- ../tools/local-env/default.template:/etc/nginx/conf.d/default.template
- ..:/var/www/${LOCAL_DIR-src}/wp-content/plugins/daggerhart-openid-connect-generic
- ../tools/local-env/mu-plugins:/var/www/${LOCAL_DIR-src}/wp-content/mu-plugins
# Load our config file, substituning environment variables into the config.
command: /bin/sh -c "envsubst '$$LOCAL_DIR $$LOCAL_HOSTNAME' < /etc/nginx/conf.d/default.template > /etc/nginx/conf.d/default.conf && exec nginx -g 'daemon off;'"
php:
environment:
LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false}
LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false}
PHP_FPM_UID: ${PHP_FPM_UID-1000}
PHP_FPM_GID: ${PHP_FPM_GID-1000}
SMTP_HOST: ${SMTP_HOST-mailhog}
SMTP_PORT: ${SMTP_PORT-1025}
volumes:
- ..:/var/www/${LOCAL_DIR-src}/wp-content/plugins/daggerhart-openid-connect-generic/
- ../tools/local-env/mu-plugins:/var/www/${LOCAL_DIR-src}/wp-content/mu-plugins
cli:
environment:
LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false}
LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false}
PHP_FPM_UID: ${PHP_FPM_UID-1000}
PHP_FPM_GID: ${PHP_FPM_GID-1000}
SMTP_HOST: ${SMTP_HOST-mailhog}
SMTP_PORT: ${SMTP_PORT-1025}
volumes:
- ..:/var/www/${LOCAL_DIR-src}/wp-content/plugins/daggerhart-openid-connect-generic/
- ../tools/local-env/mu-plugins:/var/www/${LOCAL_DIR-src}/wp-content/mu-plugins
phpunit:
environment:
LOCAL_PHP_XDEBUG: ${LOCAL_PHP_XDEBUG-false}
LOCAL_PHP_MEMCACHED: ${LOCAL_PHP_MEMCACHED-false}
LOCAL_DIR: ${LOCAL_DIR-src}
WP_MULTISITE: ${WP_MULTISITE-false}
PHP_FPM_UID: ${PHP_FPM_UID-1000}
PHP_FPM_GID: ${PHP_FPM_GID-1000}
TRAVIS_BRANCH: ${TRAVIS_BRANCH-false}
TRAVIS_PULL_REQUEST: ${TRAVIS_PULL_REQUEST-false}
SMTP_HOST: ${SMTP_HOST-mailhog}
SMTP_PORT: ${SMTP_PORT-1025}
volumes:
- ..:/var/www/${LOCAL_DIR-src}/wp-content/plugins/daggerhart-openid-connect-generic/
- ../tools/local-env/mu-plugins:/var/www/${LOCAL_DIR-src}/wp-content/mu-plugins
## SMTP Server + Web Interface for viewing and testing emails during development.
mailhog:
image: mailhog/mailhog
restart: always
networks:
- wpdevnet
ports:
- "${MAILHOG_PORT:-8025}:8025"
- "${SMTP_PORT:-1025}:1025"

@ -0,0 +1,38 @@
# grumphp.yml
parameters:
git_dir: .
bin_dir: 'vendor/bin'
stop_on_failure: true
process_timeout: 120
parallel:
enabled: true
max_workers: 32
fixer:
enabled: false
fix_by_default: false
tasks:
git_blacklist:
keywords:
- 'wp_die('
- 'die('
git_branch_name:
blacklist:
- 'main'
- 'master'
- 'dev*'
allow_detached_head: false
git_commit_message:
allow_empty_message: false
enforce_capitalized_subject: true
phpcs:
standard: './phpcs.xml.dist'
report: 'summary'
ignore_patterns:
- '/^assets\/(.*)/'
phpstan:
configuration: './phpstan.neon.dist'
level: max
ignore_patterns:
- '/^assets\/(.*)/'
memory_limit: '-1'
securitychecker: ~

@ -22,11 +22,11 @@ class OpenID_Connect_Generic_Client_Wrapper {
/**
* Inject necessary objects and services into the client
*
* @param \OpenID_Connect_Generic_Client $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_Option_Logger $logger
*/
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;
@ -35,13 +35,13 @@ class OpenID_Connect_Generic_Client_Wrapper {
/**
* Hook the client into WP
*
* @param \OpenID_Connect_Generic_Client $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_Option_Logger $logger
*
* @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
@ -60,7 +60,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
add_action( 'wp_ajax_nopriv_openid-connect-authorize', array( $client_wrapper, 'authentication_request_callback' ) );
}
if ( $settings->alternate_redirect_uri ){
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' );
@ -69,7 +69,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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;
@ -82,10 +82,9 @@ class OpenID_Connect_Generic_Client_Wrapper {
*
* @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' )
{
$query->query_vars['openid-connect-authorize'] === '1' ) {
$this->authentication_request_callback();
exit;
}
@ -95,12 +94,12 @@ class OpenID_Connect_Generic_Client_Wrapper {
/**
* Get the authentication url from the client
*
*
* @param array $atts The optional attributes array when called via a shortcode.
*
* @return string
*/
function get_authentication_url( $atts = array() ){
function get_authentication_url( $atts = array() ) {
if ( ! empty( $atts['redirect_to'] ) ) {
// Set the request query parameter used to set the cookie redirect.
@ -108,7 +107,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
$login_form = new OpenID_Connect_Generic_Login_Form( $this->settings, $this );
$login_form->handle_redirect_cookie();
}
return $this->client->make_authentication_url( $atts );
}
@ -131,17 +130,17 @@ class OpenID_Connect_Generic_Client_Wrapper {
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();
@ -183,7 +182,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
wp_redirect(
wp_login_url() .
'?login-error=' . $error->get_error_code() .
'&message=' . urlencode( $error->get_error_message() )
'&message=' . urlencode( $error->get_error_message() )
);
exit;
}
@ -193,7 +192,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
*
* @return bool | WP_Error
*/
function get_error(){
function get_error() {
return $this->error;
}
@ -231,12 +230,11 @@ class OpenID_Connect_Generic_Client_Wrapper {
$redirect_url = '';
}
$token_response = $user->get('openid-connect-generic-last-token-response');
if (! $token_response ) {
$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 ) ) {
} 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 );
}
@ -244,15 +242,15 @@ class OpenID_Connect_Generic_Client_Wrapper {
$claim = $user->get( 'openid-connect-generic-last-id-token-claim' );
if ( isset( $claim['iss'] ) && $claim['iss'] == 'https://accounts.google.com' ) {
/* Google revoke endpoint
/*
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 ) );
}
}
@ -266,7 +264,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
* @return mixed
*/
function alter_request( $request, $op ) {
if ( !empty( $this->settings->http_request_timeout ) && is_numeric( $this->settings->http_request_timeout ) ) {
if ( ! empty( $this->settings->http_request_timeout ) && is_numeric( $this->settings->http_request_timeout ) ) {
$request['timeout'] = intval( $this->settings->http_request_timeout );
}
@ -287,14 +285,14 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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
$code = $client->get_authentication_code( $authentication_request );
if ( is_wp_error( $code ) ){
if ( is_wp_error( $code ) ) {
$this->error_redirect( $code );
}
@ -311,7 +309,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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 );
}
@ -335,32 +333,32 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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
$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 ( ! 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
$valid = $client->validate_user_claim( $user_claim, $id_token_claim );
if ( is_wp_error( $valid ) ){
if ( is_wp_error( $valid ) ) {
$this->error_redirect( $valid );
}
@ -378,12 +376,10 @@ 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 link to an existing WordPress user' ), $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 {
} 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 );
}
@ -391,12 +387,12 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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 );
$this->login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity );
do_action( 'openid-connect-generic-user-logged-in', $user );
@ -406,7 +402,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
// 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 );
@ -426,7 +422,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
*
* @return true|\WP_Error
*/
function validate_user( $user ){
function validate_user( $user ) {
// ensure our found user is a real WP_User
if ( ! is_a( $user, 'WP_User' ) || ! $user->exists() ) {
return new WP_Error( 'invalid-user', __( 'Invalid user' ), $user );
@ -440,7 +436,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
*
* @param $user
*/
function login_user( $user, $token_response, $id_token_claim, $user_claim, $subject_identity ){
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
update_user_meta( $user->ID, 'openid-connect-generic-last-token-response', $token_response );
@ -456,7 +452,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
$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 );
}
@ -471,22 +467,22 @@ class OpenID_Connect_Generic_Client_Wrapper {
if ( ! $this->settings->token_refresh_enable ) {
return;
}
$session = $manager->get($token);
$now = current_time( 'timestamp' , true );
$session[$this->cookie_token_refresh_key] = array(
$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) {
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;
}
@ -497,16 +493,18 @@ class OpenID_Connect_Generic_Client_Wrapper {
*
* @return false|\WP_User
*/
function get_user_by_identity( $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,
)
$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 ( $user_query->get_total() > 0 ) {
@ -526,26 +524,22 @@ class OpenID_Connect_Generic_Client_Wrapper {
*/
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'] ) ) {
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 {
} else {
// nothing to build a name from
return new WP_Error( 'no-username', __( 'No appropriate username found' ), $user_claim );
}
// normalize the data a bit
$transliterated_username = iconv( 'UTF-8', 'ASCII//TRANSLIT', $desired_username );
$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 );
}
@ -581,8 +575,8 @@ class OpenID_Connect_Generic_Client_Wrapper {
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 ];
if ( ! empty( $this->settings->nickname_key ) && isset( $user_claim[ $this->settings->nickname_key ] ) ) {
$desired_nickname = $user_claim[ $this->settings->nickname_key ];
}
return $desired_nickname;
}
@ -600,21 +594,26 @@ class OpenID_Connect_Generic_Client_Wrapper {
$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' ),
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 );
@ -686,7 +685,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
$_nickname = $this->get_nickname_from_claim( $user_claim );
if ( is_wp_error( $_nickname ) ) {
$values_missing = true;
} else if ( $_nickname !== null) {
} else if ( $_nickname !== null ) {
$nickname = $_nickname;
}
@ -698,7 +697,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
// attempt another request for userinfo if some values are missing
if ( $values_missing && isset( $token_response['access_token'] ) && !empty( $this->settings->endpoint_userinfo) ) {
if ( $values_missing && isset( $token_response['access_token'] ) && ! empty( $this->settings->endpoint_userinfo ) ) {
$user_claim_result = $this->client->request_userinfo( $token_response['access_token'] );
// make sure we didn't get an error
@ -726,7 +725,7 @@ class OpenID_Connect_Generic_Client_Wrapper {
$_nickname = $this->get_nickname_from_claim( $user_claim );
if ( is_wp_error( $_nickname ) ) {
return $_nickname;
} else if ( $_nickname === null) {
} else if ( $_nickname === null ) {
$nickname = $username;
}
@ -738,8 +737,8 @@ class OpenID_Connect_Generic_Client_Wrapper {
}
// 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) {
if ( $this->settings->link_existing_users ) {
if ( $this->settings->identify_with_username ) {
$uid = username_exists( $username );
} else {
$uid = email_exists( $email );
@ -765,8 +764,8 @@ 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 );

@ -30,7 +30,7 @@ class OpenID_Connect_Generic_Client {
* @param $redirect_uri
* @param $state_time_limit time states are valid in seconds
*/
function __construct( $client_id, $client_secret, $scope, $endpoint_login, $endpoint_userinfo, $endpoint_token, $redirect_uri, $state_time_limit, $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;
@ -55,12 +55,13 @@ class OpenID_Connect_Generic_Client {
$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',
$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( $scope ),
@ -80,7 +81,7 @@ class OpenID_Connect_Generic_Client {
*
* @return array|\WP_Error
*/
function validate_authentication_request( $request ){
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 );
@ -92,7 +93,7 @@ class OpenID_Connect_Generic_Client {
}
// check the client request state
if( ! isset( $request['state']) ) {
if ( ! isset( $request['state'] ) ) {
do_action( 'openid-connect-generic-no-state-provided' );
return new WP_Error( 'missing-state', __( 'Missing state.' ), $request );
}
@ -111,7 +112,7 @@ class OpenID_Connect_Generic_Client {
*
* @return string|\WP_Error
*/
function get_authentication_code( $request ){
function get_authentication_code( $request ) {
return $request['code'];
}
@ -125,7 +126,7 @@ class OpenID_Connect_Generic_Client {
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);
$parsed_url = parse_url( $this->endpoint_token );
$host = $parsed_url['host'];
$request = array(
@ -137,7 +138,7 @@ 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
@ -147,8 +148,8 @@ class OpenID_Connect_Generic_Client {
$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.' ) );
}
return $response;
@ -167,8 +168,8 @@ 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
@ -179,7 +180,7 @@ class OpenID_Connect_Generic_Client {
$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.' ) );
}
return $response;
@ -191,19 +192,19 @@ class OpenID_Connect_Generic_Client {
* @param $token_result
* @return array|mixed|object
*/
function get_token_response( $token_result ){
if ( ! isset( $token_result['body'] ) ){
function get_token_response( $token_result ) {
if ( ! isset( $token_result['body'] ) ) {
return new WP_Error( 'missing-token-body', __( 'Missing token body.' ), $token_result );
}
// extract token response from token
$token_response = json_decode( $token_result['body'], true );
if ( isset( $token_response[ 'error' ] ) ) {
$error = $token_response[ 'error' ];
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 );
}
@ -225,18 +226,18 @@ class OpenID_Connect_Generic_Client {
// 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'] ) ) {
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);
$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;
@ -245,8 +246,8 @@ class OpenID_Connect_Generic_Client {
$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.' ) );
}
return $response;
@ -288,7 +289,7 @@ class OpenID_Connect_Generic_Client {
do_action( 'openid-connect-generic-state-expired', $state );
}
return !!$valid;
return ! ! $valid;
}
/**
@ -298,11 +299,11 @@ class OpenID_Connect_Generic_Client {
*
* @return bool|\WP_Error
*/
function validate_token_response( $token_response ){
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'
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 );
}
@ -317,7 +318,7 @@ class OpenID_Connect_Generic_Client {
*
* @return array|\WP_Error
*/
function get_id_token_claim( $token_response ){
function get_id_token_claim( $token_response ) {
// name sure we have an id_token
if ( ! isset( $token_response['id_token'] ) ) {
return new WP_Error( 'no-identity-token', __( 'No identity token' ), $token_response );
@ -334,12 +335,12 @@ class OpenID_Connect_Generic_Client {
$id_token_claim = json_decode(
base64_decode(
str_replace( // because token is encoded in base64 URL (and not just base64)
array('-', '_'),
array('+', '/'),
array( '-', '_' ),
array( '+', '/' ),
$tmp[1]
)
)
, true
),
true
);
return $id_token_claim;
@ -352,7 +353,7 @@ class OpenID_Connect_Generic_Client {
*
* @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 );
}
@ -372,7 +373,7 @@ class OpenID_Connect_Generic_Client {
*
* @return array|mixed|object|\WP_Error
*/
function get_user_claim( $token_response ){
function get_user_claim( $token_response ) {
// send a userinfo request to get user claim
$user_claim_result = $this->request_userinfo( $token_response['access_token'] );
@ -397,21 +398,21 @@ class OpenID_Connect_Generic_Client {
*/
function validate_user_claim( $user_claim, $id_token_claim ) {
// must be an array
if ( ! is_array( $user_claim ) ){
if ( ! is_array( $user_claim ) ) {
return new WP_Error( 'invalid-user-claim', __( 'Invalid user claim' ), $user_claim );
}
// allow for errors from the IDP
if ( isset( $user_claim['error'] ) ) {
$message = __( 'Error from the IDP' );
if ( !empty( $user_claim['error_description'] ) ) {
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'] ) {
if ( $id_token_claim['sub'] !== $user_claim['sub'] ) {
return new WP_Error( 'incorrect-user-claim', __( 'Incorrect user claim' ), func_get_args() );
}
@ -432,7 +433,7 @@ class OpenID_Connect_Generic_Client {
*
* @return mixed
*/
function get_subject_identity( $id_token_claim ){
function get_subject_identity( $id_token_claim ) {
return $id_token_claim['sub'];
}
}

@ -9,12 +9,12 @@ class OpenID_Connect_Generic_Login_Form {
* @param $settings
* @param $client_wrapper
*/
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']);
add_action( 'login_form_login', array( $this, 'handle_redirect_cookie' ) );
}
/**
@ -23,7 +23,7 @@ class OpenID_Connect_Generic_Login_Form {
*
* @return \OpenID_Connect_Generic_Login_Form
*/
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
@ -40,19 +40,16 @@ class OpenID_Connect_Generic_Login_Form {
/**
* Auto Login redirect
*/
function handle_redirect_login_type_auto()
{
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();
&& ( ! isset( $_GET['action'] ) || $_GET['action'] !== 'logout' )
&& ! 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 );
}
}
@ -61,16 +58,14 @@ class OpenID_Connect_Generic_Login_Form {
/**
* Handle login related redirects
*/
function handle_redirect_cookie()
{
if ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET[ 'action' ] ) && $_GET[ 'action' ] === 'logout' ) {
function handle_redirect_cookie() {
if ( $GLOBALS['pagenow'] == 'wp-login.php' && isset( $_GET['action'] ) && $_GET['action'] === 'logout' ) {
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;
if ( $this->settings->redirect_user_back ) {
$redirect_expiry = current_time( 'timestamp' ) + DAY_IN_SECONDS;
// default redirect to the homepage
$redirect_url = home_url( esc_url( add_query_arg( null, null ) ) );
@ -80,7 +75,7 @@ class OpenID_Connect_Generic_Login_Form {
$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'] );
}
}
@ -119,8 +114,8 @@ 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 _e( 'ERROR' ); ?>: </strong>
<?php print esc_html( $error_message ); ?>
</div>
<?php
return ob_get_clean();
@ -128,8 +123,8 @@ class OpenID_Connect_Generic_Login_Form {
/**
* Create a login button (link)
*
* @param array $atts Array of optional attributes to override login buton
*
* @param array $atts Array of optional attributes to override login buton
* functionality when used by shortcode.
*
* @return string
@ -139,7 +134,7 @@ class OpenID_Connect_Generic_Login_Form {
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 );

@ -22,12 +22,12 @@ class OpenID_Connect_Generic_Option_Logger {
/**
* Setup the logger according to the needs of the instance
*
* @param string $option_name
* @param string $default_message_type
* @param string $option_name
* @param string $default_message_type
* @param bool|TRUE $logging_enabled
* @param int $log_limit
* @param int $log_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;
@ -38,14 +38,14 @@ class OpenID_Connect_Generic_Option_Logger {
* Subscribe logger to a set of filters
*
* @param $filter_names
* @param int $priority
* @param int $priority
*/
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 );
}
}
@ -56,12 +56,12 @@ class OpenID_Connect_Generic_Option_Logger {
* @param $action_names
* @param $priority
*/
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 );
}
}
@ -72,7 +72,7 @@ class OpenID_Connect_Generic_Option_Logger {
* @param null $arg1
* @return null
*/
function log_hook( $arg1 = null ){
function log_hook( $arg1 = null ) {
$this->log( func_get_args(), current_filter() );
return $arg1;
}
@ -112,7 +112,7 @@ class OpenID_Connect_Generic_Option_Logger {
*
* @return string
*/
public function get_option_name(){
public function get_option_name() {
return $this->option_name;
}
@ -124,15 +124,14 @@ class OpenID_Connect_Generic_Option_Logger {
*
* @return array
*/
private function make_message( $data, $type ){
private function make_message( $data, $type ) {
// determine the type of message
if ( empty( $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();
}
}
@ -142,7 +141,7 @@ class OpenID_Connect_Generic_Option_Logger {
'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,
);
@ -158,9 +157,9 @@ class OpenID_Connect_Generic_Option_Logger {
private function upkeep_logs( $logs ) {
$items_to_remove = count( $logs ) - $this->log_limit;
if ( $items_to_remove > 0 ){
if ( $items_to_remove > 0 ) {
// keep only the last $log_limit messages from the end
$logs = array_slice( $logs, ( $items_to_remove * -1) );
$logs = array_slice( $logs, ( $items_to_remove * -1 ) );
}
return $logs;
@ -172,7 +171,7 @@ class OpenID_Connect_Generic_Option_Logger {
* @param $logs
* @return bool
*/
private function save_logs( $logs ){
private function save_logs( $logs ) {
// save our logs
$this->logs = $logs;
return update_option( $this->option_name, $logs, false );
@ -181,7 +180,7 @@ class OpenID_Connect_Generic_Option_Logger {
/**
* Clear all log messages
*/
public function clear_logs(){
public function clear_logs() {
$this->save_logs( array() );
}
@ -191,7 +190,7 @@ class OpenID_Connect_Generic_Option_Logger {
* @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();
}

@ -15,10 +15,10 @@ class OpenID_Connect_Generic_Option_Settings {
/**
* @param $option_name
* @param array $default_settings
* @param bool|TRUE $granular_defaults
* @param array $default_settings
* @param bool|TRUE $granular_defaults
*/
function __construct( $option_name, $default_settings = array(), $granular_defaults = true ){
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 );
@ -28,25 +28,25 @@ class OpenID_Connect_Generic_Option_Settings {
}
}
function __get( $key ){
function __get( $key ) {
if ( isset( $this->values[ $key ] ) ) {
return $this->values[ $key ];
}
}
function __set( $key, $value ){
function __set( $key, $value ) {
$this->values[ $key ] = $value;
}
function __isset( $key ){
function __isset( $key ) {
return isset( $this->values[ $key ] );
}
function __unset( $key ){
unset( $this->values[ $key ]);
function __unset( $key ) {
unset( $this->values[ $key ] );
}
function get_values(){
function get_values() {
return $this->values;
}
@ -54,7 +54,7 @@ class OpenID_Connect_Generic_Option_Settings {
return $this->option_name;
}
function save(){
function save() {
update_option( $this->option_name, $this->values );
}
}

@ -21,7 +21,7 @@ class OpenID_Connect_Generic_Settings_Page {
/**
* @param OpenID_Connect_Generic_Option_Settings $settings
* @param OpenID_Connect_Generic_Option_Logger $logger
* @param OpenID_Connect_Generic_Option_Logger $logger
*/
function __construct( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) {
$this->settings = $settings;
@ -219,11 +219,11 @@ class OpenID_Connect_Generic_Settings_Page {
/**
* @param \OpenID_Connect_Generic_Option_Settings $settings
* @param \OpenID_Connect_Generic_Option_Logger $logger
* @param \OpenID_Connect_Generic_Option_Logger $logger
*
* @return \OpenID_Connect_Generic_Settings_Page
*/
static public function register( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ){
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
@ -245,37 +245,46 @@ class OpenID_Connect_Generic_Settings_Page {
__( 'OpenID Connect Client' ),
'manage_options',
$this->options_page_name,
array( $this, 'settings_page' ) );
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'
) );
register_setting(
$this->settings_field_group,
$this->settings->get_option_name(),
array(
$this,
'sanitize_settings',
)
);
add_settings_section( 'client_settings',
add_settings_section(
'client_settings',
__( 'Client Settings' ),
array( $this, 'client_settings_description' ),
$this->options_page_name
);
add_settings_section( 'user_settings',
add_settings_section(
'user_settings',
__( 'WordPress User Settings' ),
array( $this, 'user_settings_description' ),
$this->options_page_name
);
add_settings_section( 'authorization_settings',
add_settings_section(
'authorization_settings',
__( 'Authorization Settings' ),
array( $this, 'authorization_settings_description' ),
$this->options_page_name
);
add_settings_section( 'log_settings',
add_settings_section(
'log_settings',
__( 'Log Settings' ),
array( $this, 'log_settings_description' ),
$this->options_page_name
@ -305,7 +314,9 @@ class OpenID_Connect_Generic_Settings_Page {
}
// add the field
add_settings_field( $key, $field['title'],
add_settings_field(
$key,
$field['title'],
array( $this, $callback ),
$this->options_page_name,
$field['section'],
@ -328,8 +339,7 @@ class OpenID_Connect_Generic_Settings_Page {
foreach ( $this->settings_fields as $key => $field ) {
if ( isset( $input[ $key ] ) ) {
$options[ $key ] = sanitize_text_field( trim( $input[ $key ] ) );
}
else {
} else {
$options[ $key ] = '';
}
}
@ -343,7 +353,7 @@ class OpenID_Connect_Generic_Settings_Page {
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' );
}
?>
@ -397,10 +407,10 @@ class OpenID_Connect_Generic_Settings_Page {
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'] } ); ?>">
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
$this->do_field_description( $field );
}
@ -415,9 +425,9 @@ class OpenID_Connect_Generic_Settings_Page {
?>
<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 );
@ -430,7 +440,7 @@ class OpenID_Connect_Generic_Settings_Page {
$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>

@ -2,13 +2,12 @@
/**
* OpenID Connect Generic Client
*
* This plugin provides the ability to authenticate users with Identity
* This plugin provides the ability to authenticate users with Identity
* Providers using the OpenID Connect OAuth2 API with Authorization Code Flow.
*
* @category Authentication
* @package OpenID_Connect_Generic
* @author Jonathan Daggerhart <jonathan@daggerhart.com>
* @author Tim Nolte <tim.nolte@ndigitals.com>
* @copyright 2015-2020 daggerhart
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
* @link https://github.com/daggerhart
@ -20,6 +19,8 @@
* Version: 3.6.0
* Author: daggerhart
* 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
@ -64,32 +65,65 @@ Notes
*/
/**
* OpenID_Connect_Generic class.
* Defines plugin initialization functionality.
*
* @package OpenID_Connect_Generic
*/
class OpenID_Connect_Generic {
// plugin version
/**
* Plugin version.
*
* @var
*/
const VERSION = '3.7.0';
// plugin settings
/**
* 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
/**
* Settings admin page.
*
* @var OpenID_Connect_Generic_Option_Settings
*/
private $settings_page;
// login form adjustments
/**
* Login form adjustments.
*
* @var OpenID_Connect_Generic_Login_Form
*/
private $login_form;
/**
* 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;
}
@ -97,17 +131,17 @@ class OpenID_Connect_Generic {
/**
* WP Hook 'init'
*/
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(
@ -133,11 +167,11 @@ class OpenID_Connect_Generic {
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_action( 'openid-connect-generic-cron-daily', array( $this, 'cron_states_garbage_collection' ) );
$this->upgrade();
if ( is_admin() ){
if ( is_admin() ) {
$this->settings_page = OpenID_Connect_Generic_Settings_Page::register( $this->settings, $this->logger );
}
}
@ -149,7 +183,7 @@ class OpenID_Connect_Generic {
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' ) {
if ( ! defined( 'DOING_AJAX' ) || ! DOING_AJAX || ! isset( $_GET['action'] ) || $_GET['action'] != 'openid-connect-authorize' ) {
auth_redirect();
}
}
@ -162,7 +196,7 @@ class OpenID_Connect_Generic {
*
* @return mixed
*/
function enforce_privacy_feeds( $content ){
function enforce_privacy_feeds( $content ) {
if ( $this->settings->enforce_privacy && ! is_user_logged_in() ) {
$content = 'Private site';
}
@ -172,7 +206,7 @@ class OpenID_Connect_Generic {
/**
* Handle plugin upgrades
*/
function upgrade(){
function upgrade() {
$last_version = get_option( 'openid-connect-generic-plugin-version', 0 );
$settings = $this->settings;
@ -203,10 +237,10 @@ class OpenID_Connect_Generic {
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 );
}
}
}
@ -242,7 +276,7 @@ class OpenID_Connect_Generic {
static public function autoload( $class ) {
$prefix = 'OpenID_Connect_Generic_';
if ( stripos($class, $prefix) !== 0 ) {
if ( stripos( $class, $prefix ) !== 0 ) {
return;
}
@ -251,9 +285,8 @@ class OpenID_Connect_Generic {
// 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;
@ -266,7 +299,7 @@ class OpenID_Connect_Generic {
/**
* Instantiate the plugin and hook into WP
*/
static public function bootstrap(){
static public function bootstrap() {
spl_autoload_register( array( 'OpenID_Connect_Generic', 'autoload' ) );
$settings = new OpenID_Connect_Generic_Option_Settings(
@ -314,12 +347,12 @@ class OpenID_Connect_Generic {
// 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' ) );

18708
package-lock.json generated

File diff suppressed because it is too large Load Diff

@ -0,0 +1,60 @@
{
"name": "openid-connect-generic",
"version": "3.7.0",
"description": "OpenID Connect generic WordPress plugin.",
"main": "Gruntfile.js",
"repository": {
"type": "git",
"url": "https://github.com/daggerhart/openid-connect-generic"
},
"keywords": [
"wordpress",
"openid"
],
"author": "Jonathan Daggerhart",
"license": "GPL-2.0-only",
"bugs": {
"url": "https://github.com/daggerhart/openid-connect-generic/issues"
},
"homepage": "https://github.com/daggerhart/openid-connect-generic#readme",
"dependencies": {
"dev-require": "^0.1.0"
},
"devDependencies": {
"@floatwork/grunt-po2mo": "^0.3.0",
"@ndigitals/grunt-checkrepo": "^0.2.0",
"@wordpress/env": "^1.6.0",
"@wordpress/scripts": "^12.1.0",
"grunt": "~1.0.4",
"grunt-checkbranch": "^1.0.4",
"grunt-checktextdomain": "^1.0.1",
"grunt-contrib-clean": "^2.0.0",
"grunt-contrib-copy": "^1.0.0",
"grunt-gitinfo": "^0.1.9",
"grunt-shell": "^2.1.0",
"grunt-wp-i18n": "^1.0.3",
"grunt-wp-readme-to-markdown": "~2.0.0",
"load-grunt-tasks": "^3.5",
"puppeteer": "^1.20.0",
"typescript": "^3.9.7"
},
"wp-env": {
"plugin-dir": "daggerhart-openid-connect-generic",
"plugin-name": "OpenID Connect Generic",
"docker-template": "./docker-compose.override.yml",
"welcome-build-command": "npm run env start"
},
"scripts": {
"grunt": "node_modules/.bin/grunt",
"test": "npm run grunt test",
"build": "npm run grunt build",
"wp-env": "wp-env",
"wp": "wp-env run cli wp",
"makepot": "wp-env run cli wp i18n make-pot . languages/ --slug=daggerhart-openid-connect-generic --include=openid-connect-generic.php,includes",
"lint": "npm run lint:php",
"lint:php": "composer run-script phpcs .",
"lint-fix:php": "composer run-script phpcbf .",
"analyze": "npm run analyze:php",
"analyze:php": "composer run-script phpstan analyze ."
}
}

@ -0,0 +1,32 @@
<?xml version="1.0"?>
<ruleset name="WordPress Coding Standards for Plugins">
<description>Generally-applicable sniffs for WordPress plugins</description>
<rule ref="WordPress-Core">
<exclude name="WordPress.Files.FileName.NotHyphenatedLowercase" />
<exclude name="WordPress.Files.FileName.InvalidClassFileName" />
</rule>
<rule ref="WordPress-Docs" />
<!-- Check all PHP files in directory tree by default. -->
<arg name="basepath" value="." />
<arg name="extensions" value="php" />
<arg name="report" value="summary" />
<!-- Show colors. -->
<arg name="colors" />
<!-- Show progress. -->
<arg value="p" />
<arg value="n" />
<file>.</file>
<!-- Show sniff codes in all reports -->
<arg value="s"/>
<exclude-pattern>*/dist/*</exclude-pattern>
<exclude-pattern>*/node_modules/*</exclude-pattern>
<exclude-pattern>*/tests/*</exclude-pattern>
<exclude-pattern>*/tools/*</exclude-pattern>
<exclude-pattern>*/vendor/*</exclude-pattern>
<exclude-pattern>*/wordpress/*</exclude-pattern>
</ruleset>

@ -0,0 +1,51 @@
#$ composer update --optimize-autoloader
#$ vendor/bin/phpstan analyze
includes:
# @see https://github.com/phpstan/phpstan-src/blob/master/conf/bleedingEdge.neon
- phar://phpstan.phar/conf/bleedingEdge.neon
# Include this extension
# - vendor/szepeviktor/phpstan-wordpress/extension.neon
parameters:
level: max
inferPrivatePropertyTypeFromConstructor: true
bootstrapFiles:
- tests/phpstan-bootstrap.php
# autoload_files:
# Missing constants, function and class stubs
# - tests/phpstan/bootstrap.php
# Plugin stubs
# - tests/phpstan/PLUGIN-stubs.php
# Procedural code
# - myplugin-functions.php
# autoload_directories:
# - inc/
paths:
- includes/
- ./
excludes_analyse:
- node_modules/
- scripts/
- tests/
- tools/
- vendor/
- wordpress/
# scanFiles:
# - includes/class.php
scanDirectories:
- wordpress/src/
ignoreErrors:
# Uses func_get_args()
- '#^Function apply_filters(_ref_array)? invoked with [34567] parameters, 2 required\.$#'
# Fixed in WordPress 5.3
# - '#^Function do_action(_ref_array)? invoked with [3456] parameters, 1-2 required\.$#'
# - '#^Function current_user_can invoked with 2 parameters, 1 required\.$#'
# - '#^Function add_query_arg invoked with [123] parameters?, 0 required\.$#'
# - '#^Function wp_sprintf invoked with [23456] parameters, 1 required\.$#'
# - '#^Function add_post_type_support invoked with [345] parameters, 2 required\.$#'
# - '#^Function ((get|add)_theme_support|current_theme_supports) invoked with [2345] parameters, 1 required\.$#'
# https://core.trac.wordpress.org/ticket/43304
# - '/^Parameter #2 \$deprecated of function load_plugin_textdomain expects string, false given\.$/'
# WP-CLI accepts a class as callable
# - '/^Parameter #2 \$callable of static method WP_CLI::add_command\(\) expects callable\(\): mixed, \S+ given\.$/'
# Please consider commenting ignores: issue URL or reason for ignoring

@ -0,0 +1,28 @@
<?xml version="1.0"?>
<phpunit
bootstrap="tests/bootstrap.php"
backupGlobals="false"
colors="true"
convertErrorsToExceptions="true"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
>
<testsuites>
<testsuite name="Includes">
<directory suffix="_test.php">./tests/phpunit/includes/</directory>
</testsuite>
</testsuites>
<filter>
<whitelist processUncoveredFilesFromWhitelist="true">
<directory suffix=".php">src/</directory>
<!-- <file>/path/to/file</file> -->
<exclude>
<directory suffix=".php">src/views</directory>
<!-- <file>/path/to/file</file> -->
</exclude>
</whitelist>
</filter>
<logging>
<log type="coverage-clover" target="clover.xml"/>
</logging>
</phpunit>

@ -0,0 +1,127 @@
#!/usr/bin/env bash
if [ $# -lt 3 ]; then
echo "usage: $0 <db-name> <db-user> <db-pass> [db-host] [wp-version] [skip-database-creation]"
exit 1
fi
DB_NAME=$1
DB_USER=$2
DB_PASS=$3
DB_HOST=${4-localhost}
WP_VERSION=${5-latest}
SKIP_DB_CREATE=${6-false}
WP_TESTS_DIR=${WP_TESTS_DIR-${TMPDIR-/tmp}/wordpress-tests-lib}
WP_CORE_DIR=${WP_CORE_DIR-${TMPDIR-/tmp}/wordpress/}
download() {
if [ `which curl` ]; then
curl -s "$1" > "$2";
elif [ `which wget` ]; then
wget -nv -O "$2" "$1"
fi
}
if [[ $WP_VERSION =~ [0-9]+\.[0-9]+(\.[0-9]+)? ]]; then
WP_TESTS_TAG="tags/$WP_VERSION"
elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
WP_TESTS_TAG="trunk"
else
# http serves a single offer, whereas https serves multiple. we only want one
download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
if [[ -z "$LATEST_VERSION" ]]; then
echo "Latest WordPress version could not be found"
exit 1
fi
WP_TESTS_TAG="tags/$LATEST_VERSION"
fi
set -ex
install_wp() {
if [ -d $WP_CORE_DIR ]; then
return;
fi
mkdir -p $WP_CORE_DIR
if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
mkdir -p /tmp/wordpress-nightly
download https://wordpress.org/nightly-builds/wordpress-latest.zip /tmp/wordpress-nightly/wordpress-nightly.zip
unzip -q /tmp/wordpress-nightly/wordpress-nightly.zip -d /tmp/wordpress-nightly/
mv /tmp/wordpress-nightly/wordpress/* $WP_CORE_DIR
else
if [ $WP_VERSION == 'latest' ]; then
local ARCHIVE_NAME='latest'
else
local ARCHIVE_NAME="wordpress-$WP_VERSION"
fi
download https://wordpress.org/${ARCHIVE_NAME}.tar.gz /tmp/wordpress.tar.gz
tar --strip-components=1 -zxmf /tmp/wordpress.tar.gz -C $WP_CORE_DIR
fi
download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
}
install_test_suite() {
# portable in-place argument for both GNU sed and Mac OSX sed
if [[ $(uname -s) == 'Darwin' ]]; then
local ioption='-i .bak'
else
local ioption='-i'
fi
# set up testing suite if it doesn't yet exist
if [ ! -d $WP_TESTS_DIR ]; then
# set up testing suite
mkdir -p $WP_TESTS_DIR
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
svn co --quiet https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
fi
if [ ! -f wp-tests-config.php ]; then
download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
# remove all forward slashes in the end
WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
fi
}
install_db() {
if [ ${SKIP_DB_CREATE} = "true" ]; then
return 0
fi
# parse DB_HOST for port or socket references
local PARTS=(${DB_HOST//\:/ })
local DB_HOSTNAME=${PARTS[0]};
local DB_SOCK_OR_PORT=${PARTS[1]};
local EXTRA=""
if ! [ -z $DB_HOSTNAME ] ; then
if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
elif ! [ -z $DB_SOCK_OR_PORT ] ; then
EXTRA=" --socket=$DB_SOCK_OR_PORT"
elif ! [ -z $DB_HOSTNAME ] ; then
EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
fi
fi
# create database
mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
}
install_wp
install_test_suite
install_db

@ -0,0 +1,14 @@
<?php
/**
* Phpstan bootstrap file.
*
* @package OpenID_Connect_Generic
* @author Jonathan Daggerhart <jonathan@daggerhart.com>
* @author Tim Nolte <tim.nolte@ndigitals.com>
* @copyright 2015-2020 daggerhart
* @license http://www.gnu.org/licenses/gpl-2.0.txt GPL-2.0+
* @link https://github.com/daggerhart
*/
// Define WordPress language directory.
defined( 'WP_LANG_DIR' ) || define( 'WP_LANG_DIR', 'wordpress/src/wp-includes/languages/' );

@ -0,0 +1,30 @@
server {
index index.php index.html;
listen 80 default_server;
server_name localhost penguin.linux.test ${LOCAL_HOSTNAME};
client_max_body_size 1g;
error_log /var/log/nginx/error.log;
access_log /var/log/nginx/access.log;
root /var/www/${LOCAL_DIR};
absolute_redirect off;
location / {
try_files $uri $uri/ /index.php?$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass php:9000;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_param PATH_INFO $fastcgi_path_info;
}
}

@ -0,0 +1,37 @@
<?php
/**
* Plugin Name: MailHog PhpMailer Setup
* Description: Establishes a connection between the PhpMailer library and the MailHog local-dev Docker container.
*
* @package OpenID_Connect_Generic_MuPlugins
*/
// If this file is called directly, abort.
if ( ! defined( 'WPINC' ) ) {
die;
}
/**
* Provides the configuration for PhpMailer to use MailHog.
*
* @param PHPMailer $phpmailer The PHPMailer instance.
*
* @return void
*/
function mailhog_phpmailer_setup( PHPMailer $phpmailer ) {
defined( 'SMTP_HOST' ) || define( 'SMTP_HOST', 'mailhog' );
// PHPMailer doesn't follow WordPress naming conventions so this can be ignored.
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$phpmailer->Host = SMTP_HOST;
defined( 'SMTP_PORT' ) || define( 'SMTP_PORT', 1025 );
// PHPMailer doesn't follow WordPress naming conventions so this can be ignored.
// phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase
$phpmailer->Port = SMTP_PORT;
$phpmailer->IsSMTP();
}
add_action( 'phpmailer_init', 'mailhog_phpmailer_setup', 10, 2 );
Loading…
Cancel
Save