Skip to content

Commit

Permalink
パスワードの再設定間隔
Browse files Browse the repository at this point in the history
  • Loading branch information
seto1 committed Mar 27, 2024
1 parent cb20131 commit 6ddb10b
Show file tree
Hide file tree
Showing 16 changed files with 260 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ q {}","",""
"28","outer_service_output_header","","",""
"29","outer_service_output_footer","","",""
"30","allow_simple_password","0","",""
"31","password_reset_days","","",""
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ q {}","",""
"28","outer_service_output_header","","",""
"29","outer_service_output_footer","","",""
"30","allow_simple_password","0","",""
"31","password_reset_days","","",""
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php
declare(strict_types=1);

use Migrations\AbstractMigration;

class UserPasswordModified extends AbstractMigration
{
/**
* Change Method.
*
* More information on this method is available here:
* https://book.cakephp.org/phinx/0/en/migrations.html#the-change-method
* @return void
*/
public function change(): void
{
$table = $this->table('users');
$table->addColumn('password_modified', 'datetime', [
'after' => 'nickname',
'null' => true,
]);
$table->update();
}
}
7 changes: 7 additions & 0 deletions plugins/baser-core/config/Seeds/SiteConfigsSeed.php
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,13 @@ public function run(): void
'created' => '',
'modified' => ''
],
[
'id' => '31',
'name' => 'password_reset_days',
'value' => '',
'created' => '',
'modified' => ''
],
];
$table = $this->table('site_configs');
$table->insert($data)->save();
Expand Down
10 changes: 10 additions & 0 deletions plugins/baser-core/src/Controller/Admin/BcAdminAppController.php
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,16 @@ public function beforeFilter(EventInterface $event)
if (!$usersService->reload($this->request)) {
return $this->redirect($this->Authentication->logout());
}

// パスワード更新日時のチェック
if (BcUtil::loginUser() && !$usersService->checkPasswordModified($this->request) && (
$this->getRequest()->getParam('plugin') !== 'BaserCore' ||
$this->getRequest()->getParam('controller') !== 'Dashboard' ||
$this->getRequest()->getParam('action') !== 'index'
)) {
return $this->redirect(['plugin' => 'BaserCore', 'controller' => 'Dashboard', 'action' => 'index']);
}

$response = parent::beforeFilter($event);
if ($response) return $response;
$response = $this->redirectIfIsNotSameSite();
Expand Down
29 changes: 29 additions & 0 deletions plugins/baser-core/src/Controller/Admin/UsersController.php
Original file line number Diff line number Diff line change
Expand Up @@ -298,6 +298,35 @@ public function edit(UsersAdminServiceInterface $service, $id = null)
$this->set($service->getViewVarsForEdit($user));
}

public function edit_password(UsersAdminServiceInterface $service)
{
$user = $service->get(BcUtil::loginUser()['id']);
if ($this->request->is(['patch', 'post', 'put'])) {
$event = $this->dispatchLayerEvent('beforeEditPassword', [
'data' => $this->getRequest()->getData()
]);
if ($event !== false) {
$data = ($event->getResult() === null || $event->getResult() === true) ? $event->getData('data') : $event->getResult();
$this->setRequest($this->getRequest()->withParsedBody($data));
}
try {
$user = $service->updatePassword($user, $this->request->getData());
$this->dispatchLayerEvent('afterEditPassword', [
'user' => $user
]);
$service->reLogin($this->request, $this->response);
$this->BcMessage->setSuccess(__d('baser_core', 'パスワードを更新しました。'));
return $this->redirect(['action' => 'edit_password']);
} catch (PersistenceFailedException $e) {
$user = $e->getEntity();
$this->BcMessage->setError(__d('baser_core', '入力エラーです。内容を修正してください。'));
} catch (\Throwable $e) {
$this->BcMessage->setError(__d('baser_core', 'データベース処理中にエラーが発生しました。') . $e->getMessage());
}
}
$this->set($service->getViewVarsForEdit($user));
}

/**
* ログインユーザー削除
*
Expand Down
1 change: 1 addition & 0 deletions plugins/baser-core/src/Model/Entity/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class User extends EntityAlias
protected function _setPassword($value)
{
if ($value) {
$this->password_modified = date('Y-m-d H:i:s');
$hasher = new DefaultPasswordHasher();
return $hasher->hash($value);
} else {
Expand Down
3 changes: 3 additions & 0 deletions plugins/baser-core/src/Model/Table/SiteConfigsTable.php
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ public function validationKeyValue(Validator $validator): Validator
'provider' => 'siteConfig',
'message' => __d('baser_core', '管理画面をSSLで利用するには、SSL用のWebサイトURLを入力してください。')
]]);
$validator
->allowEmptyString('password_reset_days')
->nonNegativeInteger('password_reset_days', __d('baser_core', 'パスワードの再設定日数は0以上の整数を入力してください。'));
return $validator;
}

Expand Down
51 changes: 51 additions & 0 deletions plugins/baser-core/src/Service/UsersService.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
use BaserCore\Model\Entity\User;
use BaserCore\Model\Table\LoginStoresTable;
use BaserCore\Model\Table\UsersTable;
use BaserCore\Service\SiteConfigsServiceInterface;
use BaserCore\Utility\BcContainerTrait;
use BaserCore\Utility\BcUtil;
use Cake\Core\Configure;
use Cake\Core\Exception\Exception;
Expand All @@ -41,6 +43,11 @@
class UsersService implements UsersServiceInterface
{

/**
* Trait
*/
use BcContainerTrait;

/**
* Users Table
* @var UsersTable|Table
Expand Down Expand Up @@ -192,6 +199,24 @@ public function update(EntityInterface $target, array $postData): ?EntityInterfa
return $this->Users->saveOrFail($user);
}

/**
* パスワードを更新する
*
* @param EntityInterface $user
* @param array $postData
* @return EntityInterface
* @throws \Cake\ORM\Exception\PersistenceFailedException
*/
public function updatePassword(EntityInterface $user, array $postData): ?EntityInterface
{
$user = $this->Users->patchEntity(
$user,
['password_1' => $postData['password_1'], 'password_2' => $postData['password_2']],
['validate' => 'passwordUpdate']
);
return $this->Users->saveOrFail($user);
}

/**
* ユーザー情報を削除する
* 最後のシステム管理者でなければ削除
Expand Down Expand Up @@ -395,6 +420,32 @@ public function checkAutoLogin(ServerRequest $request, Response $response)
return $user;
}

/**
* ユーザーのパスワード更新日時チェック
*
* @return boolean
*/
public function checkPasswordModified(ServerRequest $request)
{
// checkPasswordModified実行後の場合、BcUtil::loginUser()よりも新しい情報を取得可能
$session = $request->getSession();
$user = $session->read(Configure::read('BcPrefixAuth.Admin.sessionKey'));

$siteConfigsService = $this->getService(SiteConfigsServiceInterface::class);
$passwordResetDays = $siteConfigsService->getValue('password_reset_days');
if (!$passwordResetDays) {
return true;
}
if (!$user['password_modified']) {
return false;
}
// システム基本設定「ログインパスワードの再設定日数」で設定した日数以上パスワードが更新されていない場合
if ($user['password_modified']->modify('+' . $passwordResetDays . ' days') <= new DateTime()) {
return false;
}
return true;
}

/**
* 代理ログインを行う
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -223,4 +223,11 @@ public function testRedirectIfIsNotSameSite()
$this->assertNull($this->_response);
}

/**
* test checkPasswordModified
*/
public function testCheckPasswordModified()
{
// TODO
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,14 @@ public function testEdit()
$this->assertEquals(1, $query->count());
}

/**
* Test edit_password
*/
public function testEdit_password()
{
// TODO
}

/**
* Test delete method
*
Expand Down
2 changes: 2 additions & 0 deletions plugins/baser-core/tests/TestCase/Model/Entity/UserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,8 @@ public function testSetPassword()
{
$this->User->set('password', 'testtest');
$this->assertNotEquals('testtest', $this->User->password);

// TODO
}

/**
Expand Down
16 changes: 16 additions & 0 deletions plugins/baser-core/tests/TestCase/Service/UsersServiceTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,14 @@ public function testUpdate()
$this->assertEquals(1, $users->all()->count());
}

/**
* test checkUpdatePassword
*/
public function testUpdatePassword()
{
// TODO
}

/**
* Test delete
*/
Expand Down Expand Up @@ -237,6 +245,14 @@ public function testCheckAutoLogin()
$this->assertNotEquals($beforeCookie['value'], $afterCookie['value']);
}

/**
* test checkPasswordModified
*/
public function testCheckPasswordModified()
{
// TODO
}

/**
* test loginToAgent
*/
Expand Down
16 changes: 16 additions & 0 deletions plugins/bc-admin-third/templates/Admin/SiteConfigs/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,22 @@
<?php echo $this->BcAdminForm->error('allow_simple_password') ?>
</td>
</tr>
<tr>
<th class="col-head bca-form-table__label">
<?php echo $this->BcAdminForm->label('password_reset_days', __d('baser_core', 'ログインパスワードの再設定日数')) ?>
</th>
<td class="col-input bca-form-table__input">

<?php echo $this->BcAdminForm->control('password_reset_days', [
'type' => 'text',
'size' => 10,
'maxlength' => 255
]) ?>
<i class="bca-icon--question-circle bca-help"></i>
<div class="bca-helptext"><?php echo __d('baser_core', 'ユーザーのパスワードが設定した日数以上更新されていない場合に再設定画面を表示します。再設定を行うまで管理画面の利用は不可となります。') ?></div>
<?php echo $this->BcAdminForm->error('password_reset_days') ?>
</td>
</tr>

<?php echo $this->BcAdminForm->dispatchAfterForm('Admin') ?>

Expand Down
83 changes: 83 additions & 0 deletions plugins/bc-admin-third/templates/Admin/Users/edit_password.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php
/**
* baserCMS : Based Website Development Project <https://basercms.net>
* Copyright (c) NPO baser foundation <https://baserfoundation.org/>
*
* @copyright Copyright (c) NPO baser foundation
* @link https://basercms.net baserCMS Project
* @since 5.0.0
* @license https://basercms.net/license/index.html MIT License
*/

use BaserCore\View\BcAdminAppView;
use BaserCore\Model\Entity\User;

/**
* Users Edit
* @var BcAdminAppView $this
* @var User $user
*/
$this->BcAdmin->setTitle(__d('baser_core', 'パスワード編集'));
?>

<?= $this->BcAdminForm->create($user, ['novalidate' => true]) ?>

<?php // 自動入力を防止する為のダミーフィールド ?>
<input type="password" name="dummy-pass" autocomplete="off" style="top:-100px;left:-100px;position:fixed;">
<?php $this->BcAdminForm->unlockFields('dummy-pass') ?>

<?php echo $this->BcFormTable->dispatchBefore() ?>

<div class="section">
<table id="FormTable" class="form-table bca-form-table">
<tr>
<th class="col-head bca-form-table__label">
<?php echo $this->BcAdminForm->label('password_1', __d('baser_core', 'パスワード')) ?>
<?php if ($this->request->getParam('action') == 'add'): ?>
<span class="bca-label" data-bca-label-type="required"><?php echo __d('baser_core', '必須') ?></span>&nbsp;
<?php endif; ?>
</th>
<td class="col-input bca-form-table__input">
<?php if ($this->request->getParam('action') == 'edit'): ?><small>
[<?php echo __d('baser_core', 'パスワードは変更する場合のみ入力してください') ?>]</small><br/><?php endif ?>
<?php echo $this->BcAdminForm->control('password_1', ['type' => 'password', 'size' => 20, 'maxlength' => 255, 'autocomplete' => 'off']) ?>
<?php echo $this->BcAdminForm->control('password_2', ['type' => 'password', 'size' => 20, 'maxlength' => 255, 'autocomplete' => 'off', 'placeholder' => __d('baser_core', 'もう一度入力')]) ?>
<i class="bca-icon--question-circle bca-help"></i>
<div class="bca-helptext">
<ul>
<li>
<?php if ($this->request->getParam('action') == 'edit'): ?>
<?php echo __d('baser_core', 'パスワードの変更をする場合は、') ?>
<?php endif; ?>
<?php echo __d('baser_core', '確認のため2回入力してください。') ?></li>
<li><?php echo __d('baser_core', '半角英数字(英字は大文字小文字を区別)とスペース、記号(._-:/()#,@[]+=&;{}!$*)のみで入力してください') ?></li>
</ul>
</div>
<?php echo $this->BcAdminForm->error('password') ?>
</td>
</tr>

<?php echo $this->BcAdminForm->dispatchAfterForm() ?>

</table>
</div>

<?php echo $this->BcFormTable->dispatchAfter() ?>

<div class="submit section bca-actions">
<div class="bca-actions__main">
<?= $this->BcAdminForm->button(
__d('baser_core', '保存'),
['div' => false,
'class' => 'button bca-btn bca-actions__item',
'data-bca-btn-type' => 'save',
'data-bca-btn-size' => 'lg',
'data-bca-btn-width' => 'lg',
'id' => 'BtnSave']
) ?>
</div>
</div>

<?= $this->BcAdminForm->end() ?>

<?= $this->fetch('postLink') ?>
Original file line number Diff line number Diff line change
Expand Up @@ -57,3 +57,4 @@ q {}","",""
"28","outer_service_output_header","","",""
"29","outer_service_output_footer","","",""
"30","allow_simple_password","0","",""
"31","password_reset_days","","",""

0 comments on commit 6ddb10b

Please sign in to comment.