diff --git a/src/Backend.php b/src/Backend.php index 211bb93..24bf31f 100644 --- a/src/Backend.php +++ b/src/Backend.php @@ -14,7 +14,6 @@ declare(strict_types=1); namespace Dotclear\Plugin\httpPassword; -use dcAuth; use dcAdmin; use dcCore; use dcPage; @@ -31,10 +30,11 @@ class Backend extends dcNsProcess public static function process(): bool { - if (!static::$init) { + if (!static::$init || is_null(dcCore::app()->auth) || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) { return false; } + // add backend sidebar menu icon dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem( My::name(), dcCore::app()->adminurl->get('admin.plugin.' . My::id()), diff --git a/src/Frontend.php b/src/Frontend.php index 9936da4..57d07ab 100644 --- a/src/Frontend.php +++ b/src/Frontend.php @@ -33,7 +33,12 @@ class Frontend extends dcNsProcess return false; } + // check password on frontend dcCore::app()->addBehavior('publicPrependV2', function (): void { + // nullsafe + if (is_null(dcCore::app()->blog)) { + return; + } $PHP_AUTH_USER = $PHP_AUTH_PW = ''; if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) { diff --git a/src/Install.php b/src/Install.php index f8774f6..cd47085 100644 --- a/src/Install.php +++ b/src/Install.php @@ -22,14 +22,15 @@ class Install extends dcNsProcess { public static function init(): bool { - static::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version')); + static::$init = defined('DC_CONTEXT_ADMIN') + && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version')); return static::$init; } public static function process(): bool { - if (!static::$init) { + if (!static::$init || is_null(dcCore::app()->blog)) { return false; } diff --git a/src/Manage.php b/src/Manage.php index 4e57fff..3186d54 100644 --- a/src/Manage.php +++ b/src/Manage.php @@ -40,18 +40,21 @@ class Manage extends dcNsProcess { public static function init(): bool { - static::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->auth->check( - dcCore::app()->auth->makePermissions([ - My::PERMISSION, - ]), dcCore::app()->blog->id - ); + static::$init = defined('DC_CONTEXT_ADMIN') + && !is_null(dcCore::app()->auth) && !is_null(dcCore::app()->blog) // nullsafe + && dcCore::app()->auth->check( + dcCore::app()->auth->makePermissions([ + My::PERMISSION, + ]), + dcCore::app()->blog->id + ); return static::$init; } public static function process(): bool { - if (!static::$init) { + if (!static::$init || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) { return false; } @@ -67,6 +70,7 @@ class Manage extends dcNsProcess return true; } + // save settings if ('savesettings' == $action) { $s = dcCore::app()->blog->settings->get(My::id()); $s->put('active', !empty($_POST['active'])); @@ -85,6 +89,7 @@ class Manage extends dcNsProcess ); } + // delete users logins if ('savelogins' == $action) { $logs = dcCore::app()->log->getLogs(['log_table' => My::id()]); if (!$logs->isEmpty()) { @@ -105,6 +110,7 @@ class Manage extends dcNsProcess } } + // save users logins / passwords in frontend passwords file if ('savepasswords' == $action) { $passwords = self::getPasswords(); $lines = []; @@ -153,7 +159,7 @@ class Manage extends dcNsProcess public static function render(): void { - if (!static::$init) { + if (!static::$init || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) { return; } @@ -173,7 +179,7 @@ class Manage extends dcNsProcess ]) . dcPage::notices() . - # Filters select menu list + // Filters select menu list (new Form('section_menu'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->method('get')->fields([ (new Para())->class('anchor-nav')->items([ (new Label(__('Select section:')))->for('part')->class('classic'), @@ -185,6 +191,7 @@ class Manage extends dcNsProcess '

' . array_search($part, My::sectionCombo()) . '

'; + // settigns form if ('settings' == $part) { echo (new Form('section_settings'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'settings']))->method('post')->fields([ @@ -214,6 +221,7 @@ class Manage extends dcNsProcess ])->render(); } + // delete logins form if ('logins' == $part) { $logs = dcCore::app()->log->getLogs(['log_table' => My::id()]); if ($logs->isEmpty()) { @@ -250,6 +258,7 @@ class Manage extends dcNsProcess } } + // existing logins/passwords form if ('passwords' == $part) { $passwords = self::getPasswords(); @@ -295,6 +304,7 @@ class Manage extends dcNsProcess ])->render(); } + // new login form echo (new Form('section_new'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => $part]))->method('post')->fields([ (new Text('h3', Html::escapeHTML(__('Add a user')))), @@ -320,6 +330,11 @@ class Manage extends dcNsProcess dcPage::closeModule(); } + /** + * Get page section. + * + * @return string The section + */ private static function getSection(): string { $part = $_REQUEST['part'] ?? 'settings'; @@ -330,6 +345,11 @@ class Manage extends dcNsProcess return $part; } + /** + * Get existing passwords from file. + * + * @return array The passwords list + */ private static function getPasswords(): array { $passwords = []; diff --git a/src/Prepend.php b/src/Prepend.php index 1979625..6fc4430 100644 --- a/src/Prepend.php +++ b/src/Prepend.php @@ -28,10 +28,11 @@ class Prepend extends dcNsProcess public static function process(): bool { - if (!static::$init) { + if (!static::$init || is_null(dcCore::app()->auth)) { return false; } + // register module permission dcCore::app()->auth->setPermissionType( My::PERMISSION, __('Manage http password blog protection') diff --git a/src/Utils.php b/src/Utils.php index 716c5b3..9c7af5b 100644 --- a/src/Utils.php +++ b/src/Utils.php @@ -20,9 +20,15 @@ class Utils { /** * Crypt password + * + * @param string $secret The secret + * + * @return string The crypt password (empty on error) */ public static function crypt(?string $secret): string { + $secret = (string) $secret; + switch (self::cryptMethod()) { case 'plaintext': $saltlen = -1; @@ -72,43 +78,53 @@ class Utils $secret = crypt($secret, $salt); } - return($secret); + return $secret; } /** * Setting: active + * + * @return bool True if module is active */ public static function isActive(): bool { - return (bool) dcCore::app()->blog->settings->get(My::id())->get('active'); + return !is_null(dcCore::app()->blog) && (bool) dcCore::app()->blog->settings->get(My::id())->get('active'); } /** * Setting: crypt + * + * @return string The crypt method */ public static function cryptMethod(): string { - return (string) dcCore::app()->blog->settings->get(My::id())->get('crypt'); + return is_null(dcCore::app()->blog) ? '' : (string) dcCore::app()->blog->settings->get(My::id())->get('crypt'); } /** * Setting: message + * + * @return string The frontend message */ public static function httpMessage(): string { - return (string) dcCore::app()->blog->settings->get(My::id())->get('message'); + return is_null(dcCore::app()->blog) ? '' : (string) dcCore::app()->blog->settings->get(My::id())->get('message'); } /** * Get passwords file path + * + * @return string The passwords file path (empty on error) */ public static function passwordFile(): string { - return dcCore::app()->blog->public_path . DIRECTORY_SEPARATOR . My::FILE_PASSWORD; + return is_null(dcCore::app()->blog) ? '' : dcCore::app()->blog->public_path . DIRECTORY_SEPARATOR . My::FILE_PASSWORD; } /** * Check passwords file + * + * @return bool True if passwords file is writable */ public static function isWritable(): bool {