Skip to content

Commit

Permalink
Updates to release v1.0.9 fix #205 fix #206
Browse files Browse the repository at this point in the history
  • Loading branch information
kartik-v committed Sep 13, 2018
1 parent 4c934a3 commit 8cc28c2
Show file tree
Hide file tree
Showing 17 changed files with 642 additions and 459 deletions.
5 changes: 4 additions & 1 deletion CHANGE.md
Expand Up @@ -3,8 +3,11 @@ Change Log: `yii2-tree-manager`

## Version 1.0.9

**Date:** _work in process_
**Date:** 13-Sep-2018

- (enh #206): Enhancements to support Bootstrap 4.x.
- (enh #205): Enhance data hashing and security via a separate `TreeSecurity` helper class (BC Breaking).
- (enh #203): Update Russian Translations.
- (enh #202): Enhance node title to be configurable in messages.
- (bug #200): Correct validation for `TreeView::allowNewRoots`.
- (enh #198): New property `TreeView::nodeButtonLabels` to configure submit and reset button icons/labels.
Expand Down
2 changes: 1 addition & 1 deletion README.md
Expand Up @@ -189,4 +189,4 @@ echo TreeViewInput::widget([

## License

**yii2-tree-manager** is released under the BSD 3-Clause License. See the bundled `LICENSE.md` for details.
**yii2-tree-manager** is released under the BSD-3-Clause License. See the bundled `LICENSE.md` for details.
1 change: 0 additions & 1 deletion src/Module.php
Expand Up @@ -8,7 +8,6 @@

namespace kartik\tree;

use Yii;
use yii\helpers\Url;
use yii\helpers\ArrayHelper;

Expand Down
193 changes: 193 additions & 0 deletions src/TreeSecurity.php
@@ -0,0 +1,193 @@
<?php

/**
* @copyright Copyright &copy; Kartik Visweswaran, Krajee.com, 2015 - 2018
* @package yii2-tree-manager
* @version 1.0.9
*/

namespace kartik\tree;

use Closure;
use kartik\tree\models\Tree;
use Yii;
use yii\base\InvalidCallException;
use yii\base\InvalidConfigException;
use yii\helpers\ArrayHelper;
use yii\helpers\Json;
use yii\console\Application;

/**
* Tree data security and data hashing helper class
*
* @author Kartik Visweswaran <kartikv2@gmail.com>
* @since 1.0
*/
class TreeSecurity
{
/**
* Parses tree manage data and returns processed manage data signatures for the tree
* @param array $data
* @return array
* @throws InvalidConfigException
*/
public static function parseManageData($data = [])
{
$nodeTitles = static::getNodeTitles($data);
$defaults = [
'modelClass' => '',
'defaultBtnCss' => '',
'formAction' => '',
'currUrl' => '',
'nodeView' => '',
'nodeSelected' => '',
'nodeTitle' => $nodeTitles['node'],
'nodeTitlePlural' => $nodeTitles['nodes'],
'noNodesMessage' => '',
'isAdmin' => false,
'softDelete' => true,
'showFormButtons' => true,
'showIDAttribute' => true,
'showNameAttribute' => true,
'allowNewRoots' => true,
'formOptions' => [],
'nodeAddlViews' => [],
'nodeViewButtonLabels' => [],
'icons' => [],
'iconsList' => [],
'breadcrumbs' => [],
];
$out = static::getParsedData($defaults, $data, function ($type, $key, $value) {
if ($type === 'array' && $key === 'iconsList') {
return array_values($value);
}
return $value;
});
$oldHash = ArrayHelper::getValue($data, 'treeManageHash', '');
return ['out' => $out['data'], 'oldHash' => $oldHash, 'newHash' => $out['hash']];
}

/**
* Parses tree remove data and returns processed remove data signatures for the tree
* @param array $data
* @return array
* @throws InvalidConfigException
*/
public static function parseRemoveData($data = [])
{
$defaults = [
'modelClass' => '',
'softDelete' => true,
];
$out = static::getParsedData($defaults, $data);
$oldHash = ArrayHelper::getValue($data, 'treeRemoveHash', '');
return ['out' => $out['data'], 'oldHash' => $oldHash, 'newHash' => $out['hash']];
}

/**
* Parses tree move data and returns processed move data signatures for the tree
* @param array $data
* @return array
* @throws InvalidConfigException
*/
public static function parseMoveData($data = [])
{
$defaults = [
'modelClass' => '',
'allowNewRoots' => true,
];
$out = static::getParsedData($defaults, $data);
$oldHash = ArrayHelper::getValue($data, 'treeMoveHash', '');
return ['out' => $out['data'], 'oldHash' => $oldHash, 'newHash' => $out['hash']];
}

/**
* Gets parsed output and hash data for a tree action data source
* @param array $defaults the default data
* @param array $data the source data
* @param Closure|null $callback the callback to process specific data keys
* @return array the parsed data
* @throws InvalidConfigException
*/
protected static function getParsedData($defaults, $data, $callback = null)
{
$out = [];
$hash = '';
foreach ($defaults as $key => $val) {
$value = isset($data[$key]) ? $data[$key] : $val;
$type = 'string';
if (is_bool($val)) {
$value = (bool)$value;
$type = 'bool';
} elseif (is_array($val)) {
$value = empty($value) ? [] : (array)$value;
$type = 'array';
}
if (is_callable($callback)) {
$value = $callback($type, $key, $value);
}
$out[$key] = $value;
$hash .= $type === 'array' ? Json::encode($value) : $value;
}
$out['treeClass'] = ArrayHelper::getValue($out, 'modelClass', Tree::class);
/**
* @var Module $module
*/
$module = TreeView::module();
return ['data' => $out, 'hash' => Yii::$app->security->hashData($hash, $module->treeEncryptSalt)];
}

/**
* Gets the node singular and plural titles
* @param array $data the source data
* @return array
*/
public static function getNodeTitles($data)
{
return [
'node' => ArrayHelper::getValue($data, 'nodeTitle', 'node'),
'nodes' => ArrayHelper::getValue($data, 'nodeTitlePlural', 'nodes'),
];
}

/**
* Gets the model class name key from the data array
* @param array $data
* @return mixed
*/
public static function getModelClass($data = [])
{
return ArrayHelper::getValue($data, 'modelClass', Tree::class);
}

/**
* Checks signature of posted data for ensuring security against data tampering.
*
* @param string $action the name of the action
* @param string $oldHash the old hashed data
* @param string $newHash the new hashed data
*
* @throws InvalidCallException
* @throws InvalidConfigException
*/
public static function checkSignature($action, $oldHash = '', $newHash = null)
{
if (Yii::$app instanceof Application) {
return; // skip hash signature validation for console apps
}
/**
* @var Module $module
*/
$module = TreeView::module();
if (Yii::$app->security->validateData($oldHash, $module->treeEncryptSalt) && $oldHash === $newHash) {
return;
}
$params = YII_DEBUG ? '<pre>OLD HASH:<br>' . $oldHash . '<br>NEW HASH:<br>' . $newHash . '</pre>' : '';
$message = Yii::t(
'kvtree',
'<h4>Operation Disallowed</h4><hr>Invalid request signature detected during tree data <b>{action}</b> action! Please refresh the page and retry.{params}',
['action' => $action, 'params' => $params]
);
throw new InvalidCallException($message);
}
}

0 comments on commit 8cc28c2

Please sign in to comment.