diff --git a/grumphp.yml.dist b/grumphp.yml.dist index b90950c..8a63c20 100644 --- a/grumphp.yml.dist +++ b/grumphp.yml.dist @@ -31,7 +31,7 @@ parameters: - '/^assets\/(.*)/' phpstan: configuration: './phpstan.neon.dist' - level: max + level: 5 ignore_patterns: - '/^assets\/(.*)/' memory_limit: '-1' diff --git a/includes/openid-connect-generic-client-wrapper.php b/includes/openid-connect-generic-client-wrapper.php index 26b23af..3993ef5 100644 --- a/includes/openid-connect-generic-client-wrapper.php +++ b/includes/openid-connect-generic-client-wrapper.php @@ -141,7 +141,7 @@ 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. + * @param array $atts The optional attributes array when called via a shortcode. * * @return string */ @@ -249,11 +249,11 @@ class OpenID_Connect_Generic_Client_Wrapper { /** * Add the end_session endpoint to WordPress core's whitelist of redirect hosts. * - * @param array $allowed The allowed redirect host names. + * @param array $allowed The allowed redirect host names. * - * @return array|bool + * @return array|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; @@ -311,8 +311,8 @@ class OpenID_Connect_Generic_Client_Wrapper { /** * Modify outgoing requests according to settings. * - * @param array $request The outgoing request array. - * @param string $operation The request operation name. + * @param array $request The outgoing request array. + * @param string $operation The request operation name. * * @return mixed */ @@ -429,7 +429,7 @@ class OpenID_Connect_Generic_Client_Wrapper { $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 ) ); + $this->error_redirect( new WP_Error( 'identity-not-map-existing-user', __( 'User identity is not linked to an existing WordPress user' ), $user_claim ) ); } } else { // Allow plugins / themes to take action using current claims on existing user (e.g. update role). @@ -468,7 +468,7 @@ class OpenID_Connect_Generic_Client_Wrapper { /** * Validate the potential WP_User. * - * @param WP_User $user The user object. + * @param WP_User|WP_Error|false $user The user object. * * @return true|WP_Error */ @@ -514,9 +514,9 @@ class OpenID_Connect_Generic_Client_Wrapper { /** * Save refresh token to WP session tokens * - * @param WP_Session_Tokens $manager A user session tokens manager. - * @param string $token The current users session token. - * @param array $token_response The authentication 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 ) { if ( ! $this->settings->token_refresh_enable ) { @@ -578,6 +578,10 @@ class OpenID_Connect_Generic_Client_Wrapper { * @return string|WP_Error|null */ private function get_username_from_claim( $user_claim ) { + + // @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 ]; @@ -594,13 +598,14 @@ class OpenID_Connect_Generic_Client_Wrapper { } // 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', printf( __( 'Username %1$s could not be transliterated' ), $desired_username ), $desired_username ); + return new WP_Error( 'username-transliteration-failed', sprintf( __( 'Username %1$s could not be transliterated' ), $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', printf( __( 'Username %1$s could not be normalized' ), $transliterated_username ), $transliterated_username ); + return new WP_Error( 'username-normalization-failed', sprintf( __( 'Username %1$s could not be normalized' ), $transliterated_username ), $transliterated_username ); } // Copy the username for incrementing. @@ -623,7 +628,7 @@ class OpenID_Connect_Generic_Client_Wrapper { * * @param array $user_claim The IDP authenticated user claim data. * - * @return string|null + * @return string|WP_Error|null */ private function get_nickname_from_claim( $user_claim ) { $desired_nickname = null; @@ -631,6 +636,11 @@ class OpenID_Connect_Generic_Client_Wrapper { 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.' ), $this->settings->nickname_key ), $this->settings->nickname_key ); + } + return $desired_nickname; } diff --git a/includes/openid-connect-generic-client.php b/includes/openid-connect-generic-client.php index 85554f5..273539b 100644 --- a/includes/openid-connect-generic-client.php +++ b/includes/openid-connect-generic-client.php @@ -158,9 +158,9 @@ class OpenID_Connect_Generic_Client { /** * Validate the request for login authentication * - * @param array $request The authentication request results. + * @param array $request The authentication request results. * - * @return array|WP_Error + * @return array|WP_Error */ function validate_authentication_request( $request ) { // Look for an existing error of some kind. @@ -189,20 +189,24 @@ class OpenID_Connect_Generic_Client { /** * Get the authorization code from the request * - * @param array $request The authentication request results. + * @param array|WP_Error $request The authentication request results. * * @return string|WP_Error */ function get_authentication_code( $request ) { + if ( ! isset( $request['code'] ) ) { + return new WP_Error( 'missing-authentication-code', __( 'Missing authentication code.' ), $request ); + } + return $request['code']; } /** * Using the authorization_code, request an authentication token from the IDP. * - * @param string $code The authorization code. + * @param string|WP_Error $code The authorization code. * - * @return array|WP_Error + * @return array|WP_Error */ function request_authentication_token( $code ) { @@ -270,9 +274,9 @@ class OpenID_Connect_Generic_Client { /** * Extract and decode the token body of a token response * - * @param array $token_result The token response. + * @param array|WP_Error $token_result The token response. * - * @return array|WP_Error|null + * @return array|WP_Error|null */ function get_token_response( $token_result ) { if ( ! isset( $token_result['body'] ) ) { diff --git a/includes/openid-connect-generic-login-form.php b/includes/openid-connect-generic-login-form.php index 2db0fd3..7a8c071 100644 --- a/includes/openid-connect-generic-login-form.php +++ b/includes/openid-connect-generic-login-form.php @@ -53,7 +53,7 @@ class 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 OpenID_Connect_Generic_Login_Form + * @return void */ static public function register( $settings, $client_wrapper ) { $login_form = new self( $settings, $client_wrapper ); @@ -65,8 +65,6 @@ class OpenID_Connect_Generic_Login_Form { add_shortcode( 'openid_connect_generic_login_button', array( $login_form, 'make_login_button' ) ); $login_form->handle_redirect_login_type_auto(); - - return $login_form; } /** diff --git a/includes/openid-connect-generic-option-logger.php b/includes/openid-connect-generic-option-logger.php index 939a805..44c966f 100644 --- a/includes/openid-connect-generic-option-logger.php +++ b/includes/openid-connect-generic-option-logger.php @@ -243,7 +243,7 @@ class OpenID_Connect_Generic_Option_Logger { } $logs = array_reverse( $logs ); - ini_set( 'xdebug.var_display_max_depth', -1 ); + ini_set( 'xdebug.var_display_max_depth', '-1' ); ob_start(); ?> diff --git a/includes/openid-connect-generic-option-settings.php b/includes/openid-connect-generic-option-settings.php index f5822ab..1f558af 100644 --- a/includes/openid-connect-generic-option-settings.php +++ b/includes/openid-connect-generic-option-settings.php @@ -69,28 +69,32 @@ class OpenID_Connect_Generic_Option_Settings { /** * Stored option values array. * - * @var array + * @var array */ private $values; /** * Default plugin settings values. * - * @var array + * @var array */ private $default_settings; /** * The class constructor. * - * @param string $option_name The option name/key. - * @param array $default_settings The default plugin settings values. - * @param bool|TRUE $granular_defaults The granular defaults. + * @param string $option_name The option name/key. + * @param array $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 ) ) { + get_option( $this->option_name, $this->default_settings ); + } if ( $granular_defaults ) { $this->values = array_replace_recursive( $this->default_settings, $this->values ); diff --git a/includes/openid-connect-generic-settings-page.php b/includes/openid-connect-generic-settings-page.php index cc16f23..cd7c162 100644 --- a/includes/openid-connect-generic-settings-page.php +++ b/includes/openid-connect-generic-settings-page.php @@ -85,7 +85,7 @@ class OpenID_Connect_Generic_Settings_Page { * @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 \OpenID_Connect_Generic_Settings_Page + * @return void */ static public function register( OpenID_Connect_Generic_Option_Settings $settings, OpenID_Connect_Generic_Option_Logger $logger ) { $settings_page = new self( $settings, $logger ); @@ -95,8 +95,6 @@ class OpenID_Connect_Generic_Settings_Page { // Register our settings. add_action( 'admin_init', array( $settings_page, 'admin_init' ) ); - - return $settings_page; } /** diff --git a/openid-connect-generic.php b/openid-connect-generic.php index c5285ce..585735b 100644 --- a/openid-connect-generic.php +++ b/openid-connect-generic.php @@ -103,20 +103,6 @@ class OpenID_Connect_Generic { */ private $client; - /** - * Settings admin page. - * - * @var OpenID_Connect_Generic_Settings_Page - */ - private $settings_page; - - /** - * Login form adjustments. - * - * @var OpenID_Connect_Generic_Login_Form - */ - private $login_form; - /** * Client wrapper. * @@ -172,7 +158,7 @@ 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_shortcode( 'openid_connect_generic_auth_url', array( $this->client_wrapper, 'get_authentication_url' ) ); @@ -183,13 +169,15 @@ class OpenID_Connect_Generic { $this->upgrade(); if ( is_admin() ) { - $this->settings_page = OpenID_Connect_Generic_Settings_Page::register( $this->settings, $this->logger ); + 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() ) { @@ -216,6 +204,8 @@ class OpenID_Connect_Generic { /** * Handle plugin upgrades + * + * @return void */ function upgrade() { $last_version = get_option( 'openid-connect-generic-plugin-version', 0 ); @@ -243,6 +233,8 @@ 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; @@ -258,6 +250,8 @@ class OpenID_Connect_Generic { /** * 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' ) ) { @@ -267,6 +261,8 @@ class OpenID_Connect_Generic { /** * Activation hook. + * + * @return void */ static public function activation() { self::setup_cron_jobs(); @@ -274,6 +270,8 @@ class OpenID_Connect_Generic { /** * Deactivation hook. + * + * @return void */ static public function deactivation() { wp_clear_scheduled_hook( 'openid-connect-generic-cron-daily' ); @@ -283,6 +281,8 @@ class OpenID_Connect_Generic { * Simple autoloader. * * @param string $class The class name. + * + * @return void */ static public function autoload( $class ) { $prefix = 'OpenID_Connect_Generic_'; @@ -308,9 +308,16 @@ class OpenID_Connect_Generic { } /** - * Instantiate the plugin and hook into WP + * Instantiate the plugin and hook into WordPress. + * + * @return void */ 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( diff --git a/phpstan.neon.dist b/phpstan.neon.dist index 3427e77..6b2cc68 100644 --- a/phpstan.neon.dist +++ b/phpstan.neon.dist @@ -7,7 +7,7 @@ includes: # Include this extension # - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: - level: max + level: 5 inferPrivatePropertyTypeFromConstructor: true bootstrapFiles: - tests/phpstan-bootstrap.php diff --git a/tests/phpstan-bootstrap.php b/tests/phpstan-bootstrap.php index 0df3e24..7acfb44 100644 --- a/tests/phpstan-bootstrap.php +++ b/tests/phpstan-bootstrap.php @@ -12,3 +12,8 @@ // Define WordPress language directory. defined( 'WP_LANG_DIR' ) || define( 'WP_LANG_DIR', 'wordpress/src/wp-includes/languages/' ); + +defined( 'COOKIE_DOMAIN' ) || define( 'COOKIE_DOMAIN', 'localhost' ); +defined( 'COOKIEPATH' ) || define( 'COOKIEPATH', '/'); + +