From aeced6c599401273dd75f85d3896918a6e4b84cf Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Wed, 13 Sep 2023 17:29:38 +1200 Subject: [PATCH 01/15] throw 5023 if request param contains html tag --- .../InvalidTagRequestParametersException.php | 23 +++++++++++++++++++ src/Validation/RequestValidation.php | 4 ++++ tests/Validation/RequestValidationTest.php | 11 +++++++++ 3 files changed, 38 insertions(+) create mode 100644 src/Exception/InvalidTagRequestParametersException.php diff --git a/src/Exception/InvalidTagRequestParametersException.php b/src/Exception/InvalidTagRequestParametersException.php new file mode 100644 index 0000000..269903d --- /dev/null +++ b/src/Exception/InvalidTagRequestParametersException.php @@ -0,0 +1,23 @@ + RuleNotFoundException::class, ], + // invalid params contains html tags + [ + 'body' => [ + 'paramName' => '' + ], + 'rules' => [ + 'paramName' => 'regex:/^(?:(?!<[a-zA-Z])[\s\S])*$/' + ], + 'errorExpected' => InvalidTagRequestParametersException::class, + ], // custom rule [ 'body' => [ From 3b145948ebffbbb449f6c5e62b9701627534b540 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Wed, 13 Sep 2023 18:31:12 +1200 Subject: [PATCH 02/15] regex tweaks --- tests/Validation/RequestValidationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 60ecd8e..ac43464 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -122,7 +122,7 @@ public function dataProvider(): array 'paramName' => '' ], 'rules' => [ - 'paramName' => 'regex:/^(?:(?!<[a-zA-Z])[\s\S])*$/' + 'paramName' => 'regex:/^(?:(?!<[^>]*$)[^<])*$/' ], 'errorExpected' => InvalidTagRequestParametersException::class, ], From 453614dc313ea3566c83d73819aa302d0bbb2ef1 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Thu, 14 Sep 2023 15:35:53 +1200 Subject: [PATCH 03/15] make html tag check validation rule into a constant --- src/Validation/RequestValidation.php | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index 195b729..67533f7 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -14,6 +14,12 @@ */ class RequestValidation implements RequestValidationInterface { + /** + * Regex validation rule for parames without HTML tags. + * @var string + */ + public const NO_HTML_TAG_RULE = 'regex:/^(?:(?!<[^>]*$)[^<])*$/'; + /** * @param Request $request * @param array $validationRules @@ -38,8 +44,12 @@ public function validateRequestData( $validation = $validator->make($requestBody, $validationRules); + $paramsContainHtmlTag = false; // set aliases foreach ($validationRules as $ruleKey => $ruleVal) { + if ($ruleVal === self::NO_HTML_TAG_RULE) { + $paramsContainHtmlTag = true; + } $validation->setAlias($ruleKey, '`' . $ruleKey . '`'); } @@ -69,10 +79,9 @@ public function validateRequestData( if (!empty($required)) { throw new MissingRequiredParametersException('', $request, $required); } - if (!empty($invalid)) { $errors = implode('. ', $invalid); - if (strpos($errors, 'not valid format') !== false) { + if ($paramsContainHtmlTag) { throw new InvalidTagRequestParametersException($errors, $request); } throw new InvalidRequestParametersException($errors, $request); From a3616569cc476b9386bacc3b447da88670d83017 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Thu, 14 Sep 2023 15:44:18 +1200 Subject: [PATCH 04/15] tweaks --- tests/Validation/RequestValidationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index ac43464..0fd8614 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -122,7 +122,7 @@ public function dataProvider(): array 'paramName' => '' ], 'rules' => [ - 'paramName' => 'regex:/^(?:(?!<[^>]*$)[^<])*$/' + 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], 'errorExpected' => InvalidTagRequestParametersException::class, ], From 7cb9ba75871ec16efc185013be5ddfa9867c942b Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Thu, 14 Sep 2023 15:46:58 +1200 Subject: [PATCH 05/15] tweaks --- src/Validation/RequestValidation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index 67533f7..c9f3d99 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -15,7 +15,7 @@ class RequestValidation implements RequestValidationInterface { /** - * Regex validation rule for parames without HTML tags. + * Regex validation rule for params without HTML tags. * @var string */ public const NO_HTML_TAG_RULE = 'regex:/^(?:(?!<[^>]*$)[^<])*$/'; From d607db4a5e69e96d3b912f9a2de94b7ffbeda8c0 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 19 Sep 2023 14:27:15 +1200 Subject: [PATCH 06/15] add customRule and customException for checking html tag in params --- src/Validation/RequestValidation.php | 11 +-- tests/Validation/RequestValidationTest.php | 79 ++++++++++++++++++++-- 2 files changed, 82 insertions(+), 8 deletions(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index c9f3d99..1a0b8a2 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -7,6 +7,7 @@ use Serato\SwsApp\Exception\InvalidTagRequestParametersException; use Psr\Http\Message\ServerRequestInterface as Request; use Rakit\Validation\Validator; +use Rakit\Validation\Rules\Regex; /** * Class RequestValidation @@ -52,7 +53,12 @@ public function validateRequestData( } $validation->setAlias($ruleKey, '`' . $ruleKey . '`'); } - + if ($paramsContainHtmlTag) { + $customRules[self::NO_HTML_TAG_RULE] = new Regex(); + if (!isset($exceptions['regex'])) { + $exceptions['regex'] = InvalidTagRequestParametersException::class; + } + } $validation->validate(); if (!$validation->fails()) { return $validation->getValidatedData(); @@ -81,9 +87,6 @@ public function validateRequestData( } if (!empty($invalid)) { $errors = implode('. ', $invalid); - if ($paramsContainHtmlTag) { - throw new InvalidTagRequestParametersException($errors, $request); - } throw new InvalidRequestParametersException($errors, $request); } } diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 0fd8614..833d054 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -6,6 +6,7 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Rakit\Validation\RuleNotFoundException; use Rakit\Validation\Rules\Numeric; +use Rakit\Validation\Rules\Regex; use Serato\SwsApp\Exception\InvalidRequestParametersException; use Serato\SwsApp\Exception\InvalidTagRequestParametersException; use Serato\SwsApp\Exception\MissingRequiredParametersException; @@ -116,15 +117,49 @@ public function dataProvider(): array ], 'errorExpected' => RuleNotFoundException::class, ], - // invalid params contains html tags + // invalid params contains html tags throw InvalidTagRequestParametersException [ 'body' => [ - 'paramName' => '' + 'paramName' => '
' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class, + 'errorExpected' => InvalidTagRequestParametersException::class + ], + // invalid params contains invalid format throws InvalidRequestParametersException + [ + 'body' => [ + 'paramName' => '
' + ], + 'rules' => [ + 'paramName' => 'regex:/^a/' + ], + 'errorExpected' => InvalidRequestParametersException::class, + 'customRules' => [ + 'regex:/^a/' => new Regex() + ], + 'customException' => [ + 'regex' => InvalidRequestParametersException::class + ] + ], + // invalid params contains invalid format and html tags throws InvalidRequestParametersException + [ + 'body' => [ + 'paramName' => '
', + 'paramName2' => '
' + ], + 'rules' => [ + 'paramName' => 'regex:/^a/', // any string start with `a` + 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => InvalidRequestParametersException::class, + 'customRules' => [ + 'regex:/^a/' => new Regex() + ], + 'customException' => [ + 'regex' => InvalidRequestParametersException::class + ] ], // custom rule [ @@ -139,6 +174,24 @@ public function dataProvider(): array 'is_numberic' => new Numeric() ] ], + // custom rule and invalid params contains html tags not excepting errors + [ + 'body' => [ + 'paramName' => '1', + 'paramNam2' => '' + ], + 'rules' => [ + 'paramName' => 'required|is_numberic', + 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => null, + 'customRules' => [ + 'is_numberic' => new Numeric() + ], + 'customException' => [ + 'is_numberic' => UnsupportedContentTypeException::class + ] + ], // custom exception [ 'body' => [ @@ -155,6 +208,24 @@ public function dataProvider(): array 'is_numberic' => UnsupportedContentTypeException::class ] ], + // custom exception and invalid params contains html tags throws UnsupportedContentTypeException + [ + 'body' => [ + 'paramName' => 'invalid-number', + 'paramName2' => '
' + ], + 'rules' => [ + 'paramName' => 'required|is_numberic', + 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => UnsupportedContentTypeException::class, + 'customRules' => [ + 'is_numberic' => new Numeric() + ], + 'customException' => [ + 'is_numberic' => UnsupportedContentTypeException::class + ] + ], //preprocess data with default values [ 'body' => [ From 9bb2646b46171172cfaeaa21747d67a27a863afc Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 19 Sep 2023 14:38:57 +1200 Subject: [PATCH 07/15] add more unit tests in different html tags --- src/Validation/RequestValidation.php | 1 + tests/Validation/RequestValidationTest.php | 30 ++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index 1a0b8a2..3a06e0e 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -53,6 +53,7 @@ public function validateRequestData( } $validation->setAlias($ruleKey, '`' . $ruleKey . '`'); } + // add a customRule and customException when checking one param without html tag if ($paramsContainHtmlTag) { $customRules[self::NO_HTML_TAG_RULE] = new Regex(); if (!isset($exceptions['regex'])) { diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 833d054..565462f 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -127,6 +127,36 @@ public function dataProvider(): array ], 'errorExpected' => InvalidTagRequestParametersException::class ], + // invalid params contains html tags throw InvalidTagRequestParametersException 2 + [ + 'body' => [ + 'paramName' => '
test' + ], + 'rules' => [ + 'paramName' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => InvalidTagRequestParametersException::class + ], + // invalid params contains html tags throw InvalidTagRequestParametersException 3 + [ + 'body' => [ + 'paramName' => '' + ], + 'rules' => [ + 'paramName' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => InvalidTagRequestParametersException::class + ], + // invalid params contains html tags throw InvalidTagRequestParametersException 4 + [ + 'body' => [ + 'paramName' => 'test' + ], + 'rules' => [ + 'paramName' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => InvalidTagRequestParametersException::class + ], // invalid params contains invalid format throws InvalidRequestParametersException [ 'body' => [ From b46b1388affc1d55e58273844f0b5dcfba8c544c Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 19 Sep 2023 15:15:38 +1200 Subject: [PATCH 08/15] add more unit test --- tests/Validation/RequestValidationTest.php | 51 +++++++++++++++++----- 1 file changed, 40 insertions(+), 11 deletions(-) diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 565462f..8cf6aa3 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -117,6 +117,16 @@ public function dataProvider(): array ], 'errorExpected' => RuleNotFoundException::class, ], + // valid params without html tags throw no error + [ + 'body' => [ + 'paramName' => 'br' + ], + 'rules' => [ + 'paramName' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => null + ], // invalid params contains html tags throw InvalidTagRequestParametersException [ 'body' => [ @@ -197,11 +207,11 @@ public function dataProvider(): array 'paramName' => '1' ], 'rules' => [ - 'paramName' => 'required|is_numberic' + 'paramName' => 'required|is_numeric' ], 'errorExpected' => null, 'customRules' => [ - 'is_numberic' => new Numeric() + 'is_numeric' => new Numeric() ] ], // custom rule and invalid params contains html tags not excepting errors @@ -211,15 +221,15 @@ public function dataProvider(): array 'paramNam2' => '' ], 'rules' => [ - 'paramName' => 'required|is_numberic', + 'paramName' => 'required|is_numeric', 'paramName2' => RequestValidation::NO_HTML_TAG_RULE ], 'errorExpected' => null, 'customRules' => [ - 'is_numberic' => new Numeric() + 'is_numeric' => new Numeric() ], 'customException' => [ - 'is_numberic' => UnsupportedContentTypeException::class + 'is_numeric' => UnsupportedContentTypeException::class ] ], // custom exception @@ -228,14 +238,14 @@ public function dataProvider(): array 'paramName' => 'invalid-number' ], 'rules' => [ - 'paramName' => 'required|is_numberic' + 'paramName' => 'required|is_numeric' ], 'errorExpected' => UnsupportedContentTypeException::class, 'customRules' => [ - 'is_numberic' => new Numeric() + 'is_numeric' => new Numeric() ], 'customException' => [ - 'is_numberic' => UnsupportedContentTypeException::class + 'is_numeric' => UnsupportedContentTypeException::class ] ], // custom exception and invalid params contains html tags throws UnsupportedContentTypeException @@ -245,15 +255,34 @@ public function dataProvider(): array 'paramName2' => '
' ], 'rules' => [ - 'paramName' => 'required|is_numberic', + 'paramName' => 'required|is_numeric', 'paramName2' => RequestValidation::NO_HTML_TAG_RULE ], 'errorExpected' => UnsupportedContentTypeException::class, 'customRules' => [ - 'is_numberic' => new Numeric() + 'is_numeric' => new Numeric() + ], + 'customException' => [ + 'is_numeric' => UnsupportedContentTypeException::class + ] + ], + // custom exception and invalid params contains html tags throws InvalidTagRequestParametersException + // (params order change) + [ + 'body' => [ + 'paramName' => '
', + 'paramName2' => 'invalid-number', + ], + 'rules' => [ + 'paramName' => RequestValidation::NO_HTML_TAG_RULE, + 'paramName2' => 'required|is_numeric', + ], + 'errorExpected' => InvalidTagRequestParametersException::class, + 'customRules' => [ + 'is_numeric' => new Numeric() ], 'customException' => [ - 'is_numberic' => UnsupportedContentTypeException::class + 'is_numeric' => InvalidTagRequestParametersException::class ] ], //preprocess data with default values From ffc3f24579fa3987e9b6f8fb6a6e06669891e393 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 19 Sep 2023 15:17:35 +1200 Subject: [PATCH 09/15] tweaks --- tests/Validation/RequestValidationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 8cf6aa3..97b0230 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -282,7 +282,7 @@ public function dataProvider(): array 'is_numeric' => new Numeric() ], 'customException' => [ - 'is_numeric' => InvalidTagRequestParametersException::class + 'is_numeric' => UnsupportedContentTypeException::class ] ], //preprocess data with default values From f3348d5b8c5d5bfa6cfa65f9622a4616f9fb7986 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Tue, 19 Sep 2023 15:24:21 +1200 Subject: [PATCH 10/15] fix phpcs errors --- tests/Validation/RequestValidationTest.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 97b0230..179ddcd 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -266,7 +266,7 @@ public function dataProvider(): array 'is_numeric' => UnsupportedContentTypeException::class ] ], - // custom exception and invalid params contains html tags throws InvalidTagRequestParametersException + // custom exception and invalid params contains html tags throws InvalidTagRequestParametersException // (params order change) [ 'body' => [ From d312f5f00be394e00188b8d7f85e339dddb8cd22 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Fri, 22 Sep 2023 12:29:12 +1200 Subject: [PATCH 11/15] refactor --- src/Validation/RequestValidation.php | 23 +++---- tests/Validation/RequestValidationTest.php | 80 +++++++++++++++++----- 2 files changed, 74 insertions(+), 29 deletions(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index 3a06e0e..df36da0 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -15,11 +15,18 @@ */ class RequestValidation implements RequestValidationInterface { + /** + * Validation rule name for params without HTML tags. + * @var string + */ + public const NO_HTML_TAG_RULE = 'no_html_tag'; + /** * Regex validation rule for params without HTML tags. * @var string */ - public const NO_HTML_TAG_RULE = 'regex:/^(?:(?!<[^>]*$)[^<])*$/'; + public const NO_HTML_TAG_REGEX = '/^(?:(?!<[^>]*$)[^<])*$/'; + /** * @param Request $request @@ -45,21 +52,11 @@ public function validateRequestData( $validation = $validator->make($requestBody, $validationRules); - $paramsContainHtmlTag = false; // set aliases foreach ($validationRules as $ruleKey => $ruleVal) { - if ($ruleVal === self::NO_HTML_TAG_RULE) { - $paramsContainHtmlTag = true; - } $validation->setAlias($ruleKey, '`' . $ruleKey . '`'); } - // add a customRule and customException when checking one param without html tag - if ($paramsContainHtmlTag) { - $customRules[self::NO_HTML_TAG_RULE] = new Regex(); - if (!isset($exceptions['regex'])) { - $exceptions['regex'] = InvalidTagRequestParametersException::class; - } - } + $validation->validate(); if (!$validation->fails()) { return $validation->getValidatedData(); @@ -68,6 +65,8 @@ public function validateRequestData( $required = []; $invalid = []; $errors = $validation->errors()->toArray(); + // var_dump($errors); + // die; foreach ($errors as $key => $error) { if (!empty($error['required'])) { $required[] = $key; diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 179ddcd..6f3f7e3 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -77,6 +77,14 @@ public function testValidateRequestData( */ public function dataProvider(): array { + $noHtmlTagRule = new Regex(); + $noHtmlTagRule->setParameter('regex', RequestValidation::NO_HTML_TAG_REGEX); + + $paramStartWithARule = new Regex(); + $paramStartWithARule->setParameter('regex', '/^a/'); + // var_dump($noHtmlTagRule->getParameters()); + // die; + return [ // no errors [ @@ -123,9 +131,15 @@ public function dataProvider(): array 'paramName' => 'br' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => RequestValidation::NO_HTML_TAG_RULE + ], + 'errorExpected' => null, + 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule ], - 'errorExpected' => null + 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class + ] ], // invalid params contains html tags throw InvalidTagRequestParametersException [ @@ -135,7 +149,13 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class + 'errorExpected' => InvalidTagRequestParametersException::class, + 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule + ], + 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class + ] ], // invalid params contains html tags throw InvalidTagRequestParametersException 2 [ @@ -145,7 +165,13 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class + 'errorExpected' => InvalidTagRequestParametersException::class, + 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule + ], + 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class + ] ], // invalid params contains html tags throw InvalidTagRequestParametersException 3 [ @@ -155,7 +181,13 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class + 'errorExpected' => InvalidTagRequestParametersException::class, + 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule + ], + 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class + ] ], // invalid params contains html tags throw InvalidTagRequestParametersException 4 [ @@ -165,7 +197,13 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class + 'errorExpected' => InvalidTagRequestParametersException::class, + 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule + ], + 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class + ] ], // invalid params contains invalid format throws InvalidRequestParametersException [ @@ -173,14 +211,14 @@ public function dataProvider(): array 'paramName' => '
' ], 'rules' => [ - 'paramName' => 'regex:/^a/' + 'paramName' => 'start_with_a' ], 'errorExpected' => InvalidRequestParametersException::class, 'customRules' => [ - 'regex:/^a/' => new Regex() + 'start_with_a' => $paramStartWithARule ], 'customException' => [ - 'regex' => InvalidRequestParametersException::class + 'start_with_a' => InvalidRequestParametersException::class ] ], // invalid params contains invalid format and html tags throws InvalidRequestParametersException @@ -190,15 +228,17 @@ public function dataProvider(): array 'paramName2' => '
' ], 'rules' => [ - 'paramName' => 'regex:/^a/', // any string start with `a` + 'paramName' => 'start_with_a', 'paramName2' => RequestValidation::NO_HTML_TAG_RULE ], 'errorExpected' => InvalidRequestParametersException::class, 'customRules' => [ - 'regex:/^a/' => new Regex() + 'start_with_a' => $paramStartWithARule, + 'no_html_tag' => $noHtmlTagRule ], 'customException' => [ - 'regex' => InvalidRequestParametersException::class + 'start_with_a' => InvalidRequestParametersException::class, + 'no_html_tag' => InvalidTagRequestParametersException::class ] ], // custom rule @@ -226,10 +266,12 @@ public function dataProvider(): array ], 'errorExpected' => null, 'customRules' => [ - 'is_numeric' => new Numeric() + 'is_numeric' => new Numeric(), + 'no_html_tag' => $noHtmlTagRule ], 'customException' => [ - 'is_numeric' => UnsupportedContentTypeException::class + 'is_numeric' => UnsupportedContentTypeException::class, + 'no_html_tag' => InvalidTagRequestParametersException::class ] ], // custom exception @@ -260,14 +302,16 @@ public function dataProvider(): array ], 'errorExpected' => UnsupportedContentTypeException::class, 'customRules' => [ - 'is_numeric' => new Numeric() + 'is_numeric' => new Numeric(), + 'no_html_tag' => $noHtmlTagRule ], 'customException' => [ - 'is_numeric' => UnsupportedContentTypeException::class + 'is_numeric' => UnsupportedContentTypeException::class, + 'no_html_tag' => InvalidTagRequestParametersException::class ] ], // custom exception and invalid params contains html tags throws InvalidTagRequestParametersException - // (params order change) + // (params order changed) [ 'body' => [ 'paramName' => '
', @@ -279,9 +323,11 @@ public function dataProvider(): array ], 'errorExpected' => InvalidTagRequestParametersException::class, 'customRules' => [ + 'no_html_tag' => $noHtmlTagRule, 'is_numeric' => new Numeric() ], 'customException' => [ + 'no_html_tag' => InvalidTagRequestParametersException::class, 'is_numeric' => UnsupportedContentTypeException::class ] ], From 023f64046e019fcdd3897e6977d1325dab142941 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Fri, 22 Sep 2023 12:49:49 +1200 Subject: [PATCH 12/15] tweaks --- ...=> BadRequestContainHTMLTagsException.php} | 4 +- src/Validation/RequestValidation.php | 14 ++- tests/Validation/RequestValidationTest.php | 88 ++++++------------- 3 files changed, 39 insertions(+), 67 deletions(-) rename src/Exception/{InvalidTagRequestParametersException.php => BadRequestContainHTMLTagsException.php} (73%) diff --git a/src/Exception/InvalidTagRequestParametersException.php b/src/Exception/BadRequestContainHTMLTagsException.php similarity index 73% rename from src/Exception/InvalidTagRequestParametersException.php rename to src/Exception/BadRequestContainHTMLTagsException.php index 269903d..ace1f41 100644 --- a/src/Exception/InvalidTagRequestParametersException.php +++ b/src/Exception/BadRequestContainHTMLTagsException.php @@ -5,11 +5,11 @@ use Serato\SwsApp\Http\Rest\Exception\AbstractBadRequestException; /** - * Class InvalidRequestParametersException + * Class BadRequestContainHTMLTagsException * The request param is invalid with html tags * @package App\Exception\RequestValidation */ -class InvalidTagRequestParametersException extends AbstractBadRequestException +class BadRequestContainHTMLTagsException extends AbstractBadRequestException { /** * @var int diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index df36da0..d757e19 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -4,7 +4,7 @@ use Serato\SwsApp\Exception\MissingRequiredParametersException; use Serato\SwsApp\Exception\InvalidRequestParametersException; -use Serato\SwsApp\Exception\InvalidTagRequestParametersException; +use Serato\SwsApp\Exception\BadRequestContainHTMLTagsException; use Psr\Http\Message\ServerRequestInterface as Request; use Rakit\Validation\Validator; use Rakit\Validation\Rules\Regex; @@ -26,7 +26,6 @@ class RequestValidation implements RequestValidationInterface * @var string */ public const NO_HTML_TAG_REGEX = '/^(?:(?!<[^>]*$)[^<])*$/'; - /** * @param Request $request @@ -43,6 +42,15 @@ public function validateRequestData( $requestBody = $request->getParsedBody() ?? []; $validator = new Validator(); + // Add a custom validation rule and exceptions when the `no_html_tag` validation rule is specified for a param. + // to prevent the need to include the Rakit Regex class in other services. + if (in_array(self::NO_HTML_TAG_RULE, $validationRules)) { + $noHtmlTagRule = new Regex(); + $noHtmlTagRule->setParameter('regex', RequestValidation::NO_HTML_TAG_REGEX); + $customRules[self::NO_HTML_TAG_RULE] = $noHtmlTagRule; + $exceptions[self::NO_HTML_TAG_RULE] = BadRequestContainHTMLTagsException::class; + } + // Add custom validation rules if (!empty($customRules)) { foreach ($customRules as $key => $customRule) { @@ -65,8 +73,6 @@ public function validateRequestData( $required = []; $invalid = []; $errors = $validation->errors()->toArray(); - // var_dump($errors); - // die; foreach ($errors as $key => $error) { if (!empty($error['required'])) { $required[] = $key; diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 6f3f7e3..6bcb7f2 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -8,7 +8,7 @@ use Rakit\Validation\Rules\Numeric; use Rakit\Validation\Rules\Regex; use Serato\SwsApp\Exception\InvalidRequestParametersException; -use Serato\SwsApp\Exception\InvalidTagRequestParametersException; +use Serato\SwsApp\Exception\BadRequestContainHTMLTagsException; use Serato\SwsApp\Exception\MissingRequiredParametersException; use Serato\SwsApp\Http\Rest\Exception\UnsupportedContentTypeException; use Serato\SwsApp\Test\TestCase; @@ -77,14 +77,8 @@ public function testValidateRequestData( */ public function dataProvider(): array { - $noHtmlTagRule = new Regex(); - $noHtmlTagRule->setParameter('regex', RequestValidation::NO_HTML_TAG_REGEX); - $paramStartWithARule = new Regex(); $paramStartWithARule->setParameter('regex', '/^a/'); - // var_dump($noHtmlTagRule->getParameters()); - // die; - return [ // no errors [ @@ -133,15 +127,19 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => null, - 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule - ], - 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class - ] + 'errorExpected' => null ], - // invalid params contains html tags throw InvalidTagRequestParametersException + // invalid params with html tags but no `no_html_tag` specified not throw error + [ + 'body' => [ + 'paramName' => '
' + ], + 'rules' => [ + 'paramName' => 'required' + ], + 'errorExpected' => null + ], + // invalid params contains html tags throw BadRequestContainHTMLTagsException [ 'body' => [ 'paramName' => '
' @@ -149,15 +147,9 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class, - 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule - ], - 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class - ] + 'errorExpected' => BadRequestContainHTMLTagsException::class, ], - // invalid params contains html tags throw InvalidTagRequestParametersException 2 + // invalid params contains html tags throw BadRequestContainHTMLTagsException 2 [ 'body' => [ 'paramName' => '
test' @@ -165,15 +157,9 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class, - 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule - ], - 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class - ] + 'errorExpected' => BadRequestContainHTMLTagsException::class ], - // invalid params contains html tags throw InvalidTagRequestParametersException 3 + // invalid params contains html tags throw BadRequestContainHTMLTagsException 3 [ 'body' => [ 'paramName' => '' @@ -181,15 +167,9 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class, - 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule - ], - 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class - ] + 'errorExpected' => BadRequestContainHTMLTagsException::class ], - // invalid params contains html tags throw InvalidTagRequestParametersException 4 + // invalid params contains html tags throw BadRequestContainHTMLTagsException 4 [ 'body' => [ 'paramName' => 'test' @@ -197,13 +177,7 @@ public function dataProvider(): array 'rules' => [ 'paramName' => RequestValidation::NO_HTML_TAG_RULE ], - 'errorExpected' => InvalidTagRequestParametersException::class, - 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule - ], - 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class - ] + 'errorExpected' => BadRequestContainHTMLTagsException::class ], // invalid params contains invalid format throws InvalidRequestParametersException [ @@ -233,12 +207,10 @@ public function dataProvider(): array ], 'errorExpected' => InvalidRequestParametersException::class, 'customRules' => [ - 'start_with_a' => $paramStartWithARule, - 'no_html_tag' => $noHtmlTagRule + 'start_with_a' => $paramStartWithARule ], 'customException' => [ - 'start_with_a' => InvalidRequestParametersException::class, - 'no_html_tag' => InvalidTagRequestParametersException::class + 'start_with_a' => InvalidRequestParametersException::class ] ], // custom rule @@ -266,12 +238,10 @@ public function dataProvider(): array ], 'errorExpected' => null, 'customRules' => [ - 'is_numeric' => new Numeric(), - 'no_html_tag' => $noHtmlTagRule + 'is_numeric' => new Numeric() ], 'customException' => [ - 'is_numeric' => UnsupportedContentTypeException::class, - 'no_html_tag' => InvalidTagRequestParametersException::class + 'is_numeric' => UnsupportedContentTypeException::class ] ], // custom exception @@ -302,15 +272,13 @@ public function dataProvider(): array ], 'errorExpected' => UnsupportedContentTypeException::class, 'customRules' => [ - 'is_numeric' => new Numeric(), - 'no_html_tag' => $noHtmlTagRule + 'is_numeric' => new Numeric() ], 'customException' => [ 'is_numeric' => UnsupportedContentTypeException::class, - 'no_html_tag' => InvalidTagRequestParametersException::class ] ], - // custom exception and invalid params contains html tags throws InvalidTagRequestParametersException + // custom exception and invalid params contains html tags throws BadRequestContainHTMLTagsException // (params order changed) [ 'body' => [ @@ -321,13 +289,11 @@ public function dataProvider(): array 'paramName' => RequestValidation::NO_HTML_TAG_RULE, 'paramName2' => 'required|is_numeric', ], - 'errorExpected' => InvalidTagRequestParametersException::class, + 'errorExpected' => BadRequestContainHTMLTagsException::class, 'customRules' => [ - 'no_html_tag' => $noHtmlTagRule, 'is_numeric' => new Numeric() ], 'customException' => [ - 'no_html_tag' => InvalidTagRequestParametersException::class, 'is_numeric' => UnsupportedContentTypeException::class ] ], From 38039077a186ca1d0555ad6292bdef9008623560 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Fri, 22 Sep 2023 13:19:13 +1200 Subject: [PATCH 13/15] specify error message --- src/Validation/RequestValidation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index d757e19..e50cef8 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -81,7 +81,7 @@ public function validateRequestData( foreach ($exceptions as $exceptionKey => $exception) { if (!empty($error[$exceptionKey])) { - throw new $exception('', $request); + throw new $exception($error[$exceptionKey], $request); } } From ef6c173a37418edcf574d39c06a4ebf6fed9d424 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Mon, 25 Sep 2023 16:11:04 +1300 Subject: [PATCH 14/15] add a NoHtmlTag rule --- src/Validation/RequestValidation.php | 24 ++++------------ src/Validation/Rules/NoHtmlTag.php | 33 ++++++++++++++++++++++ tests/Validation/RequestValidationTest.php | 19 +++++++------ 3 files changed, 48 insertions(+), 28 deletions(-) create mode 100644 src/Validation/Rules/NoHtmlTag.php diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index e50cef8..72264c0 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -8,6 +8,7 @@ use Psr\Http\Message\ServerRequestInterface as Request; use Rakit\Validation\Validator; use Rakit\Validation\Rules\Regex; +use Serato\SwsApp\Validation\Rules\NoHtmlTag; /** * Class RequestValidation @@ -15,18 +16,6 @@ */ class RequestValidation implements RequestValidationInterface { - /** - * Validation rule name for params without HTML tags. - * @var string - */ - public const NO_HTML_TAG_RULE = 'no_html_tag'; - - /** - * Regex validation rule for params without HTML tags. - * @var string - */ - public const NO_HTML_TAG_REGEX = '/^(?:(?!<[^>]*$)[^<])*$/'; - /** * @param Request $request * @param array $validationRules @@ -42,13 +31,10 @@ public function validateRequestData( $requestBody = $request->getParsedBody() ?? []; $validator = new Validator(); - // Add a custom validation rule and exceptions when the `no_html_tag` validation rule is specified for a param. - // to prevent the need to include the Rakit Regex class in other services. - if (in_array(self::NO_HTML_TAG_RULE, $validationRules)) { - $noHtmlTagRule = new Regex(); - $noHtmlTagRule->setParameter('regex', RequestValidation::NO_HTML_TAG_REGEX); - $customRules[self::NO_HTML_TAG_RULE] = $noHtmlTagRule; - $exceptions[self::NO_HTML_TAG_RULE] = BadRequestContainHTMLTagsException::class; + // Register NoHtmlTag rule and set it's exception into BadRequestContainHTMLTagsException + if (in_array(NoHtmlTag::NO_HTML_TAG_RULE, $validationRules)) { + $validator->addValidator(NoHtmlTag::NO_HTML_TAG_RULE, new NoHtmlTag()); + $exceptions[NoHtmlTag::NO_HTML_TAG_RULE] = BadRequestContainHTMLTagsException::class; } // Add custom validation rules diff --git a/src/Validation/Rules/NoHtmlTag.php b/src/Validation/Rules/NoHtmlTag.php new file mode 100644 index 0000000..e26fba2 --- /dev/null +++ b/src/Validation/Rules/NoHtmlTag.php @@ -0,0 +1,33 @@ +]*$)[^<])*$/'; + + /** @var string */ + protected $message = "The :attribute contains html tag."; + + /** + * Check the $value is valid by checking it does not contain html tags + * + * @param mixed $value + * @return bool + */ + public function check($value): bool + { + return preg_match(self::NO_HTML_TAG_REGEX, $value) > 0; + } +} diff --git a/tests/Validation/RequestValidationTest.php b/tests/Validation/RequestValidationTest.php index 6bcb7f2..015252a 100644 --- a/tests/Validation/RequestValidationTest.php +++ b/tests/Validation/RequestValidationTest.php @@ -7,6 +7,7 @@ use Rakit\Validation\RuleNotFoundException; use Rakit\Validation\Rules\Numeric; use Rakit\Validation\Rules\Regex; +use Serato\SwsApp\Validation\Rules\NoHtmlTag; use Serato\SwsApp\Exception\InvalidRequestParametersException; use Serato\SwsApp\Exception\BadRequestContainHTMLTagsException; use Serato\SwsApp\Exception\MissingRequiredParametersException; @@ -125,7 +126,7 @@ public function dataProvider(): array 'paramName' => 'br' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => null ], @@ -145,7 +146,7 @@ public function dataProvider(): array 'paramName' => '
' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE, ], 'errorExpected' => BadRequestContainHTMLTagsException::class, ], @@ -155,7 +156,7 @@ public function dataProvider(): array 'paramName' => 'test' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => BadRequestContainHTMLTagsException::class ], @@ -165,7 +166,7 @@ public function dataProvider(): array 'paramName' => '' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => BadRequestContainHTMLTagsException::class ], @@ -175,7 +176,7 @@ public function dataProvider(): array 'paramName' => 'test' ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => BadRequestContainHTMLTagsException::class ], @@ -203,7 +204,7 @@ public function dataProvider(): array ], 'rules' => [ 'paramName' => 'start_with_a', - 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + 'paramName2' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => InvalidRequestParametersException::class, 'customRules' => [ @@ -234,7 +235,7 @@ public function dataProvider(): array ], 'rules' => [ 'paramName' => 'required|is_numeric', - 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + 'paramName2' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => null, 'customRules' => [ @@ -268,7 +269,7 @@ public function dataProvider(): array ], 'rules' => [ 'paramName' => 'required|is_numeric', - 'paramName2' => RequestValidation::NO_HTML_TAG_RULE + 'paramName2' => NoHtmlTag::NO_HTML_TAG_RULE ], 'errorExpected' => UnsupportedContentTypeException::class, 'customRules' => [ @@ -286,7 +287,7 @@ public function dataProvider(): array 'paramName2' => 'invalid-number', ], 'rules' => [ - 'paramName' => RequestValidation::NO_HTML_TAG_RULE, + 'paramName' => NoHtmlTag::NO_HTML_TAG_RULE, 'paramName2' => 'required|is_numeric', ], 'errorExpected' => BadRequestContainHTMLTagsException::class, From 1f19d01e2e97d9ae53859f981ece261d7a97f340 Mon Sep 17 00:00:00 2001 From: Jing Xu Date: Mon, 25 Sep 2023 17:02:48 +1300 Subject: [PATCH 15/15] tweaks --- src/Validation/RequestValidation.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Validation/RequestValidation.php b/src/Validation/RequestValidation.php index 72264c0..ab699a8 100644 --- a/src/Validation/RequestValidation.php +++ b/src/Validation/RequestValidation.php @@ -31,11 +31,11 @@ public function validateRequestData( $requestBody = $request->getParsedBody() ?? []; $validator = new Validator(); - // Register NoHtmlTag rule and set it's exception into BadRequestContainHTMLTagsException - if (in_array(NoHtmlTag::NO_HTML_TAG_RULE, $validationRules)) { - $validator->addValidator(NoHtmlTag::NO_HTML_TAG_RULE, new NoHtmlTag()); - $exceptions[NoHtmlTag::NO_HTML_TAG_RULE] = BadRequestContainHTMLTagsException::class; - } + // add custom validators + $validator->addValidator(NoHtmlTag::NO_HTML_TAG_RULE, new NoHtmlTag()); + + // add custom exceptions + $exceptions[NoHtmlTag::NO_HTML_TAG_RULE] = BadRequestContainHTMLTagsException::class; // Add custom validation rules if (!empty($customRules)) {