Skip to content

Commit 82b95ff

Browse files
committed
Allow to disable encryption of params
1 parent 4170f51 commit 82b95ff

File tree

8 files changed

+68
-19
lines changed

8 files changed

+68
-19
lines changed

README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -214,9 +214,12 @@ In some situations it can be very beneficial to load widget content with AJAX.
214214
Fortunately, this can be achieved very easily!
215215
All you need to do is to change facade or blade directive - `Widget::` => `AsyncWidget::`, `@widget` => `@asyncWidget`
216216

217-
> Note: Widget params are encrypted and sent via ajax call. Expect them to be json_encoded and json_decoded afterwards.
217+
Widget params are encrypted (by default) and sent via ajax call under the hood. So expect them to be `json_encoded()` and `json_decoded()` afterwards.
218218

219-
> Note: Since version 3.1 you no longer need `jquery` to make ajax calls. However you can set `use_jquery_for_ajax_calls` to `true` in the config file if you want to.
219+
> Note: You can turn encryption off for a given widget by setting `public $encryptParams = false;` on it. However, this action makes widget params publicly accessible, so please make sure you do not leave any vulnerabilities.
220+
For example, if you pass something like user_id through widget params and turn encryption off, you do need to add one more access check inside the widget.
221+
222+
> Note: You can set `use_jquery_for_ajax_calls` to `true` in the config file to use it for ajax calls if you want to.
220223
221224
By default nothing is shown until ajax call is finished.
222225

src/AbstractWidget.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,14 @@ abstract class AbstractWidget
2020
*/
2121
public $cacheTime = false;
2222

23+
/**
24+
* Should widget params be encrypted before sending them to /arrilot/load-widget?
25+
* Turning encryption off can help with making custom reloads from javascript, but makes widget params publicly accessible.
26+
*
27+
* @var bool
28+
*/
29+
public $encryptParams = true;
30+
2331
/**
2432
* The configuration array.
2533
*

src/Controllers/WidgetController.php

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,14 @@ public function showWidget(Request $request)
2222

2323
$factory = app()->make('arrilot.widget');
2424
$widgetName = $request->input('name', '');
25-
$widgetParams = $factory->decryptWidgetParams($request->input('params', ''));
2625

27-
return call_user_func_array([$factory, $widgetName], $widgetParams);
26+
$widgetParams = $request->input('skip_encryption', '')
27+
? $request->input('params', '')
28+
: $factory->decryptWidgetParams($request->input('params', ''));
29+
30+
$decodedParams = json_decode($widgetParams, true);
31+
32+
return call_user_func_array([$factory, $widgetName], $decodedParams ?: []);
2833
}
2934

3035
/**
@@ -36,5 +41,8 @@ protected function prepareGlobals(Request $request)
3641
{
3742
WidgetId::set($request->input('id', 1) - 1);
3843
AbstractWidgetFactory::$skipWidgetContainer = true;
44+
if ($request->input('skip_encryption', '')) {
45+
AbstractWidgetFactory::$allowOnlyWidgetsWithDisabledEncryption = true;
46+
}
3947
}
4048
}

src/Factories/AbstractWidgetFactory.php

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
use Arrilot\Widgets\AbstractWidget;
66
use Arrilot\Widgets\Contracts\ApplicationWrapperContract;
7+
use Arrilot\Widgets\Misc\EncryptException;
78
use Arrilot\Widgets\Misc\InvalidWidgetClassException;
89
use Arrilot\Widgets\Misc\ViewExpressionTrait;
910
use Arrilot\Widgets\WidgetId;
@@ -68,6 +69,13 @@ abstract class AbstractWidgetFactory
6869
*/
6970
public static $skipWidgetContainer = false;
7071

72+
/**
73+
* The flag for not wrapping content in a special container.
74+
*
75+
* @var bool
76+
*/
77+
public static $allowOnlyWidgetsWithDisabledEncryption = false;
78+
7179
/**
7280
* Constructor.
7381
*
@@ -101,6 +109,7 @@ public function __call($widgetName, array $params = [])
101109
* @param $params
102110
*
103111
* @throws InvalidWidgetClassException
112+
* @throws EncryptException
104113
*/
105114
protected function instantiateWidget(array $params = [])
106115
{
@@ -117,10 +126,14 @@ protected function instantiateWidget(array $params = [])
117126
$widgetClass = class_exists($fqcn) ? $fqcn : $this->widgetName;
118127

119128
if (!is_subclass_of($widgetClass, 'Arrilot\Widgets\AbstractWidget')) {
120-
throw new InvalidWidgetClassException('Class "'.$widgetClass.'" must extend "Arrilot\Widgets\AbstractWidget" class');
129+
throw new InvalidWidgetClassException('Class "'.$widgetClass.'" must exist and extend "Arrilot\Widgets\AbstractWidget" class');
121130
}
122131

123132
$this->widget = new $widgetClass($this->widgetConfig);
133+
134+
if (static::$allowOnlyWidgetsWithDisabledEncryption && $this->widget->encryptParams) {
135+
throw new EncryptException('Widget "'.$widgetClass.'" was not called properly');
136+
}
124137
}
125138

126139
/**
@@ -159,26 +172,24 @@ protected function wrapContentInContainer($content)
159172
/**
160173
* Encrypt widget params to be transported via HTTP.
161174
*
162-
* @param array $params
175+
* @param string $params
163176
*
164177
* @return string
165178
*/
166179
public function encryptWidgetParams($params)
167180
{
168-
return $this->app->make('encrypter')->encrypt(json_encode($params));
181+
return $this->app->make('encrypter')->encrypt($params);
169182
}
170183

171184
/**
172185
* Decrypt widget params that were transported via HTTP.
173186
*
174187
* @param string $params
175188
*
176-
* @return array
189+
* @return string
177190
*/
178191
public function decryptWidgetParams($params)
179192
{
180-
$params = json_decode($this->app->make('encrypter')->decrypt($params), true);
181-
182-
return $params ? $params : [];
193+
return $this->app->make('encrypter')->decrypt($params);
183194
}
184195
}

src/Factories/AsyncWidgetFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ public function run()
1414
$this->instantiateWidget(func_get_args());
1515

1616
$placeholder = call_user_func([$this->widget, 'placeholder']);
17-
$loader = $this->javascriptFactory->getLoader();
17+
$loader = $this->javascriptFactory->getLoader($this->widget->encryptParams);
1818
$content = $this->wrapContentInContainer($placeholder.$loader);
1919

2020
return $this->convertToViewExpression($content);

src/Factories/JavascriptFactory.php

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,31 +31,34 @@ public function __construct(AbstractWidgetFactory $widgetFactory)
3131
/**
3232
* Construct javascript code to load the widget.
3333
*
34+
* @param bool $encryptParams
35+
*
3436
* @return string
3537
*/
36-
public function getLoader()
38+
public function getLoader($encryptParams = true)
3739
{
3840
return
3941
'<script type="text/javascript">'.
40-
$this->constructAjaxCall().
42+
$this->constructAjaxCall($encryptParams).
4143
'</script>';
4244
}
4345

4446
/**
4547
* Construct javascript code to reload the widget.
4648
*
4749
* @param float|int $timeout
50+
* @param bool $encryptParams
4851
*
4952
* @return string
5053
*/
51-
public function getReloader($timeout)
54+
public function getReloader($timeout, $encryptParams = true)
5255
{
5356
$timeout = $timeout * 1000;
5457

5558
return
5659
'<script type="text/javascript">'.
5760
'setTimeout( function() {'.
58-
$this->constructAjaxCall().
61+
$this->constructAjaxCall($encryptParams).
5962
'}, '.$timeout.')'.
6063
'</script>';
6164
}
@@ -83,15 +86,21 @@ protected function useJquery()
8386
/**
8487
* Construct ajax call for loaders.
8588
*
89+
* @param bool $encryptParams
90+
*
8691
* @return string
8792
*/
88-
protected function constructAjaxCall()
93+
protected function constructAjaxCall($encryptParams = true)
8994
{
95+
$encodedParams = json_encode($this->widgetFactory->widgetFullParams);
9096
$queryParams = [
9197
'id' => WidgetId::get(),
9298
'name' => $this->widgetFactory->widgetName,
93-
'params' => $this->widgetFactory->encryptWidgetParams($this->widgetFactory->widgetFullParams),
99+
'params' => $encryptParams ? $this->widgetFactory->encryptWidgetParams($encodedParams) : $encodedParams,
94100
];
101+
if (!$encryptParams) {
102+
$queryParams['skip_encryption'] = 1;
103+
}
95104

96105
$url = $this->ajaxLink.'?'.http_build_query($queryParams);
97106

src/Factories/WidgetFactory.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public function run()
1717
$content = $this->getContentFromCache($args);
1818

1919
if ($timeout = (float) $this->getReloadTimeout()) {
20-
$content .= $this->javascriptFactory->getReloader($timeout);
20+
$content .= $this->javascriptFactory->getReloader($timeout, $this->widget->encryptParams);
2121
$content = $this->wrapContentInContainer($content);
2222
}
2323

src/Misc/EncryptException.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<?php
2+
3+
namespace Arrilot\Widgets\Misc;
4+
5+
use Exception;
6+
7+
class EncryptException extends Exception
8+
{
9+
10+
}

0 commit comments

Comments
 (0)