From b9ccca9728bd18cad818ec8abc78d5f052de9492 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Cansado=20Sola=CC=80?= Date: Thu, 22 Aug 2019 13:16:36 +0200 Subject: [PATCH 1/2] whitelist feature --- src/Filter.php | 65 +++++++++++++++++++++++++++++++++++++++++++- tests/FilterTest.php | 57 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 121 insertions(+), 1 deletion(-) diff --git a/src/Filter.php b/src/Filter.php index 9fd9c35..77c3ad7 100644 --- a/src/Filter.php +++ b/src/Filter.php @@ -37,6 +37,8 @@ class Filter */ protected $globalChain = null; + protected $whiteList = []; + /** * Set a filter for a value on a specific key * @@ -109,7 +111,9 @@ public function addFilterRule(FilterRule $rule, $key = null) */ public function filter(array $data) { - $data = $this->filterArrayWithGlobalChain($data); + $data = $this->filterArrayWithGlobalChain( + $this->applyWhiteList($data) + ); $this->data = new Container($data); @@ -118,6 +122,65 @@ public function filter(array $data) return $this->data->getArrayCopy(); } + /** + * Set a list of keys to be returned in the end + * + * @param array $keys + * @return void + */ + public function whiteList(array $keys) + { + $this->whiteList = $keys; + } + + /** + * Purge initial fields using white list + * + * @param array $data + * @return array + */ + protected function applyWhiteList(array $data) + { + if (empty($this->whiteList)) { + return $data; + } + + $allowed = []; + foreach ($this->whiteList as $key) { + if (strpos($key, '.') !== false) { + $allowed = $this->deepWhitelist($key, $allowed, $data); + } else { + $allowed[$key] = $data[$key]; + } + } + + return $allowed; + } + + /** + * Uses dot-notation to purge initial data + * + * @param string $key + * @param array $result + * @param array $data + * @return array + */ + protected function deepWhitelist($key, array $result, array $data) + { + $parts = explode('.', $key); + + $ref = &$result; + $dataRef = &$data; + foreach ($parts as $part) { + $ref = &$ref[$part]; + $dataRef = &$dataRef[$part]; + } + + $ref = $dataRef; + + return $result; + } + /** * Filter all set fields with a global chain, recursively * diff --git a/tests/FilterTest.php b/tests/FilterTest.php index 2507cf5..c761c35 100644 --- a/tests/FilterTest.php +++ b/tests/FilterTest.php @@ -326,4 +326,61 @@ public function testRemoveNullOnAllMultidimensionalValues() $this->assertEquals(['test2' => 'test', 'test4' => 'test'], $result); } + + /** + * Ensure the filter only returns the keys we specify on white list + */ + public function testFilterWithWhiteList() + { + $this->filter->whiteList(['first_name']); + + $result = $this->filter->filter([ + 'first_name' => 'john', + 'spam' => 'spam' + ]); + + $this->assertEquals(['first_name' => 'john'], $result); + } + + /** + * Ensure the filter only returns the keys we specify on white list, + * this time using dot notation + */ + public function testFilterWithWhiteListSubArrays() + { + $this->filter->whiteList([ + 'first_name', + 'test1', + 'test2.test', + 'test2.test3.test' + ]); + + $result = $this->filter->filter([ + 'first_name' => 'john', + 'test1' => [ + 'test' => 'hi' + ], + 'test2' => [ + 'test' => 'hi test2', + 'test3' => [ + 'test' => 'hi inner' + ], + 'spam2' => 'spam' + ], + 'spam' => 'spam' + ]); + + $this->assertEquals([ + 'first_name' => 'john', + 'test1' => [ + 'test' => 'hi' + ], + 'test2' => [ + 'test' => 'hi test2', + 'test3' => [ + 'test' => 'hi inner' + ] + ] + ], $result); + } } From b2f078b6ecc8831447e4f93888ef55c4fd5f8cab Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Cansado=20Sol=C3=A0?= Date: Thu, 22 Aug 2019 15:52:32 +0200 Subject: [PATCH 2/2] fix CS --- tests/FilterTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/FilterTest.php b/tests/FilterTest.php index c761c35..a19dc1b 100644 --- a/tests/FilterTest.php +++ b/tests/FilterTest.php @@ -365,7 +365,7 @@ public function testFilterWithWhiteListSubArrays() 'test3' => [ 'test' => 'hi inner' ], - 'spam2' => 'spam' + 'spam2' => 'spam' ], 'spam' => 'spam' ]);