Skip to content

Commit

Permalink
Implemented decoding of base64 encoded json input in middleware, refa…
Browse files Browse the repository at this point in the history
…ctored middleware to update the correct input source not just general request.
  • Loading branch information
zakhenry committed Dec 31, 2015
1 parent f3bd642 commit c240b8a
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 15 deletions.
11 changes: 5 additions & 6 deletions Controllers/EntityController.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ public function getAllPaginated(Request $request, RangeRequest $rangeRequest)
$offset = $rangeRequest->isGetLast() ? $totalCount - $limit : $rangeRequest->getOffset();

if ($request->has('q')) {
$collection = $this->searchAllEntities(base64_decode($request->query('q')), $limit, $offset, $totalCount);
$collection = $this->searchAllEntities($request->query('q'), $limit, $offset, $totalCount);
} else {
$collection = $this->getAllEntities($limit, $offset);
}
Expand Down Expand Up @@ -367,9 +367,8 @@ protected function searchAllEntities($query, $limit = null, $offset = null, &$to
/* @var ElasticquentTrait $model */
$model = $this->getModel();

$queryArray = json_decode($query, true);
if (is_array($queryArray)) { // Complex query
$searchResults = $this->complexSearch($queryArray);
if (is_array($query)) { // Complex query
$searchResults = $this->complexSearch($query);
} else {
$searchResults = $model->searchByQuery([
'match_phrase_prefix' => [
Expand All @@ -396,9 +395,9 @@ protected function searchAllEntities($query, $limit = null, $offset = null, &$to
}

/**
* @param $model
* @param $queryArray
* @param array $queryArray
* @return mixed
* @internal param $model
*/
protected function complexSearch(array $queryArray)
{
Expand Down
52 changes: 46 additions & 6 deletions Middleware/TransformInputDataMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\ParameterBag;

class TransformInputDataMiddleware
{
Expand All @@ -25,7 +26,7 @@ class TransformInputDataMiddleware
*/
public function handle($request, Closure $next)
{
$this->transformRequestInput($request, $request->all());
$this->transformRequestInput($request, $request->query);
$this->transformRequestInput($request, $request->json());

return $next($request);
Expand Down Expand Up @@ -58,27 +59,66 @@ protected function renameKeys(array $array)
}

/**
* @param $request
* Transform the input to snake_case keys and process encoded input values
* @param Request $request
* @param ParameterBag $input
*/
protected function transformRequestInput(Request $request, $input)
protected function transformRequestInput(Request $request, ParameterBag $input)
{
foreach ($input as $key => $value) {

$value = $this->extractEncodedJson($input, $key, $value);

// Handle snakecase conversion in sub arrays
if (is_array($value)) {
$value = $this->renameKeys($value);
$request->offsetSet($key, $value);
$input->set($key, $value);
}

// Find any potential camelCase keys in the 'root' array, and convert
// them to snake_case
if (! ctype_lower($key)) {
// Only convert if the key will change
if ($key != snake_case($key)) {
$request->offsetSet(snake_case($key), $value);
$request->offsetUnset($key);
$input->set(snake_case($key), $value);
$input->remove($key);
}
}
}
}


/**
* If the input is both base64 encoded and json encoded extract it to array
* @param ParameterBag $input
* @param $key
* @param $value
* @return mixed
*/
private function extractEncodedJson(ParameterBag $input, $key, $value)
{

//if it's not a string it can't be base64 encoded, exit early
if (!is_string($value)){
return $value;
}

$decoded = base64_decode($value, true);

//strict mode above allows for a quick check to see if the value is not encoded
if (!$decoded){
return $value;
}

$jsonParsed = json_decode($decoded, true);

//if value couldn't be json decoded, it wasn't valid json, return the original value
if (!$jsonParsed){
return $value;
}

$input->set($key, $jsonParsed);
return $jsonParsed;
}

}
9 changes: 6 additions & 3 deletions tests/integration/EntityTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -203,7 +203,7 @@ public function testGetAllPaginatedSimpleSearch()

$this->app->instance(TestEntity::class, $mockModel);

$this->getJson('/test/entities/pages?q='.base64_encode('foobar'), ['Range' => 'entities=0-']);
$this->getJson('/test/entities/pages?q='.base64_encode(json_encode('foobar')), ['Range' => 'entities=0-']);

$this->assertResponseStatus(404);
}
Expand Down Expand Up @@ -244,6 +244,9 @@ public function testGetAllPaginatedComplexSearch()
$this->assertResponseStatus(404);
}

/**
* @group testing
*/
public function testGetAllPaginatedComplexSearchMatchAll()
{
$results = $this->getFactory(TestEntity::class)->count(5)->make();
Expand Down Expand Up @@ -797,7 +800,7 @@ public function testEntitySearch()

sleep(1); //give the elastic search agent time to index

$this->getJson('/test/entities/pages?q='.base64_encode('searchforthisstring'), ['Range' => 'entities=0-9']);
$this->getJson('/test/entities/pages?q=searchforthisstring', ['Range' => 'entities=0-9']);

$collection = json_decode($this->response->getContent());
$this->assertResponseStatus(206);
Expand All @@ -811,7 +814,7 @@ public function testEntitySearch()

public function testEntitySearchNoResults()
{
$this->getJson('/test/entities/pages?q='.base64_encode('thisstringwontreturnresults'), ['Range' => 'entities=0-9']);
$this->getJson('/test/entities/pages?q=thisstringwontreturnresults', ['Range' => 'entities=0-9']);

$this->assertResponseStatus(404);
$this->shouldReturnJson();
Expand Down

0 comments on commit c240b8a

Please sign in to comment.