From 1d92e0ed4245a7ebf2af390b545d5b3150da6334 Mon Sep 17 00:00:00 2001 From: n7olkachev Date: Sat, 26 Aug 2017 02:05:19 +0300 Subject: [PATCH] Add filterable field for preventing security issues --- src/Exceptions/FilterableException.php | 8 ++++++++ src/Filterable.php | 13 +++++++++++++ tests/FilterableTest.php | 8 ++++++++ tests/Models/Page.php | 5 +++++ 4 files changed, 34 insertions(+) create mode 100644 src/Exceptions/FilterableException.php diff --git a/src/Exceptions/FilterableException.php b/src/Exceptions/FilterableException.php new file mode 100644 index 0000000..f944caa --- /dev/null +++ b/src/Exceptions/FilterableException.php @@ -0,0 +1,8 @@ + $value) { + if (!$this->isFilterable($key)) { + throw new FilterableException("[$key] is not allowed for filtering"); + } + if (is_null($value) || $value === '') continue; $scopeName = ucfirst(camel_case($key)); @@ -20,4 +26,11 @@ public function scopeFilter($query, array $filterData = []) } } } + + protected function isFilterable($key) + { + $filterable = $this->filterable ?: []; + + return in_array($key, $filterable); + } } \ No newline at end of file diff --git a/tests/FilterableTest.php b/tests/FilterableTest.php index eda9668..0bcc083 100644 --- a/tests/FilterableTest.php +++ b/tests/FilterableTest.php @@ -3,6 +3,7 @@ namespace N7olkachev\LaravelFilterable\Test; use Carbon\Carbon; +use N7olkachev\LaravelFilterable\Exceptions\FilterableException; use N7olkachev\LaravelFilterable\Test\Models\Page; class FilterableTest extends TestCase @@ -45,4 +46,11 @@ public function it_works_for_arrays() $pages = Page::filter(['title' => ['Third page']])->get(); $this->assertEquals($pages->count(), 0); } + + /** @test */ + public function it_throws_on_not_allowed_field() + { + $this->expectException(FilterableException::class); + Page::filter(['foobar' => 'foo']); + } } \ No newline at end of file diff --git a/tests/Models/Page.php b/tests/Models/Page.php index 50ab887..1b05f9e 100644 --- a/tests/Models/Page.php +++ b/tests/Models/Page.php @@ -14,6 +14,11 @@ class Page extends Model 'created_at', ]; + protected $filterable = [ + 'title', + 'created_after' + ]; + public function scopeCreatedAfter($query, $time) { return $query->where('created_at', '>', $time);