From 5183cec200edf109ef550a73d984323de0b1c5fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 1 Dec 2021 17:18:34 +0100 Subject: [PATCH 01/57] Run CI on PHP 8.1 as well --- .github/workflows/php.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index c8e50c3..070da36 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -18,7 +18,7 @@ jobs: build: strategy: matrix: - php-versions: ['8.0', '7.4', '7.3'] + php-versions: ['8.1', '8.0', '7.4', '7.3'] runs-on: ubuntu-latest From 4ed3584e46a19c0370dd12d9531feef630c25867 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 1 Dec 2021 17:21:49 +0100 Subject: [PATCH 02/57] Improve and optimize CI action --- .github/workflows/php.yml | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/.github/workflows/php.yml b/.github/workflows/php.yml index 070da36..557eaf6 100644 --- a/.github/workflows/php.yml +++ b/.github/workflows/php.yml @@ -3,17 +3,25 @@ name: CI test suite on: pull_request: paths: + - '.github/workflows/**' - 'composer.*' - phpcs.xml - phpstan.neon - '**.php' push: paths: + - '.github/workflows/**' - 'composer.*' - phpcs.xml - phpstan.neon - '**.php' +# Cancels all previous workflow runs for the same branch that have not yet completed. +concurrency: + # The concurrency group contains the workflow name and the branch name. + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true + jobs: build: strategy: @@ -35,7 +43,7 @@ jobs: run: composer validate - name: Install dependencies - run: composer install --prefer-dist --no-progress --no-suggest --classmap-authoritative + uses: ramsey/composer-install@v1 - name: Run CI test suite run: composer run-script ci From 5098cb95861433f294068ac8dfdd661228c6159d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 1 Dec 2021 17:37:43 +0100 Subject: [PATCH 03/57] Fix issues on PHP 8.1 --- classes/BlueChip/Security/Core/Settings.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/classes/BlueChip/Security/Core/Settings.php b/classes/BlueChip/Security/Core/Settings.php index 54ad107..0d45340 100644 --- a/classes/BlueChip/Security/Core/Settings.php +++ b/classes/BlueChip/Security/Core/Settings.php @@ -115,7 +115,7 @@ public function offsetGet($offset) * @param string $offset * @param mixed $value */ - public function offsetSet($offset, $value) + public function offsetSet($offset, $value): void { $this->update($offset, $value); } @@ -128,7 +128,7 @@ public function offsetSet($offset, $value) * * @param string $offset */ - public function offsetUnset($offset) + public function offsetUnset($offset): void { $this->update($offset, null); } From b80f0c3a6dcae2636944e52fae9986d6f07d0784 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 11:43:23 +0100 Subject: [PATCH 04/57] Replace dead (redirected) Codex links --- .../Checklist/Checks/ErrorLogNotPubliclyAccessible.php | 4 ++-- .../Modules/Checklist/Checks/NoObviousUsernamesCheck.php | 4 ++-- .../Modules/Checklist/Checks/PhpFilesEditationDisabled.php | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/ErrorLogNotPubliclyAccessible.php b/classes/BlueChip/Security/Modules/Checklist/Checks/ErrorLogNotPubliclyAccessible.php index 5801727..ee46821 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/ErrorLogNotPubliclyAccessible.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/ErrorLogNotPubliclyAccessible.php @@ -11,9 +11,9 @@ public function __construct() parent::__construct( __('Error log not publicly accessible', 'bc-security'), \sprintf( - /* translators: 1: link to Codex page on debugging, 2: WP_DEBUG constant, 3: WP_DEBUG_LOG constant, 4: debug.log file, 5: /wp-content path */ + /* translators: 1: link to article on debugging, 2: WP_DEBUG constant, 3: WP_DEBUG_LOG constant, 4: debug.log file, 5: /wp-content path */ esc_html__('Both %2$s and %3$s constants are set to true, therefore %1$s to a %4$s log file inside the %5$s directory. This file can contain sensitive information and therefore should not be publicly accessible.', 'bc-security'), - '' . esc_html__('WordPress saves all errors', 'bc-security') . '', + '' . esc_html__('WordPress saves all errors', 'bc-security') . '', 'WP_DEBUG', 'WP_DEBUG_LOG', 'debug.log', diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/NoObviousUsernamesCheck.php b/classes/BlueChip/Security/Modules/Checklist/Checks/NoObviousUsernamesCheck.php index 11ea098..666a6fc 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/NoObviousUsernamesCheck.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/NoObviousUsernamesCheck.php @@ -11,9 +11,9 @@ public function __construct() parent::__construct( __('No obvious usernames exist', 'bc-security'), \sprintf( - /* translators: 1: link to Codex page on WordPress hardening */ + /* translators: 1: link to article on WordPress hardening */ esc_html__('Usernames like "admin" and "administrator" are often used in brute force attacks and %1$s.', 'bc-security'), - '' . esc_html__('should be avoided', 'bc-security') . '' + '' . esc_html__('should be avoided', 'bc-security') . '' ) ); } diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/PhpFilesEditationDisabled.php b/classes/BlueChip/Security/Modules/Checklist/Checks/PhpFilesEditationDisabled.php index 7ea5d09..7adec28 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/PhpFilesEditationDisabled.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/PhpFilesEditationDisabled.php @@ -11,9 +11,9 @@ public function __construct() parent::__construct( __('PHP files editation disabled', 'bc-security'), \sprintf( - /* translators: 1: link to Codex page on WordPress hardening */ + /* translators: 1: link to article on WordPress hardening */ esc_html__('It is generally recommended to %1$s.', 'bc-security'), - '' . esc_html__('disable editation of PHP files', 'bc-security') . '' + '' . esc_html__('disable editation of PHP files', 'bc-security') . '' ) ); } From 8d682ef5eb394dcb002f229add573d8c5fd4e8d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 12:14:15 +0100 Subject: [PATCH 05/57] Update Composer dependencies --- composer.lock | 60 +++++++++++++++++++++++++-------------------------- 1 file changed, 30 insertions(+), 30 deletions(-) diff --git a/composer.lock b/composer.lock index ece847d..1b7f797 100644 --- a/composer.lock +++ b/composer.lock @@ -883,16 +883,16 @@ }, { "name": "phpspec/prophecy", - "version": "1.14.0", + "version": "v1.15.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e" + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", - "reference": "d86dfc2e2a3cd366cee475e52c6bb3bbc371aa0e", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", + "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", "shasum": "" }, "require": { @@ -944,9 +944,9 @@ ], "support": { "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/1.14.0" + "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" }, - "time": "2021-09-10T09:02:12+00:00" + "time": "2021-12-08T12:19:24+00:00" }, { "name": "phpstan/phpstan", @@ -1014,16 +1014,16 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.9", + "version": "9.2.10", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b" + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", - "reference": "f301eb1453c9e7a1bc912ee8b0ea9db22c60223b", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/d5850aaf931743067f4bfc1ae4cbd06468400687", + "reference": "d5850aaf931743067f4bfc1ae4cbd06468400687", "shasum": "" }, "require": { @@ -1079,7 +1079,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.9" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.10" }, "funding": [ { @@ -1087,20 +1087,20 @@ "type": "github" } ], - "time": "2021-11-19T15:21:02+00:00" + "time": "2021-12-05T09:12:13+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "3.0.5", + "version": "3.0.6", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8" + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/aa4be8575f26070b100fccb67faabb28f21f66f8", - "reference": "aa4be8575f26070b100fccb67faabb28f21f66f8", + "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", + "reference": "cf1c2e7c203ac650e352f4cc675a7021e7d1b3cf", "shasum": "" }, "require": { @@ -1139,7 +1139,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-file-iterator/issues", - "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.5" + "source": "https://github.com/sebastianbergmann/php-file-iterator/tree/3.0.6" }, "funding": [ { @@ -1147,7 +1147,7 @@ "type": "github" } ], - "time": "2020-09-28T05:57:25+00:00" + "time": "2021-12-02T12:48:52+00:00" }, { "name": "phpunit/php-invoker", @@ -1332,16 +1332,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.10", + "version": "9.5.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a" + "reference": "2406855036db1102126125537adb1406f7242fdd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/c814a05837f2edb0d1471d6e3f4ab3501ca3899a", - "reference": "c814a05837f2edb0d1471d6e3f4ab3501ca3899a", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd", + "reference": "2406855036db1102126125537adb1406f7242fdd", "shasum": "" }, "require": { @@ -1419,11 +1419,11 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.10" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11" }, "funding": [ { - "url": "https://phpunit.de/donate.html", + "url": "https://phpunit.de/sponsors.html", "type": "custom" }, { @@ -1431,7 +1431,7 @@ "type": "github" } ], - "time": "2021-09-25T07:38:51+00:00" + "time": "2021-12-25T07:07:57+00:00" }, { "name": "sebastian/cli-parser", @@ -2399,16 +2399,16 @@ }, { "name": "squizlabs/php_codesniffer", - "version": "3.6.1", + "version": "3.6.2", "source": { "type": "git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git", - "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e" + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/f268ca40d54617c6e06757f83f699775c9b3ff2e", - "reference": "f268ca40d54617c6e06757f83f699775c9b3ff2e", + "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/5e4e71592f69da17871dba6e80dd51bce74a351a", + "reference": "5e4e71592f69da17871dba6e80dd51bce74a351a", "shasum": "" }, "require": { @@ -2451,7 +2451,7 @@ "source": "https://github.com/squizlabs/PHP_CodeSniffer", "wiki": "https://github.com/squizlabs/PHP_CodeSniffer/wiki" }, - "time": "2021-10-11T04:00:11+00:00" + "time": "2021-12-12T21:44:58+00:00" }, { "name": "symfony/polyfill-ctype", From 8626be8c03594f20b4f86a21a4235d5cc3ceac35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 12:15:07 +0100 Subject: [PATCH 06/57] Fix error reported by PHP CS --- tests/integration/src/TestCase.php | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/integration/src/TestCase.php b/tests/integration/src/TestCase.php index e86cbd9..3f52650 100644 --- a/tests/integration/src/TestCase.php +++ b/tests/integration/src/TestCase.php @@ -4,5 +4,4 @@ class TestCase extends \WP_UnitTestCase { - } From 737e5fa5b2c1a736ec8add0b00f3642168c1d0ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 13:32:50 +0100 Subject: [PATCH 07/57] Make integration tests working again Also removes one test that was not useful actually. Note: works with WP 5.9 (= current trunk) only. Fixes #114. --- composer.json | 3 +- composer.lock | 63 ++++++++++++++++++- tests/integration/bin/install-wp-tests.sh | 42 ++++++++++--- tests/integration/phpunit.xml | 1 + tests/integration/src/Bootstrap.php | 2 +- .../src/Cases/Modules/Cron/JobTest.php | 2 +- tests/integration/src/Cases/PluginTest.php | 34 ---------- 7 files changed, 101 insertions(+), 46 deletions(-) delete mode 100644 tests/integration/src/Cases/PluginTest.php diff --git a/composer.json b/composer.json index 2214413..c382c9e 100644 --- a/composer.json +++ b/composer.json @@ -24,7 +24,8 @@ "squizlabs/php_codesniffer": "^3.2", "phpunit/phpunit": "^9.5", "brain/monkey": "^2.3", - "szepeviktor/phpstan-wordpress": "^1.0" + "szepeviktor/phpstan-wordpress": "^1.0", + "yoast/phpunit-polyfills": "^1.0" }, "autoload-dev": { "psr-4": { diff --git a/composer.lock b/composer.lock index 1b7f797..fb1aac7 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "d876424c0f535f1608c0899181c5acd0", + "content-hash": "071e2b4f9f5c1442e93a061f119d1b08", "packages": [ { "name": "composer/installers", @@ -2783,6 +2783,67 @@ "source": "https://github.com/webmozarts/assert/tree/1.10.0" }, "time": "2021-03-09T10:59:23+00:00" + }, + { + "name": "yoast/phpunit-polyfills", + "version": "1.0.3", + "source": { + "type": "git", + "url": "https://github.com/Yoast/PHPUnit-Polyfills.git", + "reference": "5ea3536428944955f969bc764bbe09738e151ada" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Yoast/PHPUnit-Polyfills/zipball/5ea3536428944955f969bc764bbe09738e151ada", + "reference": "5ea3536428944955f969bc764bbe09738e151ada", + "shasum": "" + }, + "require": { + "php": ">=5.4", + "phpunit/phpunit": "^4.8.36 || ^5.7.21 || ^6.0 || ^7.0 || ^8.0 || ^9.0" + }, + "require-dev": { + "yoast/yoastcs": "^2.2.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev", + "dev-develop": "1.x-dev" + } + }, + "autoload": { + "files": [ + "phpunitpolyfills-autoload.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Team Yoast", + "email": "support@yoast.com", + "homepage": "https://yoast.com" + }, + { + "name": "Contributors", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills/graphs/contributors" + } + ], + "description": "Set of polyfills for changed PHPUnit functionality to allow for creating PHPUnit cross-version compatible tests", + "homepage": "https://github.com/Yoast/PHPUnit-Polyfills", + "keywords": [ + "phpunit", + "polyfill", + "testing" + ], + "support": { + "issues": "https://github.com/Yoast/PHPUnit-Polyfills/issues", + "source": "https://github.com/Yoast/PHPUnit-Polyfills" + }, + "time": "2021-11-23T01:37:03+00:00" } ], "aliases": [], diff --git a/tests/integration/bin/install-wp-tests.sh b/tests/integration/bin/install-wp-tests.sh index 1005bf4..ee05775 100755 --- a/tests/integration/bin/install-wp-tests.sh +++ b/tests/integration/bin/install-wp-tests.sh @@ -15,7 +15,7 @@ SKIP_DB_CREATE=${6-false} TMPDIR=${TMPDIR-/tmp} TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//") WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib} -WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress/} +WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress} download() { if [ `which curl` ]; then @@ -62,10 +62,10 @@ install_wp() { mkdir -p $WP_CORE_DIR if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then - mkdir -p $TMPDIR/wordpress-nightly - download https://wordpress.org/nightly-builds/wordpress-latest.zip $TMPDIR/wordpress-nightly/wordpress-nightly.zip - unzip -q $TMPDIR/wordpress-nightly/wordpress-nightly.zip -d $TMPDIR/wordpress-nightly/ - mv $TMPDIR/wordpress-nightly/wordpress/* $WP_CORE_DIR + mkdir -p $TMPDIR/wordpress-trunk + rm -rf $TMPDIR/wordpress-trunk/* + svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress + mv $TMPDIR/wordpress-trunk/wordpress/* $WP_CORE_DIR else if [ $WP_VERSION == 'latest' ]; then local ARCHIVE_NAME='latest' @@ -107,8 +107,9 @@ install_test_suite() { if [ ! -d $WP_TESTS_DIR ]; then # set up testing suite mkdir -p $WP_TESTS_DIR - svn co --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes - svn co --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data + rm -rf $WP_TESTS_DIR/{includes,data} + svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes + svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data fi if [ ! -f wp-tests-config.php ]; then @@ -116,6 +117,7 @@ install_test_suite() { # 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:__DIR__ . '/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 @@ -124,6 +126,23 @@ install_test_suite() { } +recreate_db() { + shopt -s nocasematch + if [[ $1 =~ ^(y|yes)$ ]] + then + mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA + create_db + echo "Recreated the database ($DB_NAME)." + else + echo "Leaving the existing database ($DB_NAME) in place." + fi + shopt -u nocasematch +} + +create_db() { + mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA +} + install_db() { if [ ${SKIP_DB_CREATE} = "true" ]; then @@ -147,7 +166,14 @@ install_db() { fi # create database - mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA + if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ] + then + echo "Reinstalling will delete the existing test database ($DB_NAME)" + read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB + recreate_db $DELETE_EXISTING_DB + else + create_db + fi } install_wp diff --git a/tests/integration/phpunit.xml b/tests/integration/phpunit.xml index cbeacb4..cdff42d 100644 --- a/tests/integration/phpunit.xml +++ b/tests/integration/phpunit.xml @@ -2,6 +2,7 @@ wp_tests_dir . '/includes/functions.php'; tests_add_filter('muplugins_loaded', function () { diff --git a/tests/integration/src/Cases/Modules/Cron/JobTest.php b/tests/integration/src/Cases/Modules/Cron/JobTest.php index ca2db59..d4bee31 100644 --- a/tests/integration/src/Cases/Modules/Cron/JobTest.php +++ b/tests/integration/src/Cases/Modules/Cron/JobTest.php @@ -22,7 +22,7 @@ public function testScheduling() // ...test... $this->assertTrue($job->isScheduled()); - $this->assertInternalType('int', wp_next_scheduled(self::HOOK)); + $this->assertIsInt(wp_next_scheduled(self::HOOK)); // ...and forward the job. return $job; diff --git a/tests/integration/src/Cases/PluginTest.php b/tests/integration/src/Cases/PluginTest.php deleted file mode 100644 index 2936e1d..0000000 --- a/tests/integration/src/Cases/PluginTest.php +++ /dev/null @@ -1,34 +0,0 @@ -bc_security = new Plugin('', $wpdb); - } - - /** - * Test class instances. - */ - public function testInstances() - { - $this->assertInstanceOf(Plugin::class, $this->bc_security); - $this->assertInstanceOf(\wpdb::class, $this->readAttribute($this->bc_security, 'wpdb')); - } -} From dc1bddf0e299c18f06f9d74be42ed5f8320e1c88 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 13:52:00 +0100 Subject: [PATCH 08/57] Improve formatting --- tests/integration/src/Cases/Helpers/HaveIBeenPwnedTest.php | 3 ++- tests/integration/src/Cases/Helpers/IsTest.php | 3 ++- tests/integration/src/Cases/Modules/Cron/JobTest.php | 3 ++- tests/integration/src/Cases/Modules/Hardening/CoreTest.php | 5 ++++- tests/integration/src/TestCase.php | 5 ++++- 5 files changed, 14 insertions(+), 5 deletions(-) diff --git a/tests/integration/src/Cases/Helpers/HaveIBeenPwnedTest.php b/tests/integration/src/Cases/Helpers/HaveIBeenPwnedTest.php index 8b775d9..a10c5a1 100644 --- a/tests/integration/src/Cases/Helpers/HaveIBeenPwnedTest.php +++ b/tests/integration/src/Cases/Helpers/HaveIBeenPwnedTest.php @@ -4,8 +4,9 @@ use BlueChip\Security\Helpers\HaveIBeenPwned; use BlueChip\Security\Tests\Integration\Constants; +use BlueChip\Security\Tests\Integration\TestCase; -class HaveIBeenPwnedTest extends \BlueChip\Security\Tests\Integration\TestCase +class HaveIBeenPwnedTest extends TestCase { /** * Test integration with Pwned Passwords API. diff --git a/tests/integration/src/Cases/Helpers/IsTest.php b/tests/integration/src/Cases/Helpers/IsTest.php index bb42830..7958640 100644 --- a/tests/integration/src/Cases/Helpers/IsTest.php +++ b/tests/integration/src/Cases/Helpers/IsTest.php @@ -4,8 +4,9 @@ use BlueChip\Security\Helpers\Hooks; use BlueChip\Security\Helpers\Is; +use BlueChip\Security\Tests\Integration\TestCase; -class IsTest extends \BlueChip\Security\Tests\Integration\TestCase +class IsTest extends TestCase { /** * Test Is::admin() method and `bc-security/filter:is-admin` filter. diff --git a/tests/integration/src/Cases/Modules/Cron/JobTest.php b/tests/integration/src/Cases/Modules/Cron/JobTest.php index d4bee31..b92d844 100644 --- a/tests/integration/src/Cases/Modules/Cron/JobTest.php +++ b/tests/integration/src/Cases/Modules/Cron/JobTest.php @@ -3,8 +3,9 @@ namespace BlueChip\Security\Tests\Integration\Cases\Modules\Cron; use BlueChip\Security\Modules\Cron; +use BlueChip\Security\Tests\Integration\TestCase; -class JobTest extends \BlueChip\Security\Tests\Integration\TestCase +class JobTest extends TestCase { private const HOOK = 'test-job'; diff --git a/tests/integration/src/Cases/Modules/Hardening/CoreTest.php b/tests/integration/src/Cases/Modules/Hardening/CoreTest.php index 12a1cff..b3bd251 100644 --- a/tests/integration/src/Cases/Modules/Hardening/CoreTest.php +++ b/tests/integration/src/Cases/Modules/Hardening/CoreTest.php @@ -4,11 +4,13 @@ use BlueChip\Security\Modules\Hardening; use BlueChip\Security\Tests\Integration\Constants; +use BlueChip\Security\Tests\Integration\TestCase; -class CoreTest extends \BlueChip\Security\Tests\Integration\TestCase +class CoreTest extends TestCase { /** * Initialize the hardening with either active or non active state.. + * * @param bool $active */ protected function initHardening(bool $active) @@ -22,6 +24,7 @@ protected function initHardening(bool $active) /** * Set up $_POST data necessary to test via \edit_user() function. + * * @param bool $pwned Whether to set weak password (true) or strong password (false). */ protected function setUpUserPostData(bool $pwned = false) diff --git a/tests/integration/src/TestCase.php b/tests/integration/src/TestCase.php index 3f52650..5fa46d9 100644 --- a/tests/integration/src/TestCase.php +++ b/tests/integration/src/TestCase.php @@ -2,6 +2,9 @@ namespace BlueChip\Security\Tests\Integration; -class TestCase extends \WP_UnitTestCase +/** + * Base class for all integration tests + */ +abstract class TestCase extends \WP_UnitTestCase { } From 71abb185ca33508359fe24b7986727910d04f8e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 31 Dec 2021 15:14:51 +0100 Subject: [PATCH 09/57] Raise PHPStan level to 5 --- classes/BlueChip/Security/Admin.php | 4 +- .../Security/Modules/Checklist/AdminPage.php | 3 +- .../Checks/DisplayOfPhpErrorsIsOff.php | 2 +- .../NoAccessToPhpFilesInUploadsDirectory.php | 2 +- .../Security/Modules/Checklist/Manager.php | 38 +++++++++++-------- classes/BlueChip/Security/Plugin.php | 2 +- phpstan.neon | 2 +- 7 files changed, 31 insertions(+), 22 deletions(-) diff --git a/classes/BlueChip/Security/Admin.php b/classes/BlueChip/Security/Admin.php index 243a14c..89bbc06 100644 --- a/classes/BlueChip/Security/Admin.php +++ b/classes/BlueChip/Security/Admin.php @@ -80,11 +80,11 @@ public function makeAdminMenu() // Add (main) menu page add_menu_page( - '', // obsolete as soon as page has subpages + '', // Page title is obsolete as soon as page has subpages. _x('BC Security', 'Dashboard menu item name', 'bc-security'), self::CAPABILITY, $main_page->getSlug(), - '', // obsolete as soon as page has subpages + '__return_empty_string', // Page content is obsolete as soon as page has subpages. Passing an empty string would prevent the callback being registered at all, but it breaks static analysis - see: https://core.trac.wordpress.org/ticket/52539 self::ICON ); diff --git a/classes/BlueChip/Security/Modules/Checklist/AdminPage.php b/classes/BlueChip/Security/Modules/Checklist/AdminPage.php index 709338b..2387b40 100644 --- a/classes/BlueChip/Security/Modules/Checklist/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Checklist/AdminPage.php @@ -2,6 +2,7 @@ namespace BlueChip\Security\Modules\Checklist; +use BlueChip\Security\Core\AssetsManager; use BlueChip\Security\Helpers\AjaxHelper; use BlueChip\Security\Helpers\FormHelper; use BlueChip\Security\Modules\Hardening; @@ -32,7 +33,7 @@ class AdminPage extends \BlueChip\Security\Core\Admin\AbstractPage * @param \BlueChip\Security\Modules\Checklist\AutorunSettings $settings * @param \BlueChip\Security\Core\AssetsManager $assets_manager */ - public function __construct(Manager $checklist_manager, AutorunSettings $settings, \BlueChip\Security\Core\AssetsManager $assets_manager) + public function __construct(Manager $checklist_manager, AutorunSettings $settings, AssetsManager $assets_manager) { $this->page_title = _x('Security Checklist', 'Dashboard page title', 'bc-security'); $this->menu_title = _x('Checklist', 'Dashboard menu item name', 'bc-security'); diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/DisplayOfPhpErrorsIsOff.php b/classes/BlueChip/Security/Modules/Checklist/Checks/DisplayOfPhpErrorsIsOff.php index 6d42ec0..b0edbc9 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/DisplayOfPhpErrorsIsOff.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/DisplayOfPhpErrorsIsOff.php @@ -35,7 +35,7 @@ public function isMeaningful(): bool protected function runInternal(): Checklist\CheckResult { // Craft temporary file name. - $name = \sprintf('bc-security-checklist-test-error-display-%s.php', \md5(\rand())); + $name = \sprintf('bc-security-checklist-test-error-display-%s.php', \md5((string) \rand())); // The file is going to be created in wp-content directory. $path = WP_CONTENT_DIR . '/' . $name; diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/NoAccessToPhpFilesInUploadsDirectory.php b/classes/BlueChip/Security/Modules/Checklist/Checks/NoAccessToPhpFilesInUploadsDirectory.php index 4d7546f..b8e2d8a 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/NoAccessToPhpFilesInUploadsDirectory.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/NoAccessToPhpFilesInUploadsDirectory.php @@ -24,7 +24,7 @@ protected function runInternal(): Checklist\CheckResult $php_file_message = 'It is more secure to not allow PHP files to be accessed from within WordPress uploads directory.'; // Prepare temporary file name and contents. - $name = \sprintf('bc-security-checklist-test-%s.txt', \md5(\rand())); // .txt extension to avoid upload file MIME check killing our test + $name = \sprintf('bc-security-checklist-test-%s.txt', \md5((string) \rand())); // .txt extension to avoid upload file MIME check killing our test $bits = \sprintf('checks[$id] ?? null; + } + + /** * Return list of all implemented checks, optionally filtered. * - * @param array $filters [optional] Extra conditions to filter the list by: class (string), meaningful (boolean), + * @param array $filters [optional] Extra conditions to filter the list by: meaningful (boolean), * monitored (boolean), status (null|boolean). * @return \BlueChip\Security\Modules\Checklist\Check[] */ @@ -116,13 +126,6 @@ public function getChecks(array $filters = []): array { $checks = $this->checks; - if (isset($filters['class'])) { - $class = $filters['class']; - $checks = \array_filter($checks, function (Check $check) use ($class): bool { - return $check instanceof $class; - }); - } - if (isset($filters['meaningful'])) { $is_meaningful = $filters['meaningful']; $checks = \array_filter($checks, function (Check $check) use ($is_meaningful): bool { @@ -155,11 +158,14 @@ public function getChecks(array $filters = []): array */ public function getAdvancedChecks(bool $only_meaningful = true): array { - $filters = ['class' => AdvancedCheck::class]; + $filters = []; if ($only_meaningful) { $filters['meaningful'] = true; } - return $this->getChecks($filters); + + return \array_filter($this->getChecks($filters), function (Check $check): bool { + return $check instanceof AdvancedCheck; + }); } @@ -169,11 +175,14 @@ public function getAdvancedChecks(bool $only_meaningful = true): array */ public function getBasicChecks(bool $only_meaningful = true): array { - $filters = ['class' => BasicCheck::class]; + $filters = []; if ($only_meaningful) { $filters['meaningful'] = true; } - return $this->getChecks($filters); + + return \array_filter($this->getChecks($filters), function (Check $check): bool { + return $check instanceof BasicCheck; + }); } @@ -204,7 +213,7 @@ public function runBasicChecks() } } - if (!empty($issues)) { + if ($issues !== []) { // Trigger an action to report found issues. do_action(Hooks::BASIC_CHECKS_ALERT, $issues); } @@ -224,8 +233,7 @@ public function runCheck() ]); } - $checks = $this->getChecks(); - if (empty($check = $checks[$check_id])) { + if (($check = $this->getCheck($check_id)) === null) { wp_send_json_error([ 'message' => \sprintf(__('Unknown check ID: %s', 'bc-security'), $check_id), ]); diff --git a/classes/BlueChip/Security/Plugin.php b/classes/BlueChip/Security/Plugin.php index 6e9a95a..66c1199 100644 --- a/classes/BlueChip/Security/Plugin.php +++ b/classes/BlueChip/Security/Plugin.php @@ -13,7 +13,7 @@ class Plugin private $modules; /** - * @var \BlueChip\Security\Core\Settings[] Plugin setting objects + * @var array Plugin setting objects */ private $settings; diff --git a/phpstan.neon b/phpstan.neon index d3872d9..5741582 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -2,7 +2,7 @@ includes: - phar://phpstan.phar/conf/bleedingEdge.neon - vendor/szepeviktor/phpstan-wordpress/extension.neon parameters: - level: 2 + level: 5 paths: - %currentWorkingDirectory%/classes/ bootstrapFiles: From ca22b0b72091e6111832ff231fb57e82b0a46bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Thu, 6 Jan 2022 12:50:08 +0100 Subject: [PATCH 10/57] Drop empty bootstrap configuration for PHPUnit --- tests/unit/bootstrap.php | 10 ---------- tests/unit/phpunit.xml | 1 - tests/unit/src/Bootstrap.php | 10 ---------- 3 files changed, 21 deletions(-) delete mode 100644 tests/unit/bootstrap.php delete mode 100644 tests/unit/src/Bootstrap.php diff --git a/tests/unit/bootstrap.php b/tests/unit/bootstrap.php deleted file mode 100644 index d78e909..0000000 --- a/tests/unit/bootstrap.php +++ /dev/null @@ -1,10 +0,0 @@ -run(); diff --git a/tests/unit/phpunit.xml b/tests/unit/phpunit.xml index 61fdd72..f70e394 100644 --- a/tests/unit/phpunit.xml +++ b/tests/unit/phpunit.xml @@ -1,6 +1,5 @@ Date: Thu, 6 Jan 2022 12:50:54 +0100 Subject: [PATCH 11/57] Add type hints to methods in unit test files --- tests/unit/src/Cases/Helpers/IsTest.php | 4 ++-- tests/unit/src/Cases/Helpers/PluginTest.php | 2 +- tests/unit/src/Cases/Modules/Log/EventsManagerTest.php | 2 +- tests/unit/src/Cases/Modules/Log/EventsMonitorTest.php | 8 ++++---- tests/unit/src/Cases/Modules/Log/EventsTest.php | 8 ++++---- tests/unit/src/Cases/Setup/IpAddressTest.php | 6 +++--- tests/unit/src/TestCase.php | 2 ++ 7 files changed, 17 insertions(+), 15 deletions(-) diff --git a/tests/unit/src/Cases/Helpers/IsTest.php b/tests/unit/src/Cases/Helpers/IsTest.php index f6ec4f9..b6457b4 100644 --- a/tests/unit/src/Cases/Helpers/IsTest.php +++ b/tests/unit/src/Cases/Helpers/IsTest.php @@ -12,7 +12,7 @@ class IsTest extends \BlueChip\Security\Tests\Unit\TestCase /** * Ensure that `bc-security/filter:is-admin` fires when Is::admin() method is invoked. */ - public function testIsAdminHookFires() + public function testIsAdminHookFires(): void { Functions\when('user_can')->justReturn(true); @@ -26,7 +26,7 @@ public function testIsAdminHookFires() * Ensure that `bc-security/filter:is-admin` filters return value of Is::admin() and * passes \WP_User instance as its second argument. */ - public function testIsAdminFilter() + public function testIsAdminFilter(): void { $user = \Mockery::mock(\WP_User::class); diff --git a/tests/unit/src/Cases/Helpers/PluginTest.php b/tests/unit/src/Cases/Helpers/PluginTest.php index 1f30347..4f8b9f5 100644 --- a/tests/unit/src/Cases/Helpers/PluginTest.php +++ b/tests/unit/src/Cases/Helpers/PluginTest.php @@ -32,7 +32,7 @@ public function provideWordPressOrgUriData(): array * * @dataProvider provideWordPressOrgUriData */ - public function testHasWordPressOrgUpdateUri(bool $value, string $plugin_basename, array $plugin_data) + public function testHasWordPressOrgUpdateUri(bool $value, string $plugin_basename, array $plugin_data): void { $this->assertSame($value, Plugin::hasWordPressOrgUpdateUri($plugin_basename, $plugin_data)); } diff --git a/tests/unit/src/Cases/Modules/Log/EventsManagerTest.php b/tests/unit/src/Cases/Modules/Log/EventsManagerTest.php index b05d08d..7eb1f5c 100644 --- a/tests/unit/src/Cases/Modules/Log/EventsManagerTest.php +++ b/tests/unit/src/Cases/Modules/Log/EventsManagerTest.php @@ -9,7 +9,7 @@ class EventsManagerTest extends \BlueChip\Security\Tests\Unit\TestCase /** * Ensure that mapping from event ID to event class is sane. */ - public function testMapping() + public function testMapping(): void { $events = Log\EventsManager::getMapping(); diff --git a/tests/unit/src/Cases/Modules/Log/EventsMonitorTest.php b/tests/unit/src/Cases/Modules/Log/EventsMonitorTest.php index 1b5685f..90b6235 100644 --- a/tests/unit/src/Cases/Modules/Log/EventsMonitorTest.php +++ b/tests/unit/src/Cases/Modules/Log/EventsMonitorTest.php @@ -21,7 +21,7 @@ protected function setUp(): void } - public function testBadCookie() + public function testBadCookie(): void { Actions\expectDone(Log\Action::EVENT)->once()->with(\Mockery::type(Log\Events\AuthBadCookie::class)); @@ -29,7 +29,7 @@ public function testBadCookie() } - public function testFailedLogin() + public function testFailedLogin(): void { Actions\expectDone(Log\Action::EVENT)->once()->with(\Mockery::type(Log\Events\LoginFailure::class)); $wp_error = \Mockery::mock(\WP_Error::class); @@ -42,7 +42,7 @@ public function testFailedLogin() } - public function testLoginLockout() + public function testLoginLockout(): void { Actions\expectDone(Log\Action::EVENT)->once()->with(\Mockery::type(Log\Events\LoginLockout::class)); @@ -50,7 +50,7 @@ public function testLoginLockout() } - public function testSuccessfulLogin() + public function testSuccessfulLogin(): void { Actions\expectDone(Log\Action::EVENT)->once()->with(\Mockery::type(Log\Events\LoginSuccessful::class)); diff --git a/tests/unit/src/Cases/Modules/Log/EventsTest.php b/tests/unit/src/Cases/Modules/Log/EventsTest.php index 119594b..ca66c02 100644 --- a/tests/unit/src/Cases/Modules/Log/EventsTest.php +++ b/tests/unit/src/Cases/Modules/Log/EventsTest.php @@ -9,7 +9,7 @@ class EventsTest extends \BlueChip\Security\Tests\Unit\TestCase /** * Ensure that every event type (class) has the necessary constants: ID and LEVEL. */ - public function testConstants() + public function testConstants(): void { $event_classes = Log\EventsManager::getMapping(); @@ -25,7 +25,7 @@ public function testConstants() /** * Ensure that only PSR-4 compliant log levels are reported by events. */ - public function testLogLevels() + public function testLogLevels(): void { $reflection = new \ReflectionClass(\Psr\Log\LogLevel::class); $log_levels = $reflection->getConstants(); @@ -40,7 +40,7 @@ public function testLogLevels() /** * Ensure that event log message references only available context data. */ - public function testLogMessages() + public function testLogMessages(): void { $event_instances = Log\EventsManager::getInstances(); foreach ($event_instances as $event) { @@ -65,7 +65,7 @@ public function testLogMessages() /** * Ensure that there are no context items without label. */ - public function testContextLabels() + public function testContextLabels(): void { $event_instances = Log\EventsManager::getInstances(); foreach ($event_instances as $event) { diff --git a/tests/unit/src/Cases/Setup/IpAddressTest.php b/tests/unit/src/Cases/Setup/IpAddressTest.php index 151e1c6..bcac727 100644 --- a/tests/unit/src/Cases/Setup/IpAddressTest.php +++ b/tests/unit/src/Cases/Setup/IpAddressTest.php @@ -43,7 +43,7 @@ public function provideRemoteAddressGetterData(): array /** * @dataProvider provideRemoteAddressGetterData */ - public function testRemoteAddressGetter($connection_type, $ip_address) + public function testRemoteAddressGetter(string $connection_type, string $ip_address): void { $this->assertSame($ip_address, IpAddress::get($connection_type)); } @@ -63,7 +63,7 @@ public function provideRemoteAddressGetterFallbackData(): array * Test the case when connection type is set to proxy, but there is actually no proxy info. * @dataProvider provideRemoteAddressGetterFallbackData */ - public function testRemoteAddressGetterFallback($connection_type, $ip_address) + public function testRemoteAddressGetterFallback(string $connection_type, string $ip_address): void { // Make sure the requested connection info is empty. unset($_SERVER[$connection_type]); @@ -87,7 +87,7 @@ public function provideRawRemoteAddressGetterData(): array /** * @dataProvider provideRawRemoteAddressGetterData */ - public function testRemoteRawAddressGetter($connection_type, $ip_address) + public function testRemoteRawAddressGetter(string $connection_type, string $ip_address): void { $this->assertSame($ip_address, IpAddress::getRaw($connection_type)); } diff --git a/tests/unit/src/TestCase.php b/tests/unit/src/TestCase.php index ebd08b3..f5c7f41 100644 --- a/tests/unit/src/TestCase.php +++ b/tests/unit/src/TestCase.php @@ -9,6 +9,7 @@ class TestCase extends \PHPUnit\Framework\TestCase // See: https://github.com/Brain-WP/BrainMonkey/issues/39 use \Mockery\Adapter\Phpunit\MockeryPHPUnitIntegration; + protected function setUp(): void { parent::setUp(); @@ -33,6 +34,7 @@ protected function setUp(): void ); } + protected function tearDown(): void { Monkey\tearDown(); From 164b5eabeb6a5c8db9689e96153c5141d22b3060 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Thu, 6 Jan 2022 12:54:48 +0100 Subject: [PATCH 12/57] Sort packages in composer.json --- composer.json | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index c382c9e..3b97e90 100644 --- a/composer.json +++ b/composer.json @@ -10,6 +10,9 @@ "homepage": "https://www.chesio.com" } ], + "config": { + "sort-packages": true + }, "keywords": [ "wordpress", "wordpress-plugin" ], @@ -21,9 +24,9 @@ "composer/installers": "~1.0" }, "require-dev": { - "squizlabs/php_codesniffer": "^3.2", - "phpunit/phpunit": "^9.5", "brain/monkey": "^2.3", + "phpunit/phpunit": "^9.5", + "squizlabs/php_codesniffer": "^3.2", "szepeviktor/phpstan-wordpress": "^1.0", "yoast/phpunit-polyfills": "^1.0" }, From f40daed40fb9dc035d581897a63ba0d7da299aa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Thu, 6 Jan 2022 14:08:22 +0100 Subject: [PATCH 13/57] Update composer.lock --- composer.lock | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/composer.lock b/composer.lock index fb1aac7..c10385f 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "071e2b4f9f5c1442e93a061f119d1b08", + "content-hash": "14732d333b541ebb950c18c218fe20ce", "packages": [ { "name": "composer/installers", @@ -131,6 +131,10 @@ "zend", "zikula" ], + "support": { + "issues": "https://github.com/composer/installers/issues", + "source": "https://github.com/composer/installers/tree/v1.9.0" + }, "funding": [ { "url": "https://packagist.com", From bd150345572779cbc0c52fd0b8724689cca23255 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Thu, 6 Jan 2022 16:15:22 +0100 Subject: [PATCH 14/57] Include site URL in notification emails header --- classes/BlueChip/Security/Modules/Notifications/Mailman.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/classes/BlueChip/Security/Modules/Notifications/Mailman.php b/classes/BlueChip/Security/Modules/Notifications/Mailman.php index 0edc284..76b6534 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Mailman.php +++ b/classes/BlueChip/Security/Modules/Notifications/Mailman.php @@ -49,9 +49,10 @@ private static function formatMessage(array $message): string { $boilerplate_intro = [ \sprintf( - __('This email was sent from your website "%1$s" by BC Security plugin on %2$s at %3$s.'), + __('This email was sent from your website "%1$s" (%2$s) by BC Security plugin on %3$s at %4$s.'), // Blog name must be decoded, see: https://github.com/chesio/bc-security/issues/86 wp_specialchars_decode(get_option('blogname'), ENT_QUOTES), + get_home_url(), wp_date(get_option('date_format')), wp_date(get_option('time_format')) ), From b4b6867bbdffc49100c42ee876c3fea4ab9028fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Fri, 28 Jan 2022 19:08:28 +0100 Subject: [PATCH 15/57] Bump version in develop branch --- bc-security.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bc-security.php b/bc-security.php index 427dc73..4b86cba 100644 --- a/bc-security.php +++ b/bc-security.php @@ -4,7 +4,7 @@ * Plugin Name: BC Security * Plugin URI: https://github.com/chesio/bc-security * Description: Helps keeping WordPress websites secure. - * Version: 0.18.1 + * Version: 0.19.0-dev * Author: Česlav Przywara * Author URI: https://www.chesio.com * Requires PHP: 7.3 From 9ecef2bdb12b1760d82211bd7523eab9bc51b326 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 12:46:10 +0100 Subject: [PATCH 16/57] Remove "Check auth cookies" setting Cookies are now checked always. --- .../Security/Modules/Login/AdminPage.php | 11 -------- .../Security/Modules/Login/Gatekeeper.php | 25 ++++++------------- .../Security/Modules/Login/Settings.php | 4 --- 3 files changed, 8 insertions(+), 32 deletions(-) diff --git a/classes/BlueChip/Security/Modules/Login/AdminPage.php b/classes/BlueChip/Security/Modules/Login/AdminPage.php index d62eb45..22e81bb 100644 --- a/classes/BlueChip/Security/Modules/Login/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Login/AdminPage.php @@ -117,17 +117,6 @@ function () { [ 'append' => __('Enter one username per line.', 'bc-security'), ] ); - // Section: Authentication cookies - $this->addSettingsSection( - 'auth-cookies', - _x('Auth cookies', 'Settings section title', 'bc-security') - ); - $this->addSettingsField( - Settings::CHECK_COOKIES, - __('Check auth cookies', 'bc-security'), - [FormHelper::class, 'printCheckbox'] - ); - // Section: Display generic error message on failed login $this->addSettingsSection( 'generic-error-message', diff --git a/classes/BlueChip/Security/Modules/Login/Gatekeeper.php b/classes/BlueChip/Security/Modules/Login/Gatekeeper.php index efadf31..761f3d7 100644 --- a/classes/BlueChip/Security/Modules/Login/Gatekeeper.php +++ b/classes/BlueChip/Security/Modules/Login/Gatekeeper.php @@ -50,9 +50,7 @@ public function __construct(Settings $settings, string $remote_address, Bookkeep */ public function load() { - if ($this->settings[Settings::CHECK_COOKIES]) { - add_action('plugins_loaded', [$this, 'removeAuthCookieIfIpIsLocked'], 5, 0); - } + add_action('plugins_loaded', [$this, 'removeAuthCookieIfIpIsLocked'], 5, 0); } @@ -72,10 +70,9 @@ public function init() add_action('wp_login_failed', [$this, 'handleFailedLogin'], 100, 1); - if ($this->settings[Settings::CHECK_COOKIES]) { - add_action('auth_cookie_bad_username', [$this, 'handleBadCookie'], 10, 1); - add_action('auth_cookie_bad_hash', [$this, 'handleBadCookie'], 10, 1); - } + // Check authentication cookies: + add_action('auth_cookie_bad_username', [$this, 'handleBadCookie'], 10, 1); + add_action('auth_cookie_bad_hash', [$this, 'handleBadCookie'], 10, 1); } @@ -214,21 +211,15 @@ public function removeAuthCookieIfIpIsLocked() //// Private and protected methods /** - * Clear all WordPress authentication cookies (also for current session). + * Clear all WordPress authentication cookies (also for current request). */ protected function clearAuthCookie() { wp_clear_auth_cookie(); - if (!empty($_COOKIE[AUTH_COOKIE])) { - $_COOKIE[AUTH_COOKIE] = ''; - } - if (!empty($_COOKIE[SECURE_AUTH_COOKIE])) { - $_COOKIE[SECURE_AUTH_COOKIE] = ''; - } - if (!empty($_COOKIE[LOGGED_IN_COOKIE])) { - $_COOKIE[LOGGED_IN_COOKIE] = ''; - } + unset($_COOKIE[AUTH_COOKIE]); + unset($_COOKIE[SECURE_AUTH_COOKIE]); + unset($_COOKIE[LOGGED_IN_COOKIE]); } diff --git a/classes/BlueChip/Security/Modules/Login/Settings.php b/classes/BlueChip/Security/Modules/Login/Settings.php index a003e84..000ce21 100644 --- a/classes/BlueChip/Security/Modules/Login/Settings.php +++ b/classes/BlueChip/Security/Modules/Login/Settings.php @@ -22,9 +22,6 @@ class Settings extends \BlueChip\Security\Core\Settings /** int: Reset failed attempts after this many days [3] */ public const RESET_TIMEOUT = 'reset_timeout'; - /** bool: Also limit malformed/forged cookies? [Yes] */ - public const CHECK_COOKIES = 'check_cookies'; - /** array: List of usernames that trigger long lockout immediately when used to log in [empty] */ public const USERNAME_BLACKLIST = 'username_blacklist'; @@ -41,7 +38,6 @@ class Settings extends \BlueChip\Security\Core\Settings self::LONG_LOCKOUT_AFTER => 20, self::LONG_LOCKOUT_DURATION => 24, self::RESET_TIMEOUT => 3, - self::CHECK_COOKIES => true, self::USERNAME_BLACKLIST => [], self::GENERIC_LOGIN_ERROR_MESSAGE => false, ]; From bf7f53cf025b69caca35a06195dae3a799a13901 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 12:46:53 +0100 Subject: [PATCH 17/57] Add allowed plugins to composer.json --- composer.json | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3b97e90..3228c51 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,10 @@ } ], "config": { - "sort-packages": true + "sort-packages": true, + "allow-plugins": { + "composer/installers": true + } }, "keywords": [ "wordpress", "wordpress-plugin" From 9595fb8406dc8cf94c36e78a344ad036ccc24cff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 12:54:26 +0100 Subject: [PATCH 18/57] Update php-stubs/wordpress-stubs --- composer.lock | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/composer.lock b/composer.lock index c10385f..756378d 100644 --- a/composer.lock +++ b/composer.lock @@ -683,24 +683,27 @@ }, { "name": "php-stubs/wordpress-stubs", - "version": "v5.8.2", + "version": "v5.9.0", "source": { "type": "git", "url": "https://github.com/php-stubs/wordpress-stubs.git", - "reference": "67fd773742b7be5b4463f40318b0b4890a07033b" + "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/67fd773742b7be5b4463f40318b0b4890a07033b", - "reference": "67fd773742b7be5b4463f40318b0b4890a07033b", + "url": "https://api.github.com/repos/php-stubs/wordpress-stubs/zipball/0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", + "reference": "0fa8dd9a1bd2a1b60e85afc6c798fca1f599cc1b", "shasum": "" }, "replace": { "giacocorsiglia/wordpress-stubs": "*" }, "require-dev": { - "giacocorsiglia/stubs-generator": "^0.5.0", - "php": "~7.1" + "nikic/php-parser": "< 4.12.0", + "php": "~7.3 || ~8.0", + "php-stubs/generator": "^0.8.0", + "phpdocumentor/reflection-docblock": "^5.3", + "phpstan/phpstan": "^1.2" }, "suggest": { "paragonie/sodium_compat": "Pure PHP implementation of libsodium", @@ -721,9 +724,9 @@ ], "support": { "issues": "https://github.com/php-stubs/wordpress-stubs/issues", - "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.8.2" + "source": "https://github.com/php-stubs/wordpress-stubs/tree/v5.9.0" }, - "time": "2021-11-11T13:57:00+00:00" + "time": "2022-01-26T00:27:45+00:00" }, { "name": "phpdocumentor/reflection-common", @@ -2859,5 +2862,5 @@ "php": "^7.3 || ^8.0" }, "platform-dev": [], - "plugin-api-version": "2.1.0" + "plugin-api-version": "2.2.0" } From d32f338221a397a13dd749080637230c621dceea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 12:55:11 +0100 Subject: [PATCH 19/57] Update phpstan/phpstan --- composer.lock | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/composer.lock b/composer.lock index 756378d..c49fd3d 100644 --- a/composer.lock +++ b/composer.lock @@ -957,16 +957,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.2.0", + "version": "1.4.6", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee" + "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", - "reference": "cbe085f9fdead5b6d62e4c022ca52dc9427a10ee", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/8a7761f1c520e0dad6e04d862fdc697445457cfe", + "reference": "8a7761f1c520e0dad6e04d862fdc697445457cfe", "shasum": "" }, "require": { @@ -982,7 +982,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -997,7 +997,7 @@ "description": "PHPStan - PHP Static Analysis Tool", "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.2.0" + "source": "https://github.com/phpstan/phpstan/tree/1.4.6" }, "funding": [ { @@ -1017,7 +1017,7 @@ "type": "tidelift" } ], - "time": "2021-11-18T14:09:01+00:00" + "time": "2022-02-06T12:56:13+00:00" }, { "name": "phpunit/php-code-coverage", From e3aa3b2472ade0daf0344c1b71b242120e0f1fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 16:51:57 +0100 Subject: [PATCH 20/57] Update PHPUnit including dependencies --- composer.lock | 80 +++++++++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 40 deletions(-) diff --git a/composer.lock b/composer.lock index c49fd3d..28972f4 100644 --- a/composer.lock +++ b/composer.lock @@ -473,9 +473,6 @@ "require": { "php": "^7.1 || ^8.0" }, - "replace": { - "myclabs/deep-copy": "self.version" - }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", @@ -483,12 +480,12 @@ }, "type": "library", "autoload": { - "psr-4": { - "DeepCopy\\": "src/DeepCopy/" - }, "files": [ "src/DeepCopy/deep_copy.php" - ] + ], + "psr-4": { + "DeepCopy\\": "src/DeepCopy/" + } }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -632,16 +629,16 @@ }, { "name": "phar-io/version", - "version": "3.1.0", + "version": "3.1.1", "source": { "type": "git", "url": "https://github.com/phar-io/version.git", - "reference": "bae7c545bef187884426f042434e561ab1ddb182" + "reference": "15a90844ad40f127afd244c0cad228de2a80052a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phar-io/version/zipball/bae7c545bef187884426f042434e561ab1ddb182", - "reference": "bae7c545bef187884426f042434e561ab1ddb182", + "url": "https://api.github.com/repos/phar-io/version/zipball/15a90844ad40f127afd244c0cad228de2a80052a", + "reference": "15a90844ad40f127afd244c0cad228de2a80052a", "shasum": "" }, "require": { @@ -677,9 +674,9 @@ "description": "Library for handling version information and constraints", "support": { "issues": "https://github.com/phar-io/version/issues", - "source": "https://github.com/phar-io/version/tree/3.1.0" + "source": "https://github.com/phar-io/version/tree/3.1.1" }, - "time": "2021-02-23T14:00:09+00:00" + "time": "2022-02-07T21:56:48+00:00" }, { "name": "php-stubs/wordpress-stubs", @@ -840,16 +837,16 @@ }, { "name": "phpdocumentor/type-resolver", - "version": "1.5.1", + "version": "1.6.0", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae" + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/a12f7e301eb7258bb68acd89d4aefa05c2906cae", - "reference": "a12f7e301eb7258bb68acd89d4aefa05c2906cae", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/93ebd0014cab80c4ea9f5e297ea48672f1b87706", + "reference": "93ebd0014cab80c4ea9f5e297ea48672f1b87706", "shasum": "" }, "require": { @@ -884,9 +881,9 @@ "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", "support": { "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.5.1" + "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.0" }, - "time": "2021-10-02T14:08:47+00:00" + "time": "2022-01-04T19:58:01+00:00" }, { "name": "phpspec/prophecy", @@ -1339,16 +1336,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.11", + "version": "9.5.13", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "2406855036db1102126125537adb1406f7242fdd" + "reference": "597cb647654ede35e43b137926dfdfef0fb11743" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/2406855036db1102126125537adb1406f7242fdd", - "reference": "2406855036db1102126125537adb1406f7242fdd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/597cb647654ede35e43b137926dfdfef0fb11743", + "reference": "597cb647654ede35e43b137926dfdfef0fb11743", "shasum": "" }, "require": { @@ -1399,11 +1396,11 @@ } }, "autoload": { - "classmap": [ - "src/" - ], "files": [ "src/Framework/Assert/Functions.php" + ], + "classmap": [ + "src/" ] }, "notification-url": "https://packagist.org/downloads/", @@ -1426,7 +1423,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.11" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.13" }, "funding": [ { @@ -1438,7 +1435,7 @@ "type": "github" } ], - "time": "2021-12-25T07:07:57+00:00" + "time": "2022-01-24T07:33:35+00:00" }, { "name": "sebastian/cli-parser", @@ -1946,16 +1943,16 @@ }, { "name": "sebastian/global-state", - "version": "5.0.3", + "version": "5.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49" + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/23bd5951f7ff26f12d4e3242864df3e08dec4e49", - "reference": "23bd5951f7ff26f12d4e3242864df3e08dec4e49", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/0ca8db5a5fc9c8646244e629625ac486fa286bf2", + "reference": "0ca8db5a5fc9c8646244e629625ac486fa286bf2", "shasum": "" }, "require": { @@ -1998,7 +1995,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/global-state/issues", - "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.3" + "source": "https://github.com/sebastianbergmann/global-state/tree/5.0.5" }, "funding": [ { @@ -2006,7 +2003,7 @@ "type": "github" } ], - "time": "2021-06-11T13:31:12+00:00" + "time": "2022-02-14T08:28:10+00:00" }, { "name": "sebastian/lines-of-code", @@ -2462,21 +2459,24 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.23.0", + "version": "v1.24.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" + "reference": "30885182c981ab175d4d034db0f6f469898070ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", - "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/30885182c981ab175d4d034db0f6f469898070ab", + "reference": "30885182c981ab175d4d034db0f6f469898070ab", "shasum": "" }, "require": { "php": ">=7.1" }, + "provide": { + "ext-ctype": "*" + }, "suggest": { "ext-ctype": "For best performance" }, @@ -2521,7 +2521,7 @@ "portable" ], "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.23.0" + "source": "https://github.com/symfony/polyfill-ctype/tree/v1.24.0" }, "funding": [ { @@ -2537,7 +2537,7 @@ "type": "tidelift" } ], - "time": "2021-02-19T12:13:01+00:00" + "time": "2021-10-20T20:35:02+00:00" }, { "name": "symfony/polyfill-php73", From 2a1330cb3dac03699d1e862cb2c8ea19b2e52d8c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Tue, 15 Feb 2022 16:57:57 +0100 Subject: [PATCH 21/57] Properly check result of call to of wp_upload_dir() --- .../Modules/Checklist/Checks/DirectoryListingDisabled.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/classes/BlueChip/Security/Modules/Checklist/Checks/DirectoryListingDisabled.php b/classes/BlueChip/Security/Modules/Checklist/Checks/DirectoryListingDisabled.php index 319f68a..bdce16d 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Checks/DirectoryListingDisabled.php +++ b/classes/BlueChip/Security/Modules/Checklist/Checks/DirectoryListingDisabled.php @@ -22,7 +22,7 @@ public function __construct() protected function runInternal(): Checklist\CheckResult { $upload_paths = wp_upload_dir(); - if (!isset($upload_paths['baseurl'])) { + if ($upload_paths['error'] !== false) { return new Checklist\CheckResult(null, esc_html__('BC Security has failed to determine whether directory listing is disabled.', 'bc-security')); } From ad60ab76a1f16e839b062cb36616148ed9669db1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 14:24:45 +0100 Subject: [PATCH 22/57] Use short array notation in Psr/Log classes --- classes/Psr/Log/AbstractLogger.php | 16 ++++++++-------- classes/Psr/Log/LoggerInterface.php | 18 +++++++++--------- classes/Psr/Log/LoggerTrait.php | 18 +++++++++--------- classes/Psr/Log/NullLogger.php | 2 +- 4 files changed, 27 insertions(+), 27 deletions(-) diff --git a/classes/Psr/Log/AbstractLogger.php b/classes/Psr/Log/AbstractLogger.php index 90e721a..6fe7505 100644 --- a/classes/Psr/Log/AbstractLogger.php +++ b/classes/Psr/Log/AbstractLogger.php @@ -19,7 +19,7 @@ abstract class AbstractLogger implements LoggerInterface * * @return void */ - public function emergency($message, array $context = array()) + public function emergency($message, array $context = []) { $this->log(LogLevel::EMERGENCY, $message, $context); } @@ -35,7 +35,7 @@ public function emergency($message, array $context = array()) * * @return void */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { $this->log(LogLevel::ALERT, $message, $context); } @@ -50,7 +50,7 @@ public function alert($message, array $context = array()) * * @return void */ - public function critical($message, array $context = array()) + public function critical($message, array $context = []) { $this->log(LogLevel::CRITICAL, $message, $context); } @@ -64,7 +64,7 @@ public function critical($message, array $context = array()) * * @return void */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { $this->log(LogLevel::ERROR, $message, $context); } @@ -80,7 +80,7 @@ public function error($message, array $context = array()) * * @return void */ - public function warning($message, array $context = array()) + public function warning($message, array $context = []) { $this->log(LogLevel::WARNING, $message, $context); } @@ -93,7 +93,7 @@ public function warning($message, array $context = array()) * * @return void */ - public function notice($message, array $context = array()) + public function notice($message, array $context = []) { $this->log(LogLevel::NOTICE, $message, $context); } @@ -108,7 +108,7 @@ public function notice($message, array $context = array()) * * @return void */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { $this->log(LogLevel::INFO, $message, $context); } @@ -121,7 +121,7 @@ public function info($message, array $context = array()) * * @return void */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { $this->log(LogLevel::DEBUG, $message, $context); } diff --git a/classes/Psr/Log/LoggerInterface.php b/classes/Psr/Log/LoggerInterface.php index 5ea7243..019c2a8 100644 --- a/classes/Psr/Log/LoggerInterface.php +++ b/classes/Psr/Log/LoggerInterface.php @@ -27,7 +27,7 @@ interface LoggerInterface * * @return void */ - public function emergency($message, array $context = array()); + public function emergency($message, array $context = []); /** * Action must be taken immediately. @@ -40,7 +40,7 @@ public function emergency($message, array $context = array()); * * @return void */ - public function alert($message, array $context = array()); + public function alert($message, array $context = []); /** * Critical conditions. @@ -52,7 +52,7 @@ public function alert($message, array $context = array()); * * @return void */ - public function critical($message, array $context = array()); + public function critical($message, array $context = []); /** * Runtime errors that do not require immediate action but should typically @@ -63,7 +63,7 @@ public function critical($message, array $context = array()); * * @return void */ - public function error($message, array $context = array()); + public function error($message, array $context = []); /** * Exceptional occurrences that are not errors. @@ -76,7 +76,7 @@ public function error($message, array $context = array()); * * @return void */ - public function warning($message, array $context = array()); + public function warning($message, array $context = []); /** * Normal but significant events. @@ -86,7 +86,7 @@ public function warning($message, array $context = array()); * * @return void */ - public function notice($message, array $context = array()); + public function notice($message, array $context = []); /** * Interesting events. @@ -98,7 +98,7 @@ public function notice($message, array $context = array()); * * @return void */ - public function info($message, array $context = array()); + public function info($message, array $context = []); /** * Detailed debug information. @@ -108,7 +108,7 @@ public function info($message, array $context = array()); * * @return void */ - public function debug($message, array $context = array()); + public function debug($message, array $context = []); /** * Logs with an arbitrary level. @@ -119,5 +119,5 @@ public function debug($message, array $context = array()); * * @return void */ - public function log($level, $message, array $context = array()); + public function log($level, $message, array $context = []); } diff --git a/classes/Psr/Log/LoggerTrait.php b/classes/Psr/Log/LoggerTrait.php index 867225d..5bc74dc 100644 --- a/classes/Psr/Log/LoggerTrait.php +++ b/classes/Psr/Log/LoggerTrait.php @@ -20,7 +20,7 @@ trait LoggerTrait * * @return void */ - public function emergency($message, array $context = array()) + public function emergency($message, array $context = []) { $this->log(LogLevel::EMERGENCY, $message, $context); } @@ -36,7 +36,7 @@ public function emergency($message, array $context = array()) * * @return void */ - public function alert($message, array $context = array()) + public function alert($message, array $context = []) { $this->log(LogLevel::ALERT, $message, $context); } @@ -51,7 +51,7 @@ public function alert($message, array $context = array()) * * @return void */ - public function critical($message, array $context = array()) + public function critical($message, array $context = []) { $this->log(LogLevel::CRITICAL, $message, $context); } @@ -65,7 +65,7 @@ public function critical($message, array $context = array()) * * @return void */ - public function error($message, array $context = array()) + public function error($message, array $context = []) { $this->log(LogLevel::ERROR, $message, $context); } @@ -81,7 +81,7 @@ public function error($message, array $context = array()) * * @return void */ - public function warning($message, array $context = array()) + public function warning($message, array $context = []) { $this->log(LogLevel::WARNING, $message, $context); } @@ -94,7 +94,7 @@ public function warning($message, array $context = array()) * * @return void */ - public function notice($message, array $context = array()) + public function notice($message, array $context = []) { $this->log(LogLevel::NOTICE, $message, $context); } @@ -109,7 +109,7 @@ public function notice($message, array $context = array()) * * @return void */ - public function info($message, array $context = array()) + public function info($message, array $context = []) { $this->log(LogLevel::INFO, $message, $context); } @@ -122,7 +122,7 @@ public function info($message, array $context = array()) * * @return void */ - public function debug($message, array $context = array()) + public function debug($message, array $context = []) { $this->log(LogLevel::DEBUG, $message, $context); } @@ -136,5 +136,5 @@ public function debug($message, array $context = array()) * * @return void */ - abstract public function log($level, $message, array $context = array()); + abstract public function log($level, $message, array $context = []); } diff --git a/classes/Psr/Log/NullLogger.php b/classes/Psr/Log/NullLogger.php index d8cd682..abb6b53 100644 --- a/classes/Psr/Log/NullLogger.php +++ b/classes/Psr/Log/NullLogger.php @@ -21,7 +21,7 @@ class NullLogger extends AbstractLogger * * @return void */ - public function log($level, $message, array $context = array()) + public function log($level, $message, array $context = []) { // noop } From 81733571604ba15c8432c34fb2c8c3548027475c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 14:57:43 +0100 Subject: [PATCH 23/57] Add void return types where missing --- classes/BlueChip/Security/Admin.php | 4 ++-- .../Security/Core/Admin/AbstractPage.php | 8 ++++---- .../Security/Core/Admin/CountablePage.php | 4 ++-- .../Security/Core/Admin/ListingPage.php | 6 +++--- .../Security/Core/Admin/PageWithAssets.php | 6 +++--- .../Security/Core/Admin/SettingsPage.php | 20 +++++++++---------- classes/BlueChip/Security/Core/ListTable.php | 4 +++- classes/BlueChip/Security/Core/Settings.php | 6 +++--- .../Security/Helpers/AdminNotices.php | 2 +- .../BlueChip/Security/Helpers/AjaxHelper.php | 4 ++-- .../BlueChip/Security/Helpers/FormHelper.php | 14 ++++++------- .../BlueChip/Security/Helpers/Transients.php | 2 +- .../BlueChip/Security/Modules/Activable.php | 4 ++-- .../Security/Modules/Checklist/AdminPage.php | 18 ++++++++--------- .../Modules/Checklist/AdvancedCheck.php | 2 +- .../Security/Modules/Checklist/Manager.php | 8 ++++---- .../Security/Modules/Cron/Manager.php | 4 ++-- .../Security/Modules/Hardening/AdminPage.php | 6 +++--- .../Security/Modules/Hardening/Core.php | 14 ++++++------- .../Security/Modules/Initializable.php | 2 +- .../BlueChip/Security/Modules/Installable.php | 4 ++-- .../Modules/IpBlacklist/AdminPage.php | 20 +++++++++---------- .../Security/Modules/IpBlacklist/Bouncer.php | 8 ++++---- .../Modules/IpBlacklist/ListTable.php | 6 ++++-- .../Security/Modules/IpBlacklist/Manager.php | 6 +++--- .../BlueChip/Security/Modules/Loadable.php | 2 +- .../Security/Modules/Log/AdminPage.php | 8 ++++---- .../Security/Modules/Log/EventsMonitor.php | 12 +++++------ .../Security/Modules/Log/ListTable.php | 2 ++ .../BlueChip/Security/Modules/Log/Logger.php | 12 +++++------ .../Security/Modules/Login/AdminPage.php | 6 +++--- .../Security/Modules/Login/Bookkeeper.php | 4 ++-- .../Security/Modules/Login/Gatekeeper.php | 14 ++++++------- .../Modules/Notifications/AdminPage.php | 6 +++--- .../Modules/Notifications/Watchman.php | 20 +++++++++---------- .../Services/ReverseDnsLookup/Resolver.php | 10 +++++----- .../Security/Modules/Tools/AdminPage.php | 18 ++++++++--------- classes/BlueChip/Security/Plugin.php | 10 +++++----- classes/BlueChip/Security/Setup/AdminPage.php | 10 +++++----- 39 files changed, 161 insertions(+), 155 deletions(-) diff --git a/classes/BlueChip/Security/Admin.php b/classes/BlueChip/Security/Admin.php index 89bbc06..783d853 100644 --- a/classes/BlueChip/Security/Admin.php +++ b/classes/BlueChip/Security/Admin.php @@ -55,7 +55,7 @@ public function addPage(Core\Admin\AbstractPage $page): self /** * @action https://developer.wordpress.org/reference/hooks/admin_init/ */ - public function initAdminPages() + public function initAdminPages(): void { foreach ($this->pages as $page) { $page->initPage(); @@ -68,7 +68,7 @@ public function initAdminPages() * * @action https://developer.wordpress.org/reference/hooks/admin_menu/ */ - public function makeAdminMenu() + public function makeAdminMenu(): void { if (empty($this->pages)) { // No pages registered = no pages (no menu) to show. diff --git a/classes/BlueChip/Security/Core/Admin/AbstractPage.php b/classes/BlueChip/Security/Core/Admin/AbstractPage.php index 20c4b1c..81660e6 100644 --- a/classes/BlueChip/Security/Core/Admin/AbstractPage.php +++ b/classes/BlueChip/Security/Core/Admin/AbstractPage.php @@ -31,7 +31,7 @@ abstract class AbstractPage /** * Output page contents. */ - abstract public function printContents(); + abstract public function printContents(): void; /** @@ -87,7 +87,7 @@ public static function getPageUrl(): string * * @param string $page_hook */ - public function setPageHook(string $page_hook) + public function setPageHook(string $page_hook): void { add_action('load-' . $page_hook, [$this, 'loadPage']); } @@ -96,7 +96,7 @@ public function setPageHook(string $page_hook) /** * Run on admin initialization (in `admin_init` hook). */ - public function initPage() + public function initPage(): void { // By default do nothing. } @@ -107,7 +107,7 @@ public function initPage() * * @action https://developer.wordpress.org/reference/hooks/load-page_hook/ */ - public function loadPage() + public function loadPage(): void { // By default do nothing. } diff --git a/classes/BlueChip/Security/Core/Admin/CountablePage.php b/classes/BlueChip/Security/Core/Admin/CountablePage.php index 9b50154..c7b5948 100644 --- a/classes/BlueChip/Security/Core/Admin/CountablePage.php +++ b/classes/BlueChip/Security/Core/Admin/CountablePage.php @@ -18,7 +18,7 @@ trait CountablePage * * @param \BlueChip\Security\Modules\Countable $counter */ - protected function setCounter(\BlueChip\Security\Modules\Countable $counter) + protected function setCounter(\BlueChip\Security\Modules\Countable $counter): void { $this->counter = $counter; } @@ -27,7 +27,7 @@ protected function setCounter(\BlueChip\Security\Modules\Countable $counter) /** * Reset count(er). */ - protected function resetCount() + protected function resetCount(): void { $user = wp_get_current_user(); // Update $user's last view time for this page. diff --git a/classes/BlueChip/Security/Core/Admin/ListingPage.php b/classes/BlueChip/Security/Core/Admin/ListingPage.php index a524eaa..ee9de5b 100644 --- a/classes/BlueChip/Security/Core/Admin/ListingPage.php +++ b/classes/BlueChip/Security/Core/Admin/ListingPage.php @@ -15,7 +15,7 @@ trait ListingPage private $per_page_option_name; - abstract protected function initListTable(); + abstract protected function initListTable(): void; /** @@ -23,7 +23,7 @@ abstract protected function initListTable(); * * @param string $option_name */ - private function setPerPageOption(string $option_name) + private function setPerPageOption(string $option_name): void { $this->per_page_option_name = $option_name; @@ -36,7 +36,7 @@ private function setPerPageOption(string $option_name) /** * @link https://developer.wordpress.org/reference/functions/add_screen_option/ */ - private function addPerPageOption() + private function addPerPageOption(): void { add_screen_option('per_page', [ 'label' => __('Records', 'bc-security'), diff --git a/classes/BlueChip/Security/Core/Admin/PageWithAssets.php b/classes/BlueChip/Security/Core/Admin/PageWithAssets.php index 7a0b63c..a05fd71 100644 --- a/classes/BlueChip/Security/Core/Admin/PageWithAssets.php +++ b/classes/BlueChip/Security/Core/Admin/PageWithAssets.php @@ -15,7 +15,7 @@ trait PageWithAssets /** * @param \BlueChip\Security\Core\AssetsManager $assets_manager */ - protected function useAssetsManager(AssetsManager $assets_manager) + protected function useAssetsManager(AssetsManager $assets_manager): void { $this->assets_manager = $assets_manager; } @@ -24,7 +24,7 @@ protected function useAssetsManager(AssetsManager $assets_manager) /** * @param array $assets JS assets to enqueue in [ handle => filename ] format. */ - protected function enqueueJsAssets(array $assets) + protected function enqueueJsAssets(array $assets): void { add_action('admin_enqueue_scripts', function () use ($assets) { foreach ($assets as $handle => $filename) { @@ -43,7 +43,7 @@ protected function enqueueJsAssets(array $assets) /** * @param array $assets CSS assets to enqueue in [ handle => filename ] format. */ - protected function enqueueCssAssets(array $assets) + protected function enqueueCssAssets(array $assets): void { add_action('admin_enqueue_scripts', function () use ($assets) { foreach ($assets as $handle => $filename) { diff --git a/classes/BlueChip/Security/Core/Admin/SettingsPage.php b/classes/BlueChip/Security/Core/Admin/SettingsPage.php index 2271c89..af0805f 100644 --- a/classes/BlueChip/Security/Core/Admin/SettingsPage.php +++ b/classes/BlueChip/Security/Core/Admin/SettingsPage.php @@ -38,7 +38,7 @@ trait SettingsPage * * @param \BlueChip\Security\Core\Settings $settings */ - protected function useSettings(\BlueChip\Security\Core\Settings $settings) + protected function useSettings(\BlueChip\Security\Core\Settings $settings): void { // Remember the settings. $this->settings = $settings; @@ -50,7 +50,7 @@ protected function useSettings(\BlueChip\Security\Core\Settings $settings) /** * Display settings errors via admin notices. */ - public function displaySettingsErrors() + public function displaySettingsErrors(): void { add_action('admin_notices', 'settings_errors'); } @@ -59,7 +59,7 @@ public function displaySettingsErrors() /** * Register setting. */ - public function registerSettings() + public function registerSettings(): void { register_setting($this->option_group, $this->option_name, [$this->settings, 'sanitize']); } @@ -68,7 +68,7 @@ public function registerSettings() /** * Unregister setting. */ - public function unregisterSettings() + public function unregisterSettings(): void { unregister_setting($this->option_group, $this->option_name); } @@ -81,7 +81,7 @@ public function unregisterSettings() * of SETTINGS_* constants as $page. * @param string $page */ - public function setSettingsPage(string $page) + public function setSettingsPage(string $page): void { $this->recent_page = $page; } @@ -118,7 +118,7 @@ protected function getFieldBaseProperties(string $key, $value = null): array * @param string $title * @param callable|null $callback [optional] */ - public function addSettingsSection(string $section, string $title, ?callable $callback = null) + public function addSettingsSection(string $section, string $title, ?callable $callback = null): void { if (!\is_string($this->recent_page)) { _doing_it_wrong(__METHOD__, 'No recent page set yet!', '0.1.0'); @@ -142,7 +142,7 @@ public function addSettingsSection(string $section, string $title, ?callable $ca * @param callable $callback Callback that produces form input for the field * @param array $args [Optional] Any extra arguments for $callback function */ - public function addSettingsField(string $key, string $title, callable $callback, array $args = []) + public function addSettingsField(string $key, string $title, callable $callback, array $args = []): void { if (!\is_string($this->recent_page)) { _doing_it_wrong(__METHOD__, 'No recent page set yet!', '0.1.0'); @@ -170,7 +170,7 @@ public function addSettingsField(string $key, string $title, callable $callback, /** * Output nonce, action and other hidden fields. */ - public function printSettingsFields() + public function printSettingsFields(): void { settings_fields($this->option_group); } @@ -179,7 +179,7 @@ public function printSettingsFields() /** * Output visible form fields. */ - public function printSettingsSections() + public function printSettingsSections(): void { if (!\is_string($this->recent_page)) { _doing_it_wrong(__METHOD__, 'No recent page set!', '0.1.0'); @@ -193,7 +193,7 @@ public function printSettingsSections() /** * Output form for settings manipulation. */ - protected function printSettingsForm() + protected function printSettingsForm(): void { echo '
'; diff --git a/classes/BlueChip/Security/Core/ListTable.php b/classes/BlueChip/Security/Core/ListTable.php index 4def270..d8f7da8 100644 --- a/classes/BlueChip/Security/Core/ListTable.php +++ b/classes/BlueChip/Security/Core/ListTable.php @@ -80,7 +80,7 @@ public function __construct(string $url, string $per_page_option_name, array $ar * @param string $single The text to be used in notice if action affected single item. * @param string $plural The text to be used in notice if action affected multiple items. */ - protected function displayNotice(string $action, string $single, string $plural) + protected function displayNotice(string $action, string $single, string $plural): void { // Have any items been affected by given action? $result = \filter_input(INPUT_GET, $action, FILTER_VALIDATE_INT); @@ -162,6 +162,8 @@ public function formatDateAndTime(string $datetime): string /** * Output "no items" message. + * + * @return void */ public function no_items() // phpcs:ignore { diff --git a/classes/BlueChip/Security/Core/Settings.php b/classes/BlueChip/Security/Core/Settings.php index 0d45340..6fe50b8 100644 --- a/classes/BlueChip/Security/Core/Settings.php +++ b/classes/BlueChip/Security/Core/Settings.php @@ -67,7 +67,7 @@ public function __get(string $name) * @param string $name * @param mixed $value */ - public function __set(string $name, $value) + public function __set(string $name, $value): void { if (isset($this->data[$name])) { $this->update($name, $value); @@ -316,7 +316,7 @@ protected function update(string $name, $value): bool * * @param callable $callback Callback that accepts up to three parameters: $old_value, $value, $option_name. */ - public function addUpdateHook(callable $callback) + public function addUpdateHook(callable $callback): void { add_action("update_option_{$this->option_name}", [$this, 'updateOption'], 10, 2); add_action("update_option_{$this->option_name}", $callback, 10, 3); @@ -328,7 +328,7 @@ public function addUpdateHook(callable $callback) * @param array $old_value * @param array $new_value */ - public function updateOption(array $old_value, array $new_value) + public function updateOption(array $old_value, array $new_value): void { $this->data = $new_value; } diff --git a/classes/BlueChip/Security/Helpers/AdminNotices.php b/classes/BlueChip/Security/Helpers/AdminNotices.php index 7c51aba..8eb89e6 100644 --- a/classes/BlueChip/Security/Helpers/AdminNotices.php +++ b/classes/BlueChip/Security/Helpers/AdminNotices.php @@ -22,7 +22,7 @@ abstract class AdminNotices * @param bool $is_dismissible [optional] Should the notice be dismissible? Default is true. * @param bool $escape_html [optional] Should the content of message be HTML escaped? Default is true. */ - public static function add($message, string $type = self::INFO, bool $is_dismissible = true, bool $escape_html = true) + public static function add($message, string $type = self::INFO, bool $is_dismissible = true, bool $escape_html = true): void { $classes = \implode(' ', \array_filter(['notice', $type, $is_dismissible ? 'is-dismissible' : ''])); add_action('admin_notices', function () use ($message, $classes, $escape_html) { diff --git a/classes/BlueChip/Security/Helpers/AjaxHelper.php b/classes/BlueChip/Security/Helpers/AjaxHelper.php index f871e09..3d09652 100644 --- a/classes/BlueChip/Security/Helpers/AjaxHelper.php +++ b/classes/BlueChip/Security/Helpers/AjaxHelper.php @@ -19,7 +19,7 @@ abstract class AjaxHelper * @param string $action * @param callable $handler */ - public static function addHandler(string $action, callable $handler) + public static function addHandler(string $action, callable $handler): void { add_action(self::WP_AJAX_PREFIX . $action, function () use ($action, $handler) { // Check AJAX referer for given action - will die if invalid. @@ -38,7 +38,7 @@ public static function addHandler(string $action, callable $handler) * @param string $action * @param array $data */ - public static function injectSetup(string $handle, string $object_name, string $action, array $data = []) + public static function injectSetup(string $handle, string $object_name, string $action, array $data = []): void { add_action('admin_enqueue_scripts', function () use ($handle, $object_name, $action, $data) { // Default localization data for every AJAX request. diff --git a/classes/BlueChip/Security/Helpers/FormHelper.php b/classes/BlueChip/Security/Helpers/FormHelper.php index 205f9cb..5cae45f 100644 --- a/classes/BlueChip/Security/Helpers/FormHelper.php +++ b/classes/BlueChip/Security/Helpers/FormHelper.php @@ -35,7 +35,7 @@ abstract class FormHelper * * @param array $args Required: label_for, name, value. Optional: class, plain. */ - public static function printCheckbox(array $args) + public static function printCheckbox(array $args): void { // Field properties $properties = [ @@ -66,7 +66,7 @@ public static function printCheckbox(array $args) * * @param array $args Required: label_for, name, value. Optional: class. */ - public static function printHiddenInput(array $args) + public static function printHiddenInput(array $args): void { // Field properties $properties = [ @@ -86,7 +86,7 @@ public static function printHiddenInput(array $args) * * @param array $args Required: label_for, name, value. Optional: class. */ - public static function printNumberInput(array $args) + public static function printNumberInput(array $args): void { // Field properties $properties = [ @@ -108,7 +108,7 @@ public static function printNumberInput(array $args) * * @param array $args Required: label_for, name, value. Optional: class. */ - public static function printTextInput(array $args) + public static function printTextInput(array $args): void { // Field properties $properties = [ @@ -130,7 +130,7 @@ public static function printTextInput(array $args) * * @param array $args Required: label_for, name, value. Optional: class. */ - public static function printSelect(array $args) + public static function printSelect(array $args): void { $properties = [ 'class' => $args['class'] ?? '', @@ -157,7 +157,7 @@ public static function printSelect(array $args) * * @param array $args Required: label_for, name, value. Optional: class, cols, rows. */ - public static function printTextArea(array $args) + public static function printTextArea(array $args): void { // Field properties $properties = [ @@ -219,7 +219,7 @@ function ($key, $value) { * @param array $args * @param bool $inline */ - protected static function printAppendix(array $args, bool $inline) + protected static function printAppendix(array $args, bool $inline): void { if (isset($args['description'])) { echo \sprintf( diff --git a/classes/BlueChip/Security/Helpers/Transients.php b/classes/BlueChip/Security/Helpers/Transients.php index 92fb210..8179bf8 100644 --- a/classes/BlueChip/Security/Helpers/Transients.php +++ b/classes/BlueChip/Security/Helpers/Transients.php @@ -32,7 +32,7 @@ public static function deleteFromSite(string ...$key): bool * * @param \wpdb $wpdb WordPress database access abstraction object */ - public static function flush(\wpdb $wpdb) + public static function flush(\wpdb $wpdb): void { $table_name = is_multisite() ? $wpdb->sitemeta : $wpdb->options; diff --git a/classes/BlueChip/Security/Modules/Activable.php b/classes/BlueChip/Security/Modules/Activable.php index addb848..6ebfca3 100644 --- a/classes/BlueChip/Security/Modules/Activable.php +++ b/classes/BlueChip/Security/Modules/Activable.php @@ -7,10 +7,10 @@ interface Activable /** * Activate module (add cron jobs etc.) */ - public function activate(); + public function activate(): void; /** * Deactivate module (remove cron jobs etc.) */ - public function deactivate(); + public function deactivate(): void; } diff --git a/classes/BlueChip/Security/Modules/Checklist/AdminPage.php b/classes/BlueChip/Security/Modules/Checklist/AdminPage.php index 2387b40..a2dec4d 100644 --- a/classes/BlueChip/Security/Modules/Checklist/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Checklist/AdminPage.php @@ -48,7 +48,7 @@ public function __construct(Manager $checklist_manager, AutorunSettings $setting /** * Initialize settings page: register settings etc. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); @@ -58,7 +58,7 @@ public function initPage() } - public function loadPage() + public function loadPage(): void { $this->enqueueCssAssets(['checklist' => 'checklist.css',]); $this->enqueueJsAssets(['checklist' => 'checklist.js',]); @@ -90,7 +90,7 @@ public function getCount(): int /** * Output admin page. */ - public function printContents() + public function printContents(): void { echo '
'; @@ -141,7 +141,7 @@ public function printContents() /** * @param array $basic_checks */ - private function printBasicChecksSection(array $basic_checks) + private function printBasicChecksSection(array $basic_checks): void { echo '

' . esc_html__('Basic checks', 'bc-security') . '

'; @@ -160,7 +160,7 @@ private function printBasicChecksSection(array $basic_checks) /** * @param array $advanced_checks */ - private function printAdvancedChecksSection(array $advanced_checks) + private function printAdvancedChecksSection(array $advanced_checks): void { echo '

' . esc_html__('Advanced checks', 'bc-security') . '

'; @@ -176,7 +176,7 @@ private function printAdvancedChecksSection(array $advanced_checks) } - private function printChecklistMonitoringSection() + private function printChecklistMonitoringSection(): void { echo '

' . esc_html__('Checklist monitoring', 'bc-security') . '

'; @@ -192,7 +192,7 @@ private function printChecklistMonitoringSection() } - private function printChecklistTable(array $checks, string $checks_class) + private function printChecklistTable(array $checks, string $checks_class): void { echo ''; @@ -219,7 +219,7 @@ private function printChecklistTable(array $checks, string $checks_class) /** * Output single table row with data labels. */ - private function printLabelsRow() + private function printLabelsRow(): void { echo ''; echo ''; @@ -238,7 +238,7 @@ private function printLabelsRow() * * @param \BlueChip\Security\Modules\Checklist\Check $check */ - private function printCheckRow(Check $check, string $check_class) + private function printCheckRow(Check $check, string $check_class): void { $check_id = $check::getId(); $check_html_id = array_reverse(explode("\\", $check_id))[0]; diff --git a/classes/BlueChip/Security/Modules/Checklist/AdvancedCheck.php b/classes/BlueChip/Security/Modules/Checklist/AdvancedCheck.php index 56fdf36..bc3eda1 100644 --- a/classes/BlueChip/Security/Modules/Checklist/AdvancedCheck.php +++ b/classes/BlueChip/Security/Modules/Checklist/AdvancedCheck.php @@ -31,7 +31,7 @@ public function getCronJobHook(): string * * @hook \BlueChip\Security\Modules\Checklist\Hooks::ADVANCED_CHECK_ALERT */ - public function runInCron() + public function runInCron(): void { $result = $this->run(); diff --git a/classes/BlueChip/Security/Modules/Checklist/Manager.php b/classes/BlueChip/Security/Modules/Checklist/Manager.php index c559b08..ebdbc09 100644 --- a/classes/BlueChip/Security/Modules/Checklist/Manager.php +++ b/classes/BlueChip/Security/Modules/Checklist/Manager.php @@ -43,7 +43,7 @@ public function __construct(AutorunSettings $settings, Cron\Manager $cron_manage } - public function init() + public function init(): void { // When settings are updated, ensure that cron jobs for advanced checks are properly (de)activated. $this->settings->addUpdateHook([$this, 'updateCronJobs']); @@ -191,7 +191,7 @@ public function getBasicChecks(bool $only_meaningful = true): array * * @internal Method is intended to be run from within cron request. */ - public function runBasicChecks() + public function runBasicChecks(): void { $checks = $this->getBasicChecks(); $issues = []; @@ -225,7 +225,7 @@ public function runBasicChecks() * * @internal Method is intended to be run from within AJAX requests. */ - public function runCheck() + public function runCheck(): void { if (empty($check_id = \filter_input(INPUT_POST, 'check_id', FILTER_SANITIZE_STRING))) { wp_send_json_error([ @@ -253,7 +253,7 @@ public function runCheck() /** * Activate or deactivate cron jobs for advanced checks according to settings. */ - public function updateCronJobs() + public function updateCronJobs(): void { foreach ($this->getAdvancedChecks(false) as $check_id => $advanced_check) { if ($this->settings[$check_id]) { diff --git a/classes/BlueChip/Security/Modules/Cron/Manager.php b/classes/BlueChip/Security/Modules/Cron/Manager.php index 3ebf11f..057cd4b 100644 --- a/classes/BlueChip/Security/Modules/Cron/Manager.php +++ b/classes/BlueChip/Security/Modules/Cron/Manager.php @@ -33,7 +33,7 @@ public function __construct(Settings $settings) } - public function activate() + public function activate(): void { // Schedule cron jobs that are active. foreach ($this->jobs as $hook => $job) { @@ -44,7 +44,7 @@ public function activate() } - public function deactivate() + public function deactivate(): void { // Unschedule all scheduled cron jobs. foreach ($this->jobs as $job) { diff --git a/classes/BlueChip/Security/Modules/Hardening/AdminPage.php b/classes/BlueChip/Security/Modules/Hardening/AdminPage.php index d5a9517..71b777a 100644 --- a/classes/BlueChip/Security/Modules/Hardening/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Hardening/AdminPage.php @@ -29,7 +29,7 @@ public function __construct(Settings $settings) } - public function loadPage() + public function loadPage(): void { $this->displaySettingsErrors(); } @@ -38,7 +38,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '
'; echo '

' . esc_html($this->page_title) . '

'; @@ -51,7 +51,7 @@ public function printContents() /** * Initialize settings page: add sections and fields. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); diff --git a/classes/BlueChip/Security/Modules/Hardening/Core.php b/classes/BlueChip/Security/Modules/Hardening/Core.php index e165c8d..e7f72ff 100644 --- a/classes/BlueChip/Security/Modules/Hardening/Core.php +++ b/classes/BlueChip/Security/Modules/Hardening/Core.php @@ -44,7 +44,7 @@ public function __construct(Settings $settings) /** * Initialize WP hardening. */ - public function init() + public function init(): void { if ($this->settings[Settings::DISABLE_PINGBACKS]) { // Disable pingbacks. @@ -220,7 +220,7 @@ protected static function smellsLikeAuthorScan(array $query_vars): bool * * @param \WP $wp */ - public function stopAuthorScan(\WP $wp) + public function stopAuthorScan(\WP $wp): void { if ($wp->query_vars[self::AUTHOR_SCAN_QUERY_VAR] ?? false) { status_header(404); @@ -243,7 +243,7 @@ public function stopAuthorScan(\WP $wp) * @param string $username * @param \WP_User $user */ - public function checkUserPassword(string $username, \WP_User $user) + public function checkUserPassword(string $username, \WP_User $user): void { if (empty($password = \filter_input(INPUT_POST, 'pwd'))) { // Non-interactive sign on (probably). @@ -267,7 +267,7 @@ public function checkUserPassword(string $username, \WP_User $user) * * @param \WP_Screen $screen */ - public function displayPasswordPwnedNotice(\WP_Screen $screen) + public function displayPasswordPwnedNotice(\WP_Screen $screen): void { $user = wp_get_current_user(); @@ -302,7 +302,7 @@ public function displayPasswordPwnedNotice(\WP_Screen $screen) * @param bool $update Whether this is a user update. * @param object $user User object (passed by reference). */ - public function validatePasswordUpdate(\WP_Error &$errors, bool $update, object &$user) + public function validatePasswordUpdate(\WP_Error &$errors, bool $update, object &$user): void { if ($errors->get_error_code()) { // There is an error reported already, skip the check. @@ -326,7 +326,7 @@ public function validatePasswordUpdate(\WP_Error &$errors, bool $update, object * @param \WP_Error $errors * @param \WP_User|\WP_Error $user WP_User object if the login and reset key match. WP_Error object otherwise. */ - public function validatePasswordReset(\WP_Error $errors, object $user) + public function validatePasswordReset(\WP_Error $errors, object $user): void { if ($errors->get_error_code()) { // There is an error reported already, skip the check. @@ -348,7 +348,7 @@ public function validatePasswordReset(\WP_Error $errors, object $user) * @param string $password * @param \WP_Error $errors WP_Error object (passed by reference). */ - protected static function checkIfPasswordHasBeenPwned(string $password, \WP_Error &$errors) + protected static function checkIfPasswordHasBeenPwned(string $password, \WP_Error &$errors): void { if (HaveIBeenPwned::hasPasswordBeenPwned($password)) { $message = \sprintf( diff --git a/classes/BlueChip/Security/Modules/Initializable.php b/classes/BlueChip/Security/Modules/Initializable.php index 06ffd85..780fd30 100644 --- a/classes/BlueChip/Security/Modules/Initializable.php +++ b/classes/BlueChip/Security/Modules/Initializable.php @@ -7,5 +7,5 @@ interface Initializable /** * Initialize module (perform any tasks that should be done init hook) */ - public function init(); + public function init(): void; } diff --git a/classes/BlueChip/Security/Modules/Installable.php b/classes/BlueChip/Security/Modules/Installable.php index 2b0b58e..57e72ce 100644 --- a/classes/BlueChip/Security/Modules/Installable.php +++ b/classes/BlueChip/Security/Modules/Installable.php @@ -7,10 +7,10 @@ interface Installable /** * Install module (add DB tables etc.) */ - public function install(); + public function install(): void; /** * Uninstall module (drop DB tables etc.) */ - public function uninstall(); + public function uninstall(): void; } diff --git a/classes/BlueChip/Security/Modules/IpBlacklist/AdminPage.php b/classes/BlueChip/Security/Modules/IpBlacklist/AdminPage.php index d06e828..dd932bc 100644 --- a/classes/BlueChip/Security/Modules/IpBlacklist/AdminPage.php +++ b/classes/BlueChip/Security/Modules/IpBlacklist/AdminPage.php @@ -78,7 +78,7 @@ public function __construct(Manager $bl_manager, Cron\Manager $cron_manager) } - public function loadPage() + public function loadPage(): void { $this->resetCount(); $this->processActions(); @@ -90,7 +90,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '
'; // Page heading @@ -114,7 +114,7 @@ public function printContents() * * @hook \BlueChip\Security\Modules\IpBlacklist\Hooks::DEFAULT_MANUAL_LOCK_DURATION */ - private function printBlacklistingForm() + private function printBlacklistingForm(): void { // IP address and lock scope can be "pre-filled". $ip_address = \filter_input(INPUT_GET, self::DEFAULT_IP_ADDRESS, FILTER_VALIDATE_IP); @@ -193,7 +193,7 @@ private function printBlacklistingForm() /** * Output forms for IP blacklist pruning (including cron job activation and deactivation). */ - private function printPruningActions() + private function printPruningActions(): void { echo '

' . esc_html__('Blacklist pruning', 'bc-security') . '

'; @@ -220,7 +220,7 @@ private function printPruningActions() /** * Initialize list table instance. */ - private function initListTable() + private function initListTable(): void { $this->list_table = new ListTable($this->getUrl(), $this->per_page_option_name, $this->bl_manager); $this->list_table->processActions(); // may trigger wp_redirect() @@ -232,7 +232,7 @@ private function initListTable() /** * Dispatch any action that is indicated by POST data (form submission). */ - private function processActions() + private function processActions(): void { $nonce = \filter_input(INPUT_POST, self::NONCE_NAME, FILTER_SANITIZE_STRING); if (empty($nonce)) { @@ -265,7 +265,7 @@ private function processActions() /** * Read POST data and attempt to add IP address to blacklist. Display notice about action outcome. */ - private function processBlacklistAction() + private function processBlacklistAction(): void { $ip_address = \filter_input(INPUT_POST, 'ip-address', FILTER_VALIDATE_IP); $duration_length = \filter_input(INPUT_POST, 'duration-length', FILTER_VALIDATE_INT); @@ -301,7 +301,7 @@ private function processBlacklistAction() /** * Attempt to prune blacklist table. Display notice about action outcome. */ - private function processPruneAction() + private function processPruneAction(): void { if ($this->bl_manager->prune()) { AdminNotices::add( @@ -320,7 +320,7 @@ private function processPruneAction() /** * Deactivate cron job for blacklist table pruning. Display notice about action outcome. */ - private function processCronOffAction() + private function processCronOffAction(): void { $this->cron_manager->deactivateJob(Cron\Jobs::IP_BLACKLIST_CLEAN_UP); AdminNotices::add( @@ -333,7 +333,7 @@ private function processCronOffAction() /** * Activate cron job for blacklist table pruning. Display notice about action outcome. */ - private function processCronOnAction() + private function processCronOnAction(): void { if ($this->cron_manager->activateJob(Cron\Jobs::IP_BLACKLIST_CLEAN_UP)) { AdminNotices::add( diff --git a/classes/BlueChip/Security/Modules/IpBlacklist/Bouncer.php b/classes/BlueChip/Security/Modules/IpBlacklist/Bouncer.php index e5612f5..bd4ac05 100644 --- a/classes/BlueChip/Security/Modules/IpBlacklist/Bouncer.php +++ b/classes/BlueChip/Security/Modules/IpBlacklist/Bouncer.php @@ -36,7 +36,7 @@ public function __construct(string $remote_address, Manager $bl_manager) /** * Load module. */ - public function load() + public function load(): void { // In case of non-cli context or if remote IP address is invalid, die immediately. if (!Helpers\Is::cli() && empty($this->remote_address)) { @@ -51,7 +51,7 @@ public function load() /** * Initialize module. */ - public function init() + public function init(): void { add_filter('authenticate', [$this, 'checkLoginAttempt'], 1, 1); // Leave priority 0 for site maintainers. } @@ -64,7 +64,7 @@ public function init() * * @param string $ip_address Remote IP address to include in error message [optional]. */ - public static function blockAccessTemporarily(string $ip_address = '') + public static function blockAccessTemporarily(string $ip_address = ''): void { $error_msg = empty($ip_address) ? esc_html__('Access from your device has been temporarily disabled for security reasons.', 'bc-security') @@ -80,7 +80,7 @@ public static function blockAccessTemporarily(string $ip_address = '') /** * Block access to the website when remote IP address is locked. */ - public function checkAccess() + public function checkAccess(): void { if ($this->bl_manager->isLocked($this->remote_address, LockScope::WEBSITE)) { self::blockAccessTemporarily($this->remote_address); diff --git a/classes/BlueChip/Security/Modules/IpBlacklist/ListTable.php b/classes/BlueChip/Security/Modules/IpBlacklist/ListTable.php index 2574c60..12342e6 100644 --- a/classes/BlueChip/Security/Modules/IpBlacklist/ListTable.php +++ b/classes/BlueChip/Security/Modules/IpBlacklist/ListTable.php @@ -125,7 +125,7 @@ public function column_reason(array $item): string // phpcs:ignore /** * Display (dismissible) admin notices informing user that an action has been performed successfully. */ - public function displayNotices() + public function displayNotices(): void { $this->displayNotice( self::NOTICE_RECORD_REMOVED, @@ -231,6 +231,8 @@ protected function get_views() // phpcs:ignore /** * Prepare items for table. + * + * @return void */ public function prepare_items() // phpcs:ignore { @@ -253,7 +255,7 @@ public function prepare_items() // phpcs:ignore * * @return void */ - public function processActions() + public function processActions(): void { // Remove or unlock single record? if (($action = \filter_input(INPUT_GET, 'action'))) { diff --git a/classes/BlueChip/Security/Modules/IpBlacklist/Manager.php b/classes/BlueChip/Security/Modules/IpBlacklist/Manager.php index 22fa33a..54124d4 100644 --- a/classes/BlueChip/Security/Modules/IpBlacklist/Manager.php +++ b/classes/BlueChip/Security/Modules/IpBlacklist/Manager.php @@ -60,7 +60,7 @@ public function __construct(\wpdb $wpdb) /** * @link https://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table */ - public function install() + public function install(): void { // To have dbDelta() require_once ABSPATH . 'wp-admin/includes/upgrade.php'; @@ -83,13 +83,13 @@ public function install() } - public function uninstall() + public function uninstall(): void { $this->wpdb->query(\sprintf('DROP TABLE IF EXISTS %s', $this->blacklist_table)); } - public function init() + public function init(): void { // Hook into cron job execution. add_action(Modules\Cron\Jobs::IP_BLACKLIST_CLEAN_UP, [$this, 'prune'], 10, 0); diff --git a/classes/BlueChip/Security/Modules/Loadable.php b/classes/BlueChip/Security/Modules/Loadable.php index 172d14e..0425453 100644 --- a/classes/BlueChip/Security/Modules/Loadable.php +++ b/classes/BlueChip/Security/Modules/Loadable.php @@ -7,5 +7,5 @@ interface Loadable /** * Load module (perform any tasks that should be done immediately on plugin load) */ - public function load(); + public function load(): void; } diff --git a/classes/BlueChip/Security/Modules/Log/AdminPage.php b/classes/BlueChip/Security/Modules/Log/AdminPage.php index 7605670..d146caa 100644 --- a/classes/BlueChip/Security/Modules/Log/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Log/AdminPage.php @@ -51,7 +51,7 @@ public function __construct(Settings $settings, Logger $logger) /** * Initialize settings page: add sections and fields. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); @@ -84,7 +84,7 @@ function () { } - public function loadPage() + public function loadPage(): void { $this->resetCount(); $this->displaySettingsErrors(); @@ -96,7 +96,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '
'; @@ -119,7 +119,7 @@ public function printContents() /** * Initialize list table instance. */ - private function initListTable() + private function initListTable(): void { $this->list_table = new ListTable($this->getUrl(), $this->per_page_option_name, $this->logger); $this->list_table->prepare_items(); diff --git a/classes/BlueChip/Security/Modules/Log/EventsMonitor.php b/classes/BlueChip/Security/Modules/Log/EventsMonitor.php index 0ec953d..d3ef0e1 100644 --- a/classes/BlueChip/Security/Modules/Log/EventsMonitor.php +++ b/classes/BlueChip/Security/Modules/Log/EventsMonitor.php @@ -28,7 +28,7 @@ public function __construct(string $remote_address, string $server_address) } - public function init() + public function init(): void { // Log the following WordPress events: // - bad authentication cookie @@ -58,7 +58,7 @@ public function init() * * @param \WP $wp */ - public function log404Queries(\WP $wp) + public function log404Queries(\WP $wp): void { /** @var \WP_Query $wp_query */ global $wp_query; @@ -74,7 +74,7 @@ public function log404Queries(\WP $wp) * * @param array $cookie_elements */ - public function logBadCookie(array $cookie_elements) + public function logBadCookie(array $cookie_elements): void { do_action(Action::EVENT, (new Events\AuthBadCookie())->setUsername($cookie_elements['username'])); } @@ -86,7 +86,7 @@ public function logBadCookie(array $cookie_elements) * @param string $username * @param \WP_Error $error */ - public function logFailedLogin(string $username, \WP_Error $error) + public function logFailedLogin(string $username, \WP_Error $error): void { do_action(Action::EVENT, (new Events\LoginFailure())->setUsername($username)->setError($error)); } @@ -97,7 +97,7 @@ public function logFailedLogin(string $username, \WP_Error $error) * * @param string $username */ - public function logSuccessfulLogin(string $username) + public function logSuccessfulLogin(string $username): void { do_action(Action::EVENT, (new Events\LoginSuccessful())->setUsername($username)); } @@ -110,7 +110,7 @@ public function logSuccessfulLogin(string $username) * @param string $username * @param int $duration */ - public function logLockoutEvent(string $remote_address, string $username, int $duration) + public function logLockoutEvent(string $remote_address, string $username, int $duration): void { do_action(Action::EVENT, (new Events\LoginLockout())->setDuration($duration)->setIpAddress($remote_address)->setUsername($username)); } diff --git a/classes/BlueChip/Security/Modules/Log/ListTable.php b/classes/BlueChip/Security/Modules/Log/ListTable.php index 6c5bbf1..043fac0 100644 --- a/classes/BlueChip/Security/Modules/Log/ListTable.php +++ b/classes/BlueChip/Security/Modules/Log/ListTable.php @@ -197,6 +197,8 @@ protected function get_views() // phpcs:ignore /** * Prepare items for table. + * + * @return void */ public function prepare_items() // phpcs:ignore { diff --git a/classes/BlueChip/Security/Modules/Log/Logger.php b/classes/BlueChip/Security/Modules/Log/Logger.php index f1acd0a..bf40584 100644 --- a/classes/BlueChip/Security/Modules/Log/Logger.php +++ b/classes/BlueChip/Security/Modules/Log/Logger.php @@ -59,7 +59,7 @@ public function __construct(\wpdb $wpdb, string $remote_address, Settings $setti /** * @link https://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table */ - public function install() + public function install(): void { // To have dbDelta() require_once ABSPATH . 'wp-admin/includes/upgrade.php'; @@ -83,13 +83,13 @@ public function install() } - public function uninstall() + public function uninstall(): void { $this->wpdb->query(\sprintf('DROP TABLE IF EXISTS %s', $this->log_table)); } - public function load() + public function load(): void { // Expose log methods via do_action() - inspired by Wonolog: // https://github.com/inpsyde/Wonolog/blob/master/docs/02-basic-wonolog-concepts.md#level-rich-log-hooks @@ -106,7 +106,7 @@ public function load() } - public function init() + public function init(): void { // Hook into cron job execution. add_action(Modules\Cron\Jobs::LOGS_CLEAN_UP_BY_AGE, [$this, 'pruneByAge'], 10, 0); @@ -174,7 +174,7 @@ public function log($level, $message, array $context = []) * * @param \BlueChip\Security\Modules\Log\Event $event */ - public function logEvent(Event $event) + public function logEvent(Event $event): void { // Include event ID in context. $this->log($event->getLogLevel(), $event->getMessage(), \array_merge(['event' => $event->getId()], $event->getContext())); @@ -218,7 +218,7 @@ public function translateLogLevel(string $level): ?int * * @param \BlueChip\Security\Modules\Services\ReverseDnsLookup\Response $response */ - public function processReverseDnsLookupResponse(ReverseDnsLookup\Response $response) + public function processReverseDnsLookupResponse(ReverseDnsLookup\Response $response): void { $this->wpdb->update( $this->log_table, diff --git a/classes/BlueChip/Security/Modules/Login/AdminPage.php b/classes/BlueChip/Security/Modules/Login/AdminPage.php index 22e81bb..6dcd684 100644 --- a/classes/BlueChip/Security/Modules/Login/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Login/AdminPage.php @@ -28,7 +28,7 @@ public function __construct(Settings $settings) } - public function loadPage() + public function loadPage(): void { $this->displaySettingsErrors(); } @@ -37,7 +37,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '
'; echo '

' . esc_html($this->page_title) . '

'; @@ -49,7 +49,7 @@ public function printContents() /** * Initialize settings page: add sections and fields. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); diff --git a/classes/BlueChip/Security/Modules/Login/Bookkeeper.php b/classes/BlueChip/Security/Modules/Login/Bookkeeper.php index 7fdfc3b..24f57e9 100644 --- a/classes/BlueChip/Security/Modules/Login/Bookkeeper.php +++ b/classes/BlueChip/Security/Modules/Login/Bookkeeper.php @@ -46,7 +46,7 @@ public function __construct(Settings $settings, \wpdb $wpdb) /** * @link https://codex.wordpress.org/Creating_Tables_with_Plugins#Creating_or_Updating_the_Table */ - public function install() + public function install(): void { // To have dbDelta() require_once ABSPATH . 'wp-admin/includes/upgrade.php'; @@ -67,7 +67,7 @@ public function install() } - public function uninstall() + public function uninstall(): void { $this->wpdb->query(\sprintf('DROP TABLE IF EXISTS %s', $this->failed_logins_table)); } diff --git a/classes/BlueChip/Security/Modules/Login/Gatekeeper.php b/classes/BlueChip/Security/Modules/Login/Gatekeeper.php index 761f3d7..6601ac3 100644 --- a/classes/BlueChip/Security/Modules/Login/Gatekeeper.php +++ b/classes/BlueChip/Security/Modules/Login/Gatekeeper.php @@ -48,7 +48,7 @@ public function __construct(Settings $settings, string $remote_address, Bookkeep /** * Check if IP is locked early on, but allow other plugins to interfere. */ - public function load() + public function load(): void { add_action('plugins_loaded', [$this, 'removeAuthCookieIfIpIsLocked'], 5, 0); } @@ -57,7 +57,7 @@ public function load() /** * Initialize login hardening. */ - public function init() + public function init(): void { add_filter('illegal_user_logins', [$this, 'filterIllegalUserLogins'], 10, 1); @@ -111,7 +111,7 @@ public function filterShakeErrorCodes(array $error_codes): array * * @param array $cookie_elements */ - public function handleBadCookie(array $cookie_elements) + public function handleBadCookie(array $cookie_elements): void { // Clear authentication cookies completely $this->clearAuthCookie(); @@ -128,7 +128,7 @@ public function handleBadCookie(array $cookie_elements) * * @param string $username */ - public function handleFailedLogin(string $username) + public function handleFailedLogin(string $username): void { // If currently locked-out, bail (should not happen, but better safe than sorry) if ($this->bl_manager->isLocked($this->remote_address, IpBlacklist\LockScope::ADMIN)) { @@ -200,7 +200,7 @@ public function muteStandardErrorMessages($user) * Remove all WordPress authentication cookies if IP is on black list. * Method should be called as early as possible. */ - public function removeAuthCookieIfIpIsLocked() + public function removeAuthCookieIfIpIsLocked(): void { if ($this->bl_manager->isLocked($this->remote_address, IpBlacklist\LockScope::ADMIN)) { $this->clearAuthCookie(); @@ -213,7 +213,7 @@ public function removeAuthCookieIfIpIsLocked() /** * Clear all WordPress authentication cookies (also for current request). */ - protected function clearAuthCookie() + protected function clearAuthCookie(): void { wp_clear_auth_cookie(); @@ -232,7 +232,7 @@ protected function clearAuthCookie() * @param int $duration Duration (in secs) of lockout * @param int $reason Lockout reason */ - protected function lockOut(string $username, int $duration, int $reason) + protected function lockOut(string $username, int $duration, int $reason): void { // Trigger lockout action do_action(Hooks::LOCKOUT_EVENT, $this->remote_address, $username, $duration, $reason); diff --git a/classes/BlueChip/Security/Modules/Notifications/AdminPage.php b/classes/BlueChip/Security/Modules/Notifications/AdminPage.php index a24b0b3..e208ad6 100644 --- a/classes/BlueChip/Security/Modules/Notifications/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Notifications/AdminPage.php @@ -29,7 +29,7 @@ public function __construct(Settings $settings) } - public function loadPage() + public function loadPage(): void { $this->displaySettingsErrors(); @@ -47,7 +47,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '
'; echo '

' . esc_html($this->page_title) . '

'; @@ -59,7 +59,7 @@ public function printContents() /** * Initialize settings page: add sections and fields. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); diff --git a/classes/BlueChip/Security/Modules/Notifications/Watchman.php b/classes/BlueChip/Security/Modules/Notifications/Watchman.php index badca0e..e2cc02e 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Watchman.php +++ b/classes/BlueChip/Security/Modules/Notifications/Watchman.php @@ -82,7 +82,7 @@ private static function formatRemoteAddress(string $remote_address): string /** * Initialize notification according to settings. */ - public function init() + public function init(): void { // Bail early if no recipients are set or we are explicitly ordered to not disturb. if (empty($this->recipients) || self::isMuted()) { @@ -111,7 +111,7 @@ public function init() } - public function activate() + public function activate(): void { // Do nothing. } @@ -120,7 +120,7 @@ public function activate() /** * Send notification that plugin has been deactivated. */ - public function deactivate() + public function deactivate(): void { // Bail early if no recipients are set. if (empty($this->recipients)) { @@ -156,7 +156,7 @@ public function deactivate() * * @param object $update_transient */ - public function watchCoreUpdateAvailable($update_transient) + public function watchCoreUpdateAvailable($update_transient): void { // Check if update transient has the data we are interested in. if (!isset($update_transient->updates) || !\is_array($update_transient->updates) || empty($update_transient->updates)) { @@ -200,7 +200,7 @@ public function watchCoreUpdateAvailable($update_transient) * * @param object $update_transient */ - public function watchPluginUpdatesAvailable($update_transient) + public function watchPluginUpdatesAvailable($update_transient): void { // Check if update transient has the data we are interested in. if (!isset($update_transient->response) || !\is_array($update_transient->response)) { @@ -257,7 +257,7 @@ public function watchPluginUpdatesAvailable($update_transient) * * @param object $update_transient */ - public function watchThemeUpdatesAvailable($update_transient) + public function watchThemeUpdatesAvailable($update_transient): void { // Check if update transient has the data we are interested in. if (!isset($update_transient->response) || !\is_array($update_transient->response)) { @@ -306,7 +306,7 @@ public function watchThemeUpdatesAvailable($update_transient) * @param string $username * @param int $duration */ - public function watchLockoutEvents(string $remote_address, string $username, int $duration) + public function watchLockoutEvents(string $remote_address, string $username, int $duration): void { if (\in_array($remote_address, $this->logger->getKnownIps(), true)) { $subject = __('Known IP locked out', 'bc-security'); @@ -328,7 +328,7 @@ public function watchLockoutEvents(string $remote_address, string $username, int * @param string $username * @param \WP_User $user */ - public function watchWpLogin(string $username, \WP_User $user) + public function watchWpLogin(string $username, \WP_User $user): void { if (Is::admin($user)) { $subject = __('Admin user login', 'bc-security'); @@ -349,7 +349,7 @@ public function watchWpLogin(string $username, \WP_User $user) * @param \BlueChip\Security\Modules\Checklist\Check $check * @param \BlueChip\Security\Modules\Checklist\CheckResult $result */ - public function watchChecklistSingleCheckAlert(Checklist\Check $check, Checklist\CheckResult $result) + public function watchChecklistSingleCheckAlert(Checklist\Check $check, Checklist\CheckResult $result): void { $subject = __('Checklist monitoring alert', 'bc-security'); $preamble = [ @@ -366,7 +366,7 @@ public function watchChecklistSingleCheckAlert(Checklist\Check $check, Checklist * * @param array $issues Issues which triggered the alert (issue is an array with 'check' and 'result' keys). */ - public function watchChecklistMultipleChecksAlert(array $issues) + public function watchChecklistMultipleChecksAlert(array $issues): void { $subject = __('Checklist monitoring alert', 'bc-security'); $message = [ diff --git a/classes/BlueChip/Security/Modules/Services/ReverseDnsLookup/Resolver.php b/classes/BlueChip/Security/Modules/Services/ReverseDnsLookup/Resolver.php index 8aabcb9..2082f89 100644 --- a/classes/BlueChip/Security/Modules/Services/ReverseDnsLookup/Resolver.php +++ b/classes/BlueChip/Security/Modules/Services/ReverseDnsLookup/Resolver.php @@ -26,20 +26,20 @@ class Resolver implements Modules\Activable, Modules\Initializable private const CACHE_TTL = DAY_IN_SECONDS; - public function activate() + public function activate(): void { // Do nothing. } - public function deactivate() + public function deactivate(): void { // Unschedule all cron jobs consumed by this module. wp_unschedule_hook(self::RESOLVE_REMOTE_ADDRESS); } - public function init() + public function init(): void { // Register action for non-blocking hostname resolution. add_action(self::RESOLVE_REMOTE_ADDRESS, [$this, 'resolveHostname'], 10, 3); @@ -55,7 +55,7 @@ public function init() * @param string $action Name of action to invoke with resolved hostname. * @param array $context Additional parameters that are passed to the action. */ - public function resolveHostname(string $ip_address, string $action, array $context) + public function resolveHostname(string $ip_address, string $action, array $context): void { if (!empty($hostname = $this->resolveHostnameInForeground($ip_address))) { do_action($action, new Response($ip_address, $hostname, $context)); @@ -72,7 +72,7 @@ public function resolveHostname(string $ip_address, string $action, array $conte * @param string $action Name of action to call when remote hostname is resolved. * @param array $context [optional] Additional parameters to pass to the action. */ - public function resolveHostnameInBackground(string $ip_address, string $action, array $context = []) + public function resolveHostnameInBackground(string $ip_address, string $action, array $context = []): void { wp_schedule_single_event(\time(), self::RESOLVE_REMOTE_ADDRESS, [$ip_address, $action, $context]); } diff --git a/classes/BlueChip/Security/Modules/Tools/AdminPage.php b/classes/BlueChip/Security/Modules/Tools/AdminPage.php index 7a607c9..1a073e3 100644 --- a/classes/BlueChip/Security/Modules/Tools/AdminPage.php +++ b/classes/BlueChip/Security/Modules/Tools/AdminPage.php @@ -46,13 +46,13 @@ public function __construct(array $settings) } - public function loadPage() + public function loadPage(): void { $this->processActions(); } - public function printContents() + public function printContents(): void { echo '
'; echo '

' . esc_html($this->page_title) . '

'; @@ -67,7 +67,7 @@ public function printContents() } - private function printExportForm() + private function printExportForm(): void { echo '

' . esc_html__('Export settings', 'bc-security') . '

'; echo '

' . esc_html__('Create JSON file with plugin settings that can be used as backup or to clone the settings to another installation.', 'bc-security') . '

'; @@ -80,7 +80,7 @@ private function printExportForm() } - private function printImportForm() + private function printImportForm(): void { echo '

' . esc_html__('Import settings', 'bc-security') . '

'; echo '

' . esc_html__('Import only JSON files created with the same version of the plugin!', 'bc-security') . '

'; @@ -96,7 +96,7 @@ private function printImportForm() } - private function printResetForm() + private function printResetForm(): void { echo '

' . esc_html__('Reset settings', 'bc-security') . '

'; echo '

'; @@ -122,7 +122,7 @@ private function printResetForm() /** * Dispatch any action that is indicated by POST data (form submission). */ - private function processActions() + private function processActions(): void { $nonce = \filter_input(INPUT_POST, self::NONCE_NAME, FILTER_SANITIZE_STRING); if (empty($nonce)) { @@ -147,7 +147,7 @@ private function processActions() } - private function processExportAction() + private function processExportAction(): void { $export = []; @@ -166,7 +166,7 @@ private function processExportAction() } - private function processImportAction() + private function processImportAction(): void { $import_file = $_FILES['import-file']; @@ -228,7 +228,7 @@ private function processImportAction() } - private function processResetAction() + private function processResetAction(): void { foreach ($this->settings as $settings) { $settings->reset(); diff --git a/classes/BlueChip/Security/Plugin.php b/classes/BlueChip/Security/Plugin.php index 66c1199..8816008 100644 --- a/classes/BlueChip/Security/Plugin.php +++ b/classes/BlueChip/Security/Plugin.php @@ -114,7 +114,7 @@ private static function constructModules(\wpdb $wpdb, string $remote_address, st * Load the plugin by hooking into WordPress actions and filters. * Method should be invoked immediately on plugin load. */ - public function load() + public function load(): void { // Load all modules that require immediate loading. foreach ($this->modules as $module) { @@ -134,7 +134,7 @@ public function load() * * @action https://developer.wordpress.org/reference/hooks/init/ */ - public function init() + public function init(): void { // Initialize all modules that require initialization. foreach ($this->modules as $module) { @@ -187,7 +187,7 @@ public function init() * * @link https://developer.wordpress.org/plugins/the-basics/activation-deactivation-hooks/ */ - public function activate() + public function activate(): void { // Explicitly persist every setting object, so related option is autoloaded. foreach ($this->settings as $settings) { @@ -216,7 +216,7 @@ public function activate() * * @link https://developer.wordpress.org/plugins/the-basics/activation-deactivation-hooks/ */ - public function deactivate() + public function deactivate(): void { // Deactivate every module that requires it. foreach ($this->modules as $module) { @@ -233,7 +233,7 @@ public function deactivate() * * @link https://developer.wordpress.org/plugins/the-basics/uninstall-methods/ */ - public function uninstall() + public function uninstall(): void { // Remove plugin settings. foreach ($this->settings as $settings) { diff --git a/classes/BlueChip/Security/Setup/AdminPage.php b/classes/BlueChip/Security/Setup/AdminPage.php index f146b9a..89630d3 100644 --- a/classes/BlueChip/Security/Setup/AdminPage.php +++ b/classes/BlueChip/Security/Setup/AdminPage.php @@ -29,7 +29,7 @@ public function __construct(Settings $settings) } - public function loadPage() + public function loadPage(): void { $this->displaySettingsErrors(); @@ -64,7 +64,7 @@ public function loadPage() /** * Output page contents. */ - public function printContents() + public function printContents(): void { echo '

'; echo '

' . esc_html($this->page_title) . '

'; @@ -76,7 +76,7 @@ public function printContents() /** * Initialize settings page: add sections and fields. */ - public function initPage() + public function initPage(): void { // Register settings. $this->registerSettings(); @@ -111,7 +111,7 @@ public function initPage() } - public function printGoogleAPIHint() + public function printGoogleAPIHint(): void { echo '

'; echo sprintf( @@ -124,7 +124,7 @@ public function printGoogleAPIHint() } - public function printSiteConnectionHint() + public function printSiteConnectionHint(): void { $list = IpAddress::enlist(true); From 48c0d9c9c439ee396696ce081508ff440f3bebb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 14:59:45 +0100 Subject: [PATCH 24/57] Fix type hints of class properties --- .../Security/Modules/Hardening/Settings.php | 12 ++++++------ .../Security/Modules/Log/EventsManager.php | 1 + .../BlueChip/Security/Modules/Log/Settings.php | 4 ++-- .../Security/Modules/Login/Settings.php | 14 +++++++------- .../Modules/Notifications/Settings.php | 18 +++++++++--------- classes/BlueChip/Security/Setup/Settings.php | 8 ++++++-- 6 files changed, 31 insertions(+), 26 deletions(-) diff --git a/classes/BlueChip/Security/Modules/Hardening/Settings.php b/classes/BlueChip/Security/Modules/Hardening/Settings.php index d6f7c79..eb3bdd5 100644 --- a/classes/BlueChip/Security/Modules/Hardening/Settings.php +++ b/classes/BlueChip/Security/Modules/Hardening/Settings.php @@ -5,32 +5,32 @@ class Settings extends \BlueChip\Security\Core\Settings { /** - * bool: Disable pingbacks? [No] + * @var string Disable pingbacks? [bool:no] */ public const DISABLE_PINGBACKS = 'disable_pingbacks'; /** - * bool: Disable XML RPC methods that require authentication? [No] + * @var string Disable XML RPC methods that require authentication? [bool:no] */ public const DISABLE_XML_RPC = 'disable_xml_rpc'; /** - * bool: Disable application passwords feature? [No] + * @var string Disable application passwords feature? [bool:no] */ public const DISABLE_APPLICATION_PASSWORDS = 'disable_application_passwords'; /** - * bool: Disable users listings via REST API `/wp/v2/users` endpoint and author scan via author=N query? [No] + * @var string Disable users listings via REST API `/wp/v2/users` endpoint and author scan via author=N query? [bool:no] */ public const DISABLE_USERNAMES_DISCOVERY = 'disable_usernames_discovery'; /** - * bool: Check existing passwords against Pwned Passwords database? [No] + * @var string Check existing passwords against Pwned Passwords database? [bool:no] */ public const CHECK_PASSWORDS = 'check_passwords'; /** - * bool: Validate new/updated passwords against Pwned Passwords database? [No] + * @var string Validate new/updated passwords against Pwned Passwords database? [bool:no] */ public const VALIDATE_PASSWORDS = 'validate_passwords'; diff --git a/classes/BlueChip/Security/Modules/Log/EventsManager.php b/classes/BlueChip/Security/Modules/Log/EventsManager.php index 558b788..51cd6a2 100644 --- a/classes/BlueChip/Security/Modules/Log/EventsManager.php +++ b/classes/BlueChip/Security/Modules/Log/EventsManager.php @@ -7,6 +7,7 @@ */ abstract class EventsManager { + /** @var array */ private static $mapping = [ Events\AuthBadCookie::ID => Events\AuthBadCookie::class, Events\LoginFailure::ID => Events\LoginFailure::class, diff --git a/classes/BlueChip/Security/Modules/Log/Settings.php b/classes/BlueChip/Security/Modules/Log/Settings.php index 2bc7e9e..077543b 100644 --- a/classes/BlueChip/Security/Modules/Log/Settings.php +++ b/classes/BlueChip/Security/Modules/Log/Settings.php @@ -7,10 +7,10 @@ */ class Settings extends \BlueChip\Security\Core\Settings { - /** int: Maximum size of log table in thousands of records [20] */ + /** @var string Maximum size of log table in thousands of records [int:20] */ public const LOG_MAX_SIZE = 'log_max_size'; - /** int: Maximum age of log record in days [365] */ + /** @var string Maximum age of log record in days [int:365] */ public const LOG_MAX_AGE = 'log_max_age'; diff --git a/classes/BlueChip/Security/Modules/Login/Settings.php b/classes/BlueChip/Security/Modules/Login/Settings.php index 000ce21..58870e8 100644 --- a/classes/BlueChip/Security/Modules/Login/Settings.php +++ b/classes/BlueChip/Security/Modules/Login/Settings.php @@ -7,25 +7,25 @@ */ class Settings extends \BlueChip\Security\Core\Settings { - /** int: Lock out for a short time after every N tries [5] */ + /** @var string Lock out for a short time after every N tries [int:5] */ public const SHORT_LOCKOUT_AFTER = 'short_lockout_after'; - /** int: Lock out for a short time for this many minutes [10] */ + /** @var string Lock out for a short time for this many minutes [int:10] */ public const SHORT_LOCKOUT_DURATION = 'short_lockout_duration'; - /** int: Lock out for a long time after every N tries [20] */ + /** @var string Lock out for a long time after every N tries [int:20] */ public const LONG_LOCKOUT_AFTER = 'long_lockout_after'; - /** int: Lock out for a long time for this many hours [24] */ + /** @var string Lock out for a long time for this many hours [int:24] */ public const LONG_LOCKOUT_DURATION = 'long_lockout_duration'; - /** int: Reset failed attempts after this many days [3] */ + /** @var string Reset failed attempts after this many days [int:3] */ public const RESET_TIMEOUT = 'reset_timeout'; - /** array: List of usernames that trigger long lockout immediately when used to log in [empty] */ + /** @var string List of usernames that trigger long lockout immediately when used to log in [array:empty] */ public const USERNAME_BLACKLIST = 'username_blacklist'; - /** bool: Display generic login error message? [No] */ + /** @var string Display generic login error message? [bool:no] */ public const GENERIC_LOGIN_ERROR_MESSAGE = 'display_generic_error_message'; diff --git a/classes/BlueChip/Security/Modules/Notifications/Settings.php b/classes/BlueChip/Security/Modules/Notifications/Settings.php index 10e1dc0..5efef5c 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Settings.php +++ b/classes/BlueChip/Security/Modules/Notifications/Settings.php @@ -7,31 +7,31 @@ */ class Settings extends \BlueChip\Security\Core\Settings { - /** bool: Notify when user with admin privileges logs in [Yes] */ + /** @var string Notify when user with admin privileges logs in [bool:yes] */ public const ADMIN_USER_LOGIN = 'admin_user_login'; - /** bool: Notify when known IP (IP for which there is a successful login in logs) is locked out [Yes] */ + /** @var string Notify when known IP (IP for which there is a successful login in logs) is locked out [bool:yes] */ public const KNOWN_IP_LOCKOUT = 'known_ip_lockout'; - /** bool: Notify when there is an update for WordPress available [Yes] */ + /** @var string Notify when there is an update for WordPress available [bool:yes] */ public const CORE_UPDATE_AVAILABLE = 'core_update_available'; - /** bool: Notify when there is a plugin update available [Yes] */ + /** @var string Notify when there is a plugin update available [bool:yes] */ public const PLUGIN_UPDATE_AVAILABLE = 'plugin_update_available'; - /** bool: Notify when there is a theme update available [Yes] */ + /** @var string Notify when there is a theme update available [bool:yes] */ public const THEME_UPDATE_AVAILABLE = 'theme_update_available'; - /** bool: Notify when automatic checklist check triggers an alert [Yes] */ + /** @var string Notify when automatic checklist check triggers an alert [bool:yes] */ public const CHECKLIST_ALERT = 'checklist_alert'; - /** bool: Notify when BC Security is deactivated [Yes] */ + /** @var string Notify when BC Security is deactivated [bool:yes] */ public const PLUGIN_DEACTIVATED = 'plugin_deactivated'; - /** bool: Send notification to email address of site administrator [No] */ + /** @var string Send notification to email address of site administrator [bool:no] */ public const NOTIFY_SITE_ADMIN = 'notify_site_admin'; - /** array: List of email addresses of any additional notifications [empty] */ + /** @var string List of email addresses of any additional notifications [array:empty] */ public const NOTIFICATION_RECIPIENTS = 'notification_recipients'; /** diff --git a/classes/BlueChip/Security/Setup/Settings.php b/classes/BlueChip/Security/Setup/Settings.php index 57a6647..989f573 100644 --- a/classes/BlueChip/Security/Setup/Settings.php +++ b/classes/BlueChip/Security/Setup/Settings.php @@ -7,10 +7,14 @@ */ class Settings extends \BlueChip\Security\Core\Settings { - /** string: What is server connection type? [REMOTE_ADDR] */ + /** + * @var string What is server connection type? [string:REMOTE_ADDR] + */ public const CONNECTION_TYPE = 'connection-type'; - /** string: Google API key (for Safe Browsing check) */ + /** + * @var string Google API key (for Safe Browsing check) [string] + */ public const GOOGLE_API_KEY = 'google-api-key'; From df758d9acbf29dcecbaa7c07cc66c0fccee49113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 15:08:03 +0100 Subject: [PATCH 25/57] Simplify interface of AdminNotices::add() method Now we can make it more concrete with a type hint. Nowhere in the plugin it has been called with the $message argument as array anyway... --- classes/BlueChip/Security/Helpers/AdminNotices.php | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/classes/BlueChip/Security/Helpers/AdminNotices.php b/classes/BlueChip/Security/Helpers/AdminNotices.php index 8eb89e6..8d85c2f 100644 --- a/classes/BlueChip/Security/Helpers/AdminNotices.php +++ b/classes/BlueChip/Security/Helpers/AdminNotices.php @@ -17,20 +17,17 @@ abstract class AdminNotices * * @link https://make.wordpress.org/core/2015/04/23/spinners-and-dismissible-admin-notices-in-4-2/ * - * @param array|string $message Single message or array of messages. + * @param string $message Message to display in admin notice. * @param string $type [optional] Type: 'notice-error', 'notice-warning', 'notice-success' or 'notice-info] (default). * @param bool $is_dismissible [optional] Should the notice be dismissible? Default is true. * @param bool $escape_html [optional] Should the content of message be HTML escaped? Default is true. */ - public static function add($message, string $type = self::INFO, bool $is_dismissible = true, bool $escape_html = true): void + public static function add(string $message, string $type = self::INFO, bool $is_dismissible = true, bool $escape_html = true): void { $classes = \implode(' ', \array_filter(['notice', $type, $is_dismissible ? 'is-dismissible' : ''])); add_action('admin_notices', function () use ($message, $classes, $escape_html) { echo '

'; - $messages = \is_array($message) ? $message : [$message]; - \array_walk($messages, function ($msg) use ($escape_html) { - echo '

' . ($escape_html ? esc_html($msg) : $msg) . '

'; - }); + echo '

' . ($escape_html ? esc_html($message) : $message) . '

'; echo '
'; }); } From 2fb54828ccfa7663cda2da9d227c90391329da0c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 15:32:26 +0100 Subject: [PATCH 26/57] Refactor IpAddress::enlist() method --- classes/BlueChip/Security/Setup/AdminPage.php | 7 ++----- classes/BlueChip/Security/Setup/IpAddress.php | 11 ++++------- classes/BlueChip/Security/Setup/Settings.php | 2 +- 3 files changed, 7 insertions(+), 13 deletions(-) diff --git a/classes/BlueChip/Security/Setup/AdminPage.php b/classes/BlueChip/Security/Setup/AdminPage.php index 89630d3..17be67f 100644 --- a/classes/BlueChip/Security/Setup/AdminPage.php +++ b/classes/BlueChip/Security/Setup/AdminPage.php @@ -126,14 +126,12 @@ public function printGoogleAPIHint(): void public function printSiteConnectionHint(): void { - $list = IpAddress::enlist(true); - echo '

'; echo esc_html__('Your server provides following information about remote addresses:', 'bc-security'); echo '

'; echo '
    '; - foreach ($list as $type => $explanation) { + foreach (IpAddress::enlist() as $type => $explanation) { if (($ip_address = IpAddress::getRaw($type))) { echo '
  1. ' . \sprintf('%s: $_SERVER[%s] = %s', esc_html($explanation), $type, $ip_address) . '
  2. '; } @@ -149,9 +147,8 @@ public function printSiteConnectionHint(): void */ private function getConnectionOptions(): array { - $list = IpAddress::enlist(true); $options = []; - foreach ($list as $type => $explanation) { + foreach (IpAddress::enlist() as $type => $explanation) { $options[$type] = \sprintf('%s: %s', $type, $explanation); } return $options; diff --git a/classes/BlueChip/Security/Setup/IpAddress.php b/classes/BlueChip/Security/Setup/IpAddress.php index fb4521f..658a86b 100644 --- a/classes/BlueChip/Security/Setup/IpAddress.php +++ b/classes/BlueChip/Security/Setup/IpAddress.php @@ -25,19 +25,16 @@ abstract class IpAddress /** * Get a list of all connection types supported by the plugin. * - * @param bool $explain Return array with type as key and explanation as value. * @return array Array of known (valid) connection types. */ - public static function enlist(bool $explain = false): array + public static function enlist(): array { - $list = [ + return [ self::REMOTE_ADDR => __('Direct connection to the Internet', 'bc-security'), self::HTTP_CF_CONNECTING_IP => __('Behind CloudFlare CDN and reverse proxy', 'bc-security'), self::HTTP_X_FORWARDED_FOR => __('Behind a reverse proxy or load balancer', 'bc-security'), self::HTTP_X_REAL_IP => __('Behind a reverse proxy or load balancer', 'bc-security'), ]; - - return $explain ? $list : \array_keys($list); } @@ -49,7 +46,7 @@ public static function enlist(bool $explain = false): array */ public static function get(string $type): string { - if (!\in_array($type, self::enlist(), true)) { + if (!\array_key_exists($type, self::enlist())) { // Invalid type, fall back to direct address. $type = self::REMOTE_ADDR; } @@ -81,7 +78,7 @@ public static function get(string $type): string */ public static function getRaw(string $type): string { - return (\in_array($type, self::enlist(), true) && isset($_SERVER[$type])) ? $_SERVER[$type] : ''; + return \array_key_exists($type, self::enlist()) ? ($_SERVER[$type] ?? '') : ''; } diff --git a/classes/BlueChip/Security/Setup/Settings.php b/classes/BlueChip/Security/Setup/Settings.php index 989f573..d7de2e2 100644 --- a/classes/BlueChip/Security/Setup/Settings.php +++ b/classes/BlueChip/Security/Setup/Settings.php @@ -43,6 +43,6 @@ class Settings extends \BlueChip\Security\Core\Settings */ public static function sanitizeConnectionType(string $value, string $default): string { - return \in_array($value, IpAddress::enlist(), true) ? $value : $default; + return \array_key_exists($value, IpAddress::enlist()) ? $value : $default; } } From bc6850f81a2e4e535fe52c42ce73d4b0a2dba2cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 15:35:43 +0100 Subject: [PATCH 27/57] Make plain array type hints more precise --- classes/BlueChip/Security/Admin.php | 4 ++-- classes/BlueChip/Security/Core/Settings.php | 4 ++-- .../BlueChip/Security/Helpers/SafeBrowsingClient.php | 4 ++-- classes/BlueChip/Security/Modules/Login/Settings.php | 4 ++-- .../Security/Modules/Notifications/Mailman.php | 10 +++++----- .../Security/Modules/Notifications/Settings.php | 4 ++-- .../Security/Modules/Notifications/Watchman.php | 4 ++-- 7 files changed, 17 insertions(+), 17 deletions(-) diff --git a/classes/BlueChip/Security/Admin.php b/classes/BlueChip/Security/Admin.php index 783d853..d74600f 100644 --- a/classes/BlueChip/Security/Admin.php +++ b/classes/BlueChip/Security/Admin.php @@ -110,8 +110,8 @@ public function makeAdminMenu(): void * * @filter https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/ * - * @param array $links - * @return array + * @param string[] $links + * @return string[] */ public function filterActionLinks(array $links): array { diff --git a/classes/BlueChip/Security/Core/Settings.php b/classes/BlueChip/Security/Core/Settings.php index 6fe50b8..ec86df0 100644 --- a/classes/BlueChip/Security/Core/Settings.php +++ b/classes/BlueChip/Security/Core/Settings.php @@ -265,8 +265,8 @@ protected static function sanitizeByType($value, $default) /** * Parse a list of items separated by EOL character into array. Trim any empty lines (items). * - * @param array|string $list - * @return array + * @param string|string[] $list + * @return string[] */ protected static function parseList($list): array { diff --git a/classes/BlueChip/Security/Helpers/SafeBrowsingClient.php b/classes/BlueChip/Security/Helpers/SafeBrowsingClient.php index bf7938b..d864fea 100644 --- a/classes/BlueChip/Security/Helpers/SafeBrowsingClient.php +++ b/classes/BlueChip/Security/Helpers/SafeBrowsingClient.php @@ -97,7 +97,7 @@ public function check(string $url): ?bool /** - * @param array $urls List of URLs to look up. + * @param string[] $urls List of URLs to look up. * @return array|null List of matches (empty means no matches found) or null on error. */ public function lookup(array $urls): ?array @@ -159,7 +159,7 @@ private static function getCacheDuration(object $match): ?int /** * @link https://developers.google.com/safe-browsing/v4/lookup-api#http-post-request * - * @param array $urls List of URLs to check + * @param string[] $urls List of URLs to check * @return array Safe Browsing request data */ private static function getRequestBody(array $urls): array diff --git a/classes/BlueChip/Security/Modules/Login/Settings.php b/classes/BlueChip/Security/Modules/Login/Settings.php index 58870e8..1055bb1 100644 --- a/classes/BlueChip/Security/Modules/Login/Settings.php +++ b/classes/BlueChip/Security/Modules/Login/Settings.php @@ -53,8 +53,8 @@ class Settings extends \BlueChip\Security\Core\Settings /** * Sanitize "username blacklist" setting. Must be list of valid usernames. * - * @param array|string $value - * @return array + * @param string|string[] $value + * @return string[] */ public static function sanitizeUsernameBlacklist($value): array { diff --git a/classes/BlueChip/Security/Modules/Notifications/Mailman.php b/classes/BlueChip/Security/Modules/Notifications/Mailman.php index 76b6534..06c4305 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Mailman.php +++ b/classes/BlueChip/Security/Modules/Notifications/Mailman.php @@ -24,9 +24,9 @@ abstract class Mailman * * @see wp_mail() * - * @param array|string $to Email address(es) of notification recipient(s). + * @param string|string[] $to Email address(es) of notification recipient(s). * @param string $subject Subject of notification. - * @param array|string $message Body of notification. + * @param string|string[] $message Body of notification. * @return bool True if notification has been sent successfully, false otherwise. */ public static function send($to, string $subject, $message): bool @@ -42,7 +42,7 @@ public static function send($to, string $subject, $message): bool /** * Strip any HTML tags from $message and add plugin boilerplate to it. * - * @param array $message Message body as list of lines. + * @param string[] $message Message body as list of lines. * @return string */ private static function formatMessage(array $message): string @@ -100,8 +100,8 @@ private static function formatSubject(string $subject): string * [1] https://www.example.com * [2] https://www.one-more-example.com/ * - * @param array $message Message as list of strings with HTML tags. - * @return array Message as list of strings without HTML tags with optional URL index appended. + * @param string[] $message Message as list of strings with HTML tags. + * @return string[] Message as list of strings without HTML tags with optional URL index appended. */ private static function stripTags(array $message): array { diff --git a/classes/BlueChip/Security/Modules/Notifications/Settings.php b/classes/BlueChip/Security/Modules/Notifications/Settings.php index 5efef5c..b990b43 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Settings.php +++ b/classes/BlueChip/Security/Modules/Notifications/Settings.php @@ -60,8 +60,8 @@ class Settings extends \BlueChip\Security\Core\Settings /** * Sanitize "notification recipients" setting. Must be list of emails. * - * @param array|string $value - * @return array + * @param string|string[] $value + * @return string[] */ public static function sanitizeNotificationRecipient($value): array { diff --git a/classes/BlueChip/Security/Modules/Notifications/Watchman.php b/classes/BlueChip/Security/Modules/Notifications/Watchman.php index e2cc02e..04db001 100644 --- a/classes/BlueChip/Security/Modules/Notifications/Watchman.php +++ b/classes/BlueChip/Security/Modules/Notifications/Watchman.php @@ -28,7 +28,7 @@ class Watchman implements Modules\Initializable, Modules\Activable private $logger; /** - * @var array List of notifications recipients + * @var string[] List of notifications recipients */ private $recipients; @@ -386,7 +386,7 @@ public function watchChecklistMultipleChecksAlert(array $issues): void * Send email notification with given $subject and $message to recipients configured in plugin settings. * * @param string $subject - * @param array|string $message + * @param string|string[] $message * @return bool|null Null if there are no recipients configured. True if email has been sent, false otherwise. */ private function notify(string $subject, $message): ?bool From 69394ef28bd4e73076f1802d56a01dae1dcea37d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=8Ceslav=20Przywara?= Date: Wed, 16 Feb 2022 16:12:17 +0100 Subject: [PATCH 28/57] Let comments breathe :-) --- classes/BlueChip/Security/Admin.php | 4 ++ .../BlueChip/Security/Core/AssetsManager.php | 4 ++ classes/BlueChip/Security/Core/ListTable.php | 4 ++ classes/BlueChip/Security/Core/Settings.php | 9 ++++ .../BlueChip/Security/Helpers/FormHelper.php | 2 + .../Security/Helpers/HaveIBeenPwned.php | 3 ++ classes/BlueChip/Security/Helpers/Is.php | 2 + .../Security/Helpers/MySQLDateTime.php | 2 + classes/BlueChip/Security/Helpers/Plugin.php | 10 ++++ .../Security/Helpers/SafeBrowsingClient.php | 5 ++ .../BlueChip/Security/Helpers/Transients.php | 4 ++ .../BlueChip/Security/Helpers/WpRemote.php | 2 + .../Checklist/Checks/CoreIntegrity.php | 3 ++ .../Checks/NoPluginsRemovedFromDirectory.php | 2 + .../Checklist/Checks/PluginsIntegrity.php | 1 + .../Security/Modules/Checklist/Helper.php | 5 ++ .../Security/Modules/Checklist/Manager.php | 6 +++ .../BlueChip/Security/Modules/Countable.php | 1 + .../BlueChip/Security/Modules/Cron/Job.php | 1 + .../Security/Modules/Cron/Manager.php | 3 ++ .../Security/Modules/Hardening/Core.php | 6 +++ .../Modules/IpBlacklist/AdminPage.php | 1 + .../Security/Modules/IpBlacklist/Bouncer.php | 1 + .../Modules/IpBlacklist/ListTable.php | 5 ++ .../Security/Modules/IpBlacklist/Manager.php | 11 +++++ .../BlueChip/Security/Modules/Log/Action.php | 49 +++++++++++++++---- .../BlueChip/Security/Modules/Log/Event.php | 1 + .../Security/Modules/Log/EventsManager.php | 5 +- .../Security/Modules/Log/ListTable.php | 27 ++++++++-- .../BlueChip/Security/Modules/Log/Logger.php | 4 ++ .../Security/Modules/Login/Bookkeeper.php | 1 + .../Security/Modules/Login/Gatekeeper.php | 7 ++- .../Security/Modules/Login/Settings.php | 29 ++++++++--- .../Modules/Notifications/Mailman.php | 4 ++ .../Modules/Notifications/Settings.php | 37 ++++++++++---- .../Modules/Notifications/Watchman.php | 2 + .../Services/ReverseDnsLookup/Resolver.php | 1 + classes/BlueChip/Security/Plugin.php | 1 + classes/BlueChip/Security/Setup/IpAddress.php | 3 ++ classes/BlueChip/Security/Setup/Settings.php | 1 + 40 files changed, 236 insertions(+), 33 deletions(-) diff --git a/classes/BlueChip/Security/Admin.php b/classes/BlueChip/Security/Admin.php index d74600f..beff268 100644 --- a/classes/BlueChip/Security/Admin.php +++ b/classes/BlueChip/Security/Admin.php @@ -28,6 +28,7 @@ class Admin * Initialize admin area of the plugin. * * @param string $plugin_filename + * * @return self */ public function init(string $plugin_filename): self @@ -43,6 +44,7 @@ public function init(string $plugin_filename): self * Add a page to plugin dashboard menu. * * @param \BlueChip\Security\Core\Admin\AbstractPage $page + * * @return self */ public function addPage(Core\Admin\AbstractPage $page): self @@ -111,6 +113,7 @@ public function makeAdminMenu(): void * @filter https://developer.wordpress.org/reference/hooks/plugin_action_links_plugin_file/ * * @param string[] $links + * * @return string[] */ public function filterActionLinks(array $links): array @@ -130,6 +133,7 @@ public function filterActionLinks(array $links): array * Format counter indicator for menu title for given $page. * * @param \BlueChip\Security\Core\Admin\AbstractPage $page + * * @return string */ private function renderCounter(Core\Admin\AbstractPage $page): string diff --git a/classes/BlueChip/Security/Core/AssetsManager.php b/classes/BlueChip/Security/Core/AssetsManager.php index d9a7a7a..422b77c 100644 --- a/classes/BlueChip/Security/Core/AssetsManager.php +++ b/classes/BlueChip/Security/Core/AssetsManager.php @@ -31,6 +31,7 @@ public function __construct(string $plugin_filename) /** * @param string $filename Asset filename (ie. asset.js). + * * @return string Absolute path to the asset. */ public function getScriptFilePath(string $filename): string @@ -41,6 +42,7 @@ public function getScriptFilePath(string $filename): string /** * @param string $filename Asset filename (ie. asset.js). + * * @return string URL of the asset. */ public function getScriptFileUrl(string $filename): string @@ -51,6 +53,7 @@ public function getScriptFileUrl(string $filename): string /** * @param string $filename Asset filename (ie. asset.css). + * * @return string Absolute path to the asset. */ public function getStyleFilePath(string $filename): string @@ -61,6 +64,7 @@ public function getStyleFilePath(string $filename): string /** * @param string $filename Asset filename (ie. asset.css). + * * @return string URL of the asset. */ public function getStyleFileUrl(string $filename): string diff --git a/classes/BlueChip/Security/Core/ListTable.php b/classes/BlueChip/Security/Core/ListTable.php index d8f7da8..b1d9423 100644 --- a/classes/BlueChip/Security/Core/ListTable.php +++ b/classes/BlueChip/Security/Core/ListTable.php @@ -104,6 +104,7 @@ protected function displayNotice(string $action, string $single, string $plural) * @param int $id * @param string $class * @param string $label + * * @return string */ protected function renderRowAction(string $action, int $id, string $class, string $label): string @@ -127,6 +128,7 @@ protected function renderRowAction(string $action, int $id, string $class, strin * Return content for "checkbox" column. * * @param array $item + * * @return string */ public function column_cb($item) // phpcs:ignore @@ -140,6 +142,7 @@ public function column_cb($item) // phpcs:ignore * * @param array $item * @param string $column_name + * * @return string */ public function column_default($item, $column_name) // phpcs:ignore @@ -152,6 +155,7 @@ public function column_default($item, $column_name) // phpcs:ignore * Display datetime database fields in local time. * * @param string $datetime Datetime string retrieved from database. + * * @return string Date and time of $datetime formatted in local time. */ public function formatDateAndTime(string $datetime): string diff --git a/classes/BlueChip/Security/Core/Settings.php b/classes/BlueChip/Security/Core/Settings.php index ec86df0..dfa36da 100644 --- a/classes/BlueChip/Security/Core/Settings.php +++ b/classes/BlueChip/Security/Core/Settings.php @@ -48,6 +48,7 @@ public function __construct(string $option_name) * Get value of setting under key $name. * * @param string $name + * * @return mixed A null value is returned if $name is not a valid key. */ public function __get(string $name) @@ -85,6 +86,7 @@ public function __set(string $name, $value): void * @internal Implements ArrayAccess interface. * * @param string $offset + * * @return bool */ public function offsetExists($offset): bool @@ -99,6 +101,7 @@ public function offsetExists($offset): bool * @internal Implements ArrayAccess interface. * * @param string $offset + * * @return mixed A null value is returned if $offset is not a valid key. */ public function offsetGet($offset) @@ -160,6 +163,7 @@ public function get(): array * Set $data as option data. * * @param array $data + * * @return bool */ public function set(array $data): bool @@ -215,6 +219,7 @@ public function persist(): bool * * @param array $settings Input data to sanitize. * @param array $defaults [optional] If provided, used as default values for sanitization instead of local data. + * * @return array */ public function sanitize(array $settings, array $defaults = []): array @@ -244,6 +249,7 @@ public function sanitize(array $settings, array $defaults = []): array * * @param mixed $value * @param mixed $default + * * @return mixed */ protected static function sanitizeByType($value, $default) @@ -266,6 +272,7 @@ protected static function sanitizeByType($value, $default) * Parse a list of items separated by EOL character into array. Trim any empty lines (items). * * @param string|string[] $list + * * @return string[] */ protected static function parseList($list): array @@ -279,6 +286,7 @@ protected static function parseList($list): array * * @param string $name * @param mixed $value + * * @return bool */ protected function update(string $name, $value): bool @@ -325,6 +333,7 @@ public function addUpdateHook(callable $callback): void /** * @action https://developer.wordpress.org/reference/hooks/update_option_option/ + * * @param array $old_value * @param array $new_value */ diff --git a/classes/BlueChip/Security/Helpers/FormHelper.php b/classes/BlueChip/Security/Helpers/FormHelper.php index 5cae45f..19e533e 100644 --- a/classes/BlueChip/Security/Helpers/FormHelper.php +++ b/classes/BlueChip/Security/Helpers/FormHelper.php @@ -6,6 +6,7 @@ abstract class FormHelper { /** * @link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/textarea + * * @var int Default value of "cols" attribute of
' . esc_html__('Monitor', 'bc-security') . '