Compare commits
10 Commits
3a6dc3fc82
...
12fb9cd689
Author | SHA1 | Date |
---|---|---|
Jean-Christian Paul Denis | 12fb9cd689 | |
Jean-Christian Paul Denis | f28ffa423e | |
Jean-Christian Paul Denis | 7a3117e1ac | |
Jean-Christian Paul Denis | e9242f40c3 | |
Jean-Christian Paul Denis | 3b0d213722 | |
Jean-Christian Paul Denis | 086ef53c25 | |
Jean-Christian Paul Denis | daf242ce90 | |
Jean-Christian Paul Denis | 4dbdb4390e | |
Jean-Christian Paul Denis | 02480c5b3f | |
Jean-Christian Paul Denis | ecc0ac08d8 |
12
CHANGELOG.md
12
CHANGELOG.md
|
@ -1,3 +1,15 @@
|
||||||
|
1.3 - 2023.05.13
|
||||||
|
- require dotclear 2.26
|
||||||
|
- fix type hint and nullsafe warnings
|
||||||
|
|
||||||
|
1.2 - 2023.04.22
|
||||||
|
- require dotclear 2.26
|
||||||
|
- add plugin Uninstaller features
|
||||||
|
- use latest dotclear namespace
|
||||||
|
- fix static init
|
||||||
|
- fix permission
|
||||||
|
- code doc and review
|
||||||
|
|
||||||
1.1 - 2023.03.25
|
1.1 - 2023.03.25
|
||||||
- require dotclear 2.26
|
- require dotclear 2.26
|
||||||
- use namespace
|
- use namespace
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
* @copyright Jean-Christian Denis
|
* @copyright Jean-Christian Denis
|
||||||
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
*/
|
*/
|
||||||
if (!defined('DC_RC_PATH')) {
|
if (!defined('DC_RC_PATH') || is_null(dcCore::app()->auth)) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,11 +18,11 @@ $this->registerModule(
|
||||||
'Http password',
|
'Http password',
|
||||||
'Manage .htpasswd file to make the blog private',
|
'Manage .htpasswd file to make the blog private',
|
||||||
'Frederic PLE and contributors',
|
'Frederic PLE and contributors',
|
||||||
'1.1',
|
'1.3',
|
||||||
[
|
[
|
||||||
'requires' => [['core', '2.26']],
|
'requires' => [['core', '2.26']],
|
||||||
'permissions' => dcCore::app()->auth->makePermissions([
|
'permissions' => dcCore::app()->auth->makePermissions([
|
||||||
dcAuth::PERMISSION_USAGE,
|
dcCore::app()->auth::PERMISSION_USAGE,
|
||||||
initHttpPassword::PERMISSION,
|
initHttpPassword::PERMISSION,
|
||||||
]),
|
]),
|
||||||
'type' => 'plugin',
|
'type' => 'plugin',
|
||||||
|
|
|
@ -2,10 +2,10 @@
|
||||||
<modules xmlns:da="http://dotaddict.org/da/">
|
<modules xmlns:da="http://dotaddict.org/da/">
|
||||||
<module id="httpPassword">
|
<module id="httpPassword">
|
||||||
<name>Http password</name>
|
<name>Http password</name>
|
||||||
<version>1.1</version>
|
<version>1.3</version>
|
||||||
<author>Frederic PLE and contributors</author>
|
<author>Frederic PLE and contributors</author>
|
||||||
<desc>Manage .htpasswd file to make the blog private</desc>
|
<desc>Manage .htpasswd file to make the blog private</desc>
|
||||||
<file>https://github.com/JcDenis/httpPassword/releases/download/v1.1/plugin-httpPassword.zip</file>
|
<file>https://github.com/JcDenis/httpPassword/releases/download/v1.3/plugin-httpPassword.zip</file>
|
||||||
<da:dcmin>2.26</da:dcmin>
|
<da:dcmin>2.26</da:dcmin>
|
||||||
<da:details>http://plugins.dotaddict.org/dc2/details/httpPassword</da:details>
|
<da:details>http://plugins.dotaddict.org/dc2/details/httpPassword</da:details>
|
||||||
<da:support>https://github.com/JcDenis/httpPassword</da:support>
|
<da:support>https://github.com/JcDenis/httpPassword</da:support>
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.0//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||||
|
<svg version="1.0" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||||
|
width="64px" height="64px" viewBox="0 0 64 64" enable-background="new 0 0 64 64" xml:space="preserve">
|
||||||
|
<g>
|
||||||
|
<circle fill="#676e78" cx="24" cy="24" r="16"/>
|
||||||
|
<g>
|
||||||
|
<path fill="#a2cbe9" d="M45.863,33.859C47.223,30.852,48,27.516,48,24C48,10.742,37.254,0,24,0S0,10.742,0,24
|
||||||
|
c0,13.25,10.746,24,24,24c3.52,0,6.852-0.781,9.863-2.141L36,48h8v8h8v8h12V52L45.863,33.859z M24,40c-8.836,0-16-7.164-16-16
|
||||||
|
S15.164,8,24,8s16,7.164,16,16S32.836,40,24,40z"/>
|
||||||
|
<path fill="#a2cbe9" d="M24,16c-4.422,0-8,3.578-8,8s3.578,8,8,8s8-3.578,8-8S28.422,16,24,16z"/>
|
||||||
|
</g>
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 835 B |
|
@ -9,27 +9,29 @@
|
||||||
# DOT NOT MODIFY THIS FILE !
|
# DOT NOT MODIFY THIS FILE !
|
||||||
#
|
#
|
||||||
|
|
||||||
l10n::$locales['Manage http password blog protection'] = 'Gérer la protection du blog par mot de passe HTTP';
|
use Dotclear\Helper\L10n;
|
||||||
l10n::$locales['No encryption'] = 'pas de cryptage';
|
|
||||||
l10n::$locales['Logins history'] = 'Historique des logins';
|
L10n::$locales['Manage http password blog protection'] = 'Gérer la protection du blog par mot de passe HTTP';
|
||||||
l10n::$locales['Authorized users'] = 'Utilisateurs autorisés';
|
L10n::$locales['No encryption'] = 'pas de cryptage';
|
||||||
l10n::$locales['No write permissions on blogs directories.'] = 'Aucun droit d\'écriture sur le répertoire du blog.';
|
L10n::$locales['Logins history'] = 'Historique des logins';
|
||||||
l10n::$locales['Settings successfully updated.'] = 'Paramètres mis à jour.';
|
L10n::$locales['Authorized users'] = 'Utilisateurs autorisés';
|
||||||
l10n::$locales['Logs successfully cleared.'] = 'Logs effacé.';
|
L10n::$locales['No write permissions on blogs directories.'] = 'Aucun droit d\'écriture sur le répertoire du blog.';
|
||||||
l10n::$locales['Logins successfully updated.'] = 'Logins mis à jour.';
|
L10n::$locales['Settings successfully updated.'] = 'Paramètres mis à jour.';
|
||||||
l10n::$locales['Select section:'] = 'Sélectionner une section :';
|
L10n::$locales['Logs successfully cleared.'] = 'Logs effacé.';
|
||||||
l10n::$locales['Enable http password protection on this blog'] = 'Activer la protection du blog par mot de passe http';
|
L10n::$locales['Logins successfully updated.'] = 'Logins mis à jour.';
|
||||||
l10n::$locales['Crypt algorithm:'] = 'Algorithme de cryptage :';
|
L10n::$locales['Select section:'] = 'Sélectionner une section :';
|
||||||
l10n::$locales['Some web servers does not surpport plaintext (no) encryption.'] = 'Certains serveurs web ne supportent pas le cryptage "plaintext".';
|
L10n::$locales['Enable http password protection on this blog'] = 'Activer la protection du blog par mot de passe http';
|
||||||
l10n::$locales['If you change crypt algo, you must edit and resave each users passwords.'] = 'Si vous changer l\'algorithme de cryptage, vous devrez modifier et sauver tous les mots de passes.';
|
L10n::$locales['Crypt algorithm:'] = 'Algorithme de cryptage :';
|
||||||
l10n::$locales['Authentication message:'] = 'Message d\'authentification :';
|
L10n::$locales['Some web servers does not surpport plaintext (no) encryption.'] = 'Certains serveurs web ne supportent pas le cryptage "plaintext".';
|
||||||
l10n::$locales['Logins history is empty.'] = 'L\'historique des logins est vide.';
|
L10n::$locales['If you change crypt algo, you must edit and resave each users passwords.'] = 'Si vous changer l\'algorithme de cryptage, vous devrez modifier et sauver tous les mots de passes.';
|
||||||
l10n::$locales['Clear logs'] = 'Effacer les logs';
|
L10n::$locales['Authentication message:'] = 'Message d\'authentification :';
|
||||||
l10n::$locales['List of %s last logins.'] = 'Liste des %s derniers logins.';
|
L10n::$locales['Logins history is empty.'] = 'L\'historique des logins est vide.';
|
||||||
l10n::$locales['Authorized users list is empty.'] = 'La listes des utilisateurs autorisés est vide.';
|
L10n::$locales['Clear logs'] = 'Effacer les logs';
|
||||||
l10n::$locales['List of %s authorized users.'] = 'Liste des %s utilisateurs autorisés.';
|
L10n::$locales['List of %s last logins.'] = 'Liste des %s derniers logins.';
|
||||||
l10n::$locales['New password'] = 'Nouveau mot de passe';
|
L10n::$locales['Authorized users list is empty.'] = 'La listes des utilisateurs autorisés est vide.';
|
||||||
l10n::$locales['Change password'] = 'Modifier le mot de passe';
|
L10n::$locales['List of %s authorized users.'] = 'Liste des %s utilisateurs autorisés.';
|
||||||
l10n::$locales['Add a user'] = 'Ajouter un utilisateur';
|
L10n::$locales['New password'] = 'Nouveau mot de passe';
|
||||||
l10n::$locales['Login:'] = 'Identifiant :';
|
L10n::$locales['Change password'] = 'Modifier le mot de passe';
|
||||||
l10n::$locales['Manage .htpasswd file to make the blog private'] = 'Gestion du fichier .htpasswd pour rendre le blog privé.';
|
L10n::$locales['Add a user'] = 'Ajouter un utilisateur';
|
||||||
|
L10n::$locales['Login:'] = 'Identifiant :';
|
||||||
|
L10n::$locales['Manage .htpasswd file to make the blog private'] = 'Gestion du fichier .htpasswd pour rendre le blog privé.';
|
||||||
|
|
|
@ -14,10 +14,10 @@ declare(strict_types=1);
|
||||||
|
|
||||||
namespace Dotclear\Plugin\httpPassword;
|
namespace Dotclear\Plugin\httpPassword;
|
||||||
|
|
||||||
use dcAuth;
|
|
||||||
use dcAdmin;
|
use dcAdmin;
|
||||||
use dcCore;
|
use dcCore;
|
||||||
use dcPage;
|
use dcPage;
|
||||||
|
use dcMenu;
|
||||||
use dcNsProcess;
|
use dcNsProcess;
|
||||||
|
|
||||||
class Backend extends dcNsProcess
|
class Backend extends dcNsProcess
|
||||||
|
@ -31,20 +31,22 @@ class Backend extends dcNsProcess
|
||||||
|
|
||||||
public static function process(): bool
|
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;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
// add backend sidebar menu icon
|
||||||
My::name(),
|
if ((dcCore::app()->menu[dcAdmin::MENU_PLUGINS] instanceof dcMenu)) {
|
||||||
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
dcCore::app()->menu[dcAdmin::MENU_PLUGINS]->addItem(
|
||||||
dcPage::getPF(My::id() . '/icon.png'),
|
My::name(),
|
||||||
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
|
dcCore::app()->adminurl->get('admin.plugin.' . My::id()),
|
||||||
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
dcPage::getPF(My::id() . '/icon.svg'),
|
||||||
dcAuth::PERMISSION_USAGE,
|
preg_match('/' . preg_quote(dcCore::app()->adminurl->get('admin.plugin.' . My::id())) . '(&.*)?$/', $_SERVER['REQUEST_URI']),
|
||||||
My::PERMISSION,
|
dcCore::app()->auth->check(dcCore::app()->auth->makePermissions([
|
||||||
]), dcCore::app()->blog->id)
|
My::PERMISSION,
|
||||||
);
|
]), dcCore::app()->blog->id)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,12 @@ class Frontend extends dcNsProcess
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// check password on frontend
|
||||||
dcCore::app()->addBehavior('publicPrependV2', function (): void {
|
dcCore::app()->addBehavior('publicPrependV2', function (): void {
|
||||||
|
// nullsafe
|
||||||
|
if (is_null(dcCore::app()->blog)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
$PHP_AUTH_USER = $PHP_AUTH_PW = '';
|
$PHP_AUTH_USER = $PHP_AUTH_PW = '';
|
||||||
|
|
||||||
if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) {
|
if (isset($_SERVER['PHP_AUTH_USER']) and isset($_SERVER['PHP_AUTH_PW'])) {
|
||||||
|
@ -74,7 +79,7 @@ class Frontend extends dcNsProcess
|
||||||
if (!$logs->isEmpty()) {
|
if (!$logs->isEmpty()) {
|
||||||
$ids = [];
|
$ids = [];
|
||||||
while ($logs->fetch()) {
|
while ($logs->fetch()) {
|
||||||
$ids[] = (int) $logs->f('log_id');
|
$ids[] = is_numeric($logs->f('log_id')) ? (int) $logs->f('log_id') : 0;
|
||||||
}
|
}
|
||||||
$logs = dcCore::app()->log->delLogs($ids);
|
$logs = dcCore::app()->log->delLogs($ids);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,14 +22,17 @@ class Install extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function init(): bool
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
static::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->newVersion(My::id(), dcCore::app()->plugins->moduleInfo(My::id(), 'version'));
|
if (defined('DC_CONTEXT_ADMIN')) {
|
||||||
|
$version = dcCore::app()->plugins->moduleInfo(My::id(), 'version');
|
||||||
|
static::$init = is_string($version) ? dcCore::app()->newVersion(My::id(), $version) : true;
|
||||||
|
}
|
||||||
|
|
||||||
return static::$init;
|
return static::$init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function process(): bool
|
public static function process(): bool
|
||||||
{
|
{
|
||||||
if (!static::$init) {
|
if (!static::$init || is_null(dcCore::app()->blog)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ namespace Dotclear\Plugin\httpPassword;
|
||||||
use dcCore;
|
use dcCore;
|
||||||
use dcNsProcess;
|
use dcNsProcess;
|
||||||
use dcPage;
|
use dcPage;
|
||||||
|
use Dotclear\Helper\Date;
|
||||||
use Dotclear\Helper\Html\Html;
|
use Dotclear\Helper\Html\Html;
|
||||||
use Dotclear\Helper\Html\Form\{
|
use Dotclear\Helper\Html\Form\{
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
@ -31,7 +32,6 @@ use Dotclear\Helper\Html\Form\{
|
||||||
Submit,
|
Submit,
|
||||||
Text
|
Text
|
||||||
};
|
};
|
||||||
use dt;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manage contributions list
|
* Manage contributions list
|
||||||
|
@ -40,18 +40,21 @@ class Manage extends dcNsProcess
|
||||||
{
|
{
|
||||||
public static function init(): bool
|
public static function init(): bool
|
||||||
{
|
{
|
||||||
static::$init = defined('DC_CONTEXT_ADMIN') && dcCore::app()->auth->check(
|
static::$init = defined('DC_CONTEXT_ADMIN')
|
||||||
dcCore::app()->auth->makePermissions([
|
&& !is_null(dcCore::app()->auth) && !is_null(dcCore::app()->blog) // nullsafe
|
||||||
My::PERMISSION,
|
&& dcCore::app()->auth->check(
|
||||||
]), dcCore::app()->blog->id
|
dcCore::app()->auth->makePermissions([
|
||||||
);
|
My::PERMISSION,
|
||||||
|
]),
|
||||||
|
dcCore::app()->blog->id
|
||||||
|
);
|
||||||
|
|
||||||
return static::$init;
|
return static::$init;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function process(): bool
|
public static function process(): bool
|
||||||
{
|
{
|
||||||
if (!static::$init) {
|
if (!static::$init || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -67,6 +70,7 @@ class Manage extends dcNsProcess
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save settings
|
||||||
if ('savesettings' == $action) {
|
if ('savesettings' == $action) {
|
||||||
$s = dcCore::app()->blog->settings->get(My::id());
|
$s = dcCore::app()->blog->settings->get(My::id());
|
||||||
$s->put('active', !empty($_POST['active']));
|
$s->put('active', !empty($_POST['active']));
|
||||||
|
@ -85,6 +89,7 @@ class Manage extends dcNsProcess
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete users logins
|
||||||
if ('savelogins' == $action) {
|
if ('savelogins' == $action) {
|
||||||
$logs = dcCore::app()->log->getLogs(['log_table' => My::id()]);
|
$logs = dcCore::app()->log->getLogs(['log_table' => My::id()]);
|
||||||
if (!$logs->isEmpty()) {
|
if (!$logs->isEmpty()) {
|
||||||
|
@ -105,6 +110,7 @@ class Manage extends dcNsProcess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// save users logins / passwords in frontend passwords file
|
||||||
if ('savepasswords' == $action) {
|
if ('savepasswords' == $action) {
|
||||||
$passwords = self::getPasswords();
|
$passwords = self::getPasswords();
|
||||||
$lines = [];
|
$lines = [];
|
||||||
|
@ -153,7 +159,7 @@ class Manage extends dcNsProcess
|
||||||
|
|
||||||
public static function render(): void
|
public static function render(): void
|
||||||
{
|
{
|
||||||
if (!static::$init) {
|
if (!static::$init || is_null(dcCore::app()->blog) || is_null(dcCore::app()->adminurl)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -173,7 +179,7 @@ class Manage extends dcNsProcess
|
||||||
]) .
|
]) .
|
||||||
dcPage::notices() .
|
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 Form('section_menu'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id()))->method('get')->fields([
|
||||||
(new Para())->class('anchor-nav')->items([
|
(new Para())->class('anchor-nav')->items([
|
||||||
(new Label(__('Select section:')))->for('part')->class('classic'),
|
(new Label(__('Select section:')))->for('part')->class('classic'),
|
||||||
|
@ -185,6 +191,7 @@ class Manage extends dcNsProcess
|
||||||
|
|
||||||
'<h3>' . array_search($part, My::sectionCombo()) . '</h3>';
|
'<h3>' . array_search($part, My::sectionCombo()) . '</h3>';
|
||||||
|
|
||||||
|
// settigns form
|
||||||
if ('settings' == $part) {
|
if ('settings' == $part) {
|
||||||
echo
|
echo
|
||||||
(new Form('section_settings'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'settings']))->method('post')->fields([
|
(new Form('section_settings'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => 'settings']))->method('post')->fields([
|
||||||
|
@ -209,11 +216,12 @@ class Manage extends dcNsProcess
|
||||||
(new Submit(['save']))->value(__('Save')),
|
(new Submit(['save']))->value(__('Save')),
|
||||||
(new Hidden(['action'], 'savesettings')),
|
(new Hidden(['action'], 'savesettings')),
|
||||||
(new Hidden(['part'], $part)),
|
(new Hidden(['part'], $part)),
|
||||||
(new Text('', dcCore::app()->formNonce())),
|
dcCore::app()->formNonce(false),
|
||||||
]),
|
]),
|
||||||
])->render();
|
])->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// delete logins form
|
||||||
if ('logins' == $part) {
|
if ('logins' == $part) {
|
||||||
$logs = dcCore::app()->log->getLogs(['log_table' => My::id()]);
|
$logs = dcCore::app()->log->getLogs(['log_table' => My::id()]);
|
||||||
if ($logs->isEmpty()) {
|
if ($logs->isEmpty()) {
|
||||||
|
@ -226,7 +234,7 @@ class Manage extends dcNsProcess
|
||||||
(new Submit(['save']))->value(__('Clear logs')),
|
(new Submit(['save']))->value(__('Clear logs')),
|
||||||
(new Hidden(['action'], 'savelogins')),
|
(new Hidden(['action'], 'savelogins')),
|
||||||
(new Hidden(['part'], $part)),
|
(new Hidden(['part'], $part)),
|
||||||
(new Text('', dcCore::app()->formNonce())),
|
dcCore::app()->formNonce(false),
|
||||||
]),
|
]),
|
||||||
])->render() .
|
])->render() .
|
||||||
|
|
||||||
|
@ -238,10 +246,12 @@ class Manage extends dcNsProcess
|
||||||
'</tr></thead<tbody>';
|
'</tr></thead<tbody>';
|
||||||
|
|
||||||
while ($logs->fetch()) {
|
while ($logs->fetch()) {
|
||||||
|
$msg = is_string($logs->f('log_msg')) ? $logs->f('log_msg') : '';
|
||||||
|
$dt = is_string($logs->f('log_dt')) ? $logs->f('log_dt') : '';
|
||||||
echo
|
echo
|
||||||
'<tr class="line">' .
|
'<tr class="line">' .
|
||||||
'<td class="nowrap maximal">' . Html::escapeHTML($logs->f('log_msg')) . '</td>' .
|
'<td class="nowrap maximal">' . Html::escapeHTML($msg) . '</td>' .
|
||||||
'<td class="nowrap count">' . Html::escapeHTML(dt::dt2str(__('%Y-%m-%d %H:%M'), $logs->f('log_dt'))) . '</td>' .
|
'<td class="nowrap count">' . Html::escapeHTML(Date::dt2str(__('%Y-%m-%d %H:%M'), $dt)) . '</td>' .
|
||||||
'</tr>';
|
'</tr>';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -250,6 +260,7 @@ class Manage extends dcNsProcess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// existing logins/passwords form
|
||||||
if ('passwords' == $part) {
|
if ('passwords' == $part) {
|
||||||
$passwords = self::getPasswords();
|
$passwords = self::getPasswords();
|
||||||
|
|
||||||
|
@ -290,11 +301,12 @@ class Manage extends dcNsProcess
|
||||||
(new Para())->items([
|
(new Para())->items([
|
||||||
(new Hidden(['action'], 'savepasswords')),
|
(new Hidden(['action'], 'savepasswords')),
|
||||||
(new Hidden(['part'], $part)),
|
(new Hidden(['part'], $part)),
|
||||||
(new Text('', dcCore::app()->formNonce())),
|
dcCore::app()->formNonce(false),
|
||||||
]),
|
]),
|
||||||
])->render();
|
])->render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// new login form
|
||||||
echo
|
echo
|
||||||
(new Form('section_new'))->action(dcCore::app()->adminurl->get('admin.plugin.' . My::id(), ['part' => $part]))->method('post')->fields([
|
(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')))),
|
(new Text('h3', Html::escapeHTML(__('Add a user')))),
|
||||||
|
@ -312,7 +324,7 @@ class Manage extends dcNsProcess
|
||||||
(new Submit(['add']))->value(__('Save')),
|
(new Submit(['add']))->value(__('Save')),
|
||||||
(new Hidden(['action'], 'savepasswords')),
|
(new Hidden(['action'], 'savepasswords')),
|
||||||
(new Hidden(['part'], $part)),
|
(new Hidden(['part'], $part)),
|
||||||
(new Text('', dcCore::app()->formNonce())),
|
dcCore::app()->formNonce(false),
|
||||||
]),
|
]),
|
||||||
])->render();
|
])->render();
|
||||||
}
|
}
|
||||||
|
@ -320,6 +332,11 @@ class Manage extends dcNsProcess
|
||||||
dcPage::closeModule();
|
dcPage::closeModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get page section.
|
||||||
|
*
|
||||||
|
* @return string The section
|
||||||
|
*/
|
||||||
private static function getSection(): string
|
private static function getSection(): string
|
||||||
{
|
{
|
||||||
$part = $_REQUEST['part'] ?? 'settings';
|
$part = $_REQUEST['part'] ?? 'settings';
|
||||||
|
@ -330,6 +347,11 @@ class Manage extends dcNsProcess
|
||||||
return $part;
|
return $part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get existing passwords from file.
|
||||||
|
*
|
||||||
|
* @return array<string,string> The passwords list
|
||||||
|
*/
|
||||||
private static function getPasswords(): array
|
private static function getPasswords(): array
|
||||||
{
|
{
|
||||||
$passwords = [];
|
$passwords = [];
|
||||||
|
|
31
src/My.php
31
src/My.php
|
@ -16,16 +16,19 @@ namespace Dotclear\Plugin\httpPassword;
|
||||||
|
|
||||||
use dcCore;
|
use dcCore;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This module definitions.
|
||||||
|
*/
|
||||||
class My
|
class My
|
||||||
{
|
{
|
||||||
/** @var string This plugin permissions */
|
/** @var string This plugin permissions */
|
||||||
public const PERMISSION = 'httpPassword';
|
public const PERMISSION = 'httpPassword';
|
||||||
|
|
||||||
/** @var string Passwords file name */
|
/** @var string Passwords file name */
|
||||||
public const FILE_PASSWORD = '.htpasswd';
|
public const FILE_PASSWORD = '.htpasswd';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This module id
|
* This module id.
|
||||||
*/
|
*/
|
||||||
public static function id(): string
|
public static function id(): string
|
||||||
{
|
{
|
||||||
|
@ -33,15 +36,27 @@ class My
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This module name
|
* This module name.
|
||||||
*/
|
*/
|
||||||
public static function name(): string
|
public static function name(): string
|
||||||
{
|
{
|
||||||
return __((string) dcCore::app()->plugins->moduleInfo(self::id(), 'name'));
|
$name = dcCore::app()->plugins->moduleInfo(self::id(), 'name');
|
||||||
|
|
||||||
|
return __(is_string($name) ? $name : self::id());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encryption methods combo
|
* This module path.
|
||||||
|
*/
|
||||||
|
public static function path(): string
|
||||||
|
{
|
||||||
|
return dirname(__DIR__);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encryption methods combo.
|
||||||
|
*
|
||||||
|
* @return array<string,string>
|
||||||
*/
|
*/
|
||||||
public static function cryptCombo(): array
|
public static function cryptCombo(): array
|
||||||
{
|
{
|
||||||
|
@ -57,7 +72,9 @@ class My
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Admin section menu
|
* Admin section menu.
|
||||||
|
*
|
||||||
|
* @return array<string,string>
|
||||||
*/
|
*/
|
||||||
public static function sectionCombo(): array
|
public static function sectionCombo(): array
|
||||||
{
|
{
|
||||||
|
|
|
@ -28,10 +28,11 @@ class Prepend extends dcNsProcess
|
||||||
|
|
||||||
public static function process(): bool
|
public static function process(): bool
|
||||||
{
|
{
|
||||||
if (!static::$init) {
|
if (!static::$init || is_null(dcCore::app()->auth)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// register module permission
|
||||||
dcCore::app()->auth->setPermissionType(
|
dcCore::app()->auth->setPermissionType(
|
||||||
My::PERMISSION,
|
My::PERMISSION,
|
||||||
__('Manage http password blog protection')
|
__('Manage http password blog protection')
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* @brief httpPassword, a plugin for Dotclear 2
|
||||||
|
*
|
||||||
|
* @package Dotclear
|
||||||
|
* @subpackage Plugin
|
||||||
|
*
|
||||||
|
* @author Frederic PLE and contributors
|
||||||
|
*
|
||||||
|
* @copyright Jean-Christian Denis
|
||||||
|
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
|
||||||
|
*/
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
namespace Dotclear\Plugin\httpPassword;
|
||||||
|
|
||||||
|
use dcCore;
|
||||||
|
use dcNsProcess;
|
||||||
|
use Dotclear\Plugin\Uninstaller\Uninstaller;
|
||||||
|
|
||||||
|
class Uninstall extends dcNsProcess
|
||||||
|
{
|
||||||
|
public static function init(): bool
|
||||||
|
{
|
||||||
|
static::$init = defined('DC_CONTEXT_ADMIN');
|
||||||
|
|
||||||
|
return static::$init;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function process(): bool
|
||||||
|
{
|
||||||
|
if (!static::$init || !dcCore::app()->plugins->moduleExists('Uninstaller')) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
Uninstaller::instance()
|
||||||
|
->addUserAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addUserAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'settings',
|
||||||
|
'delete_all',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'plugins',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
->addDirectAction(
|
||||||
|
'versions',
|
||||||
|
'delete',
|
||||||
|
My::id()
|
||||||
|
)
|
||||||
|
;
|
||||||
|
|
||||||
|
// no custom action
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -20,9 +20,15 @@ class Utils
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Crypt password
|
* Crypt password
|
||||||
|
*
|
||||||
|
* @param string $secret The secret
|
||||||
|
*
|
||||||
|
* @return string The crypt password (empty on error)
|
||||||
*/
|
*/
|
||||||
public static function crypt(?string $secret): string
|
public static function crypt(?string $secret): string
|
||||||
{
|
{
|
||||||
|
$secret = (string) $secret;
|
||||||
|
|
||||||
switch (self::cryptMethod()) {
|
switch (self::cryptMethod()) {
|
||||||
case 'plaintext':
|
case 'plaintext':
|
||||||
$saltlen = -1;
|
$saltlen = -1;
|
||||||
|
@ -72,43 +78,53 @@ class Utils
|
||||||
$secret = crypt($secret, $salt);
|
$secret = crypt($secret, $salt);
|
||||||
}
|
}
|
||||||
|
|
||||||
return($secret);
|
return $secret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting: active
|
* Setting: active
|
||||||
|
*
|
||||||
|
* @return bool True if module is active
|
||||||
*/
|
*/
|
||||||
public static function isActive(): bool
|
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
|
* Setting: crypt
|
||||||
|
*
|
||||||
|
* @return string The crypt method
|
||||||
*/
|
*/
|
||||||
public static function cryptMethod(): string
|
public static function cryptMethod(): string
|
||||||
{
|
{
|
||||||
return (string) dcCore::app()->blog->settings->get(My::id())->get('crypt');
|
return !is_null(dcCore::app()->blog) && is_string(dcCore::app()->blog->settings->get(My::id())->get('crypt')) ? dcCore::app()->blog->settings->get(My::id())->get('crypt') : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Setting: message
|
* Setting: message
|
||||||
|
*
|
||||||
|
* @return string The frontend message
|
||||||
*/
|
*/
|
||||||
public static function httpMessage(): string
|
public static function httpMessage(): string
|
||||||
{
|
{
|
||||||
return (string) dcCore::app()->blog->settings->get(My::id())->get('message');
|
return !is_null(dcCore::app()->blog) && is_string(dcCore::app()->blog->settings->get(My::id())->get('message')) ? dcCore::app()->blog->settings->get(My::id())->get('message') : '';
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get passwords file path
|
* Get passwords file path
|
||||||
|
*
|
||||||
|
* @return string The passwords file path (empty on error)
|
||||||
*/
|
*/
|
||||||
public static function passwordFile(): string
|
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
|
* Check passwords file
|
||||||
|
*
|
||||||
|
* @return bool True if passwords file is writable
|
||||||
*/
|
*/
|
||||||
public static function isWritable(): bool
|
public static function isWritable(): bool
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue