limoncello-php / app

Quick start JSON API application
MIT License
83 stars 7 forks source link

JsonApiQueries validation #48

Open dreamsbond opened 6 years ago

dreamsbond commented 6 years ago

with Schema::REL_NAME assigned to getFilterRules which come with r::asSantizedString();

I found if i try invalid to test validation, like with "#" as prefix, the validation throws

Limoncello\\Flute\\Exceptions\\InvalidArgumentException in C:\\API\\vendor\\limoncello-php\\flute\\src\\Adapters\\ModelQueryBuilder.php:797\nStack trace:\n#0 C:\\API\\vendor\\limoncello-php\\flute\\src\\Adapters\\ModelQueryBuilder.php(731): Limoncello\\Flute\\Adapters\\ModelQueryBuilder->firstValue(Array)\n#1 C:\\API\\vendor\\limoncello-php\\flute\\src\\Adapters\\ModelQueryBuilder.php(527): Limoncello\\Flute\\Adapters\\ModelQueryBuilder->createFilterExpression('`roles1`.`name`', 0, Array)\n#2 C:\\API\\vendor\\limoncello-php\\flute\\src\\Adapters\\ModelQueryBuilder.php(343): Limoncello\\Flute\\Adapters\\ModelQueryBuilder->applyFilters(Object(Doctrine\\DBAL\\Query\\Expression\\CompositeExpression), 'roles1', Array)\n#3 C:\\API\\vendor\\limoncello-php\\flute\\src\\Api\\Crud.php(454): Limoncello\\Flute\\Adapters\\ModelQueryBuilder->addFiltersWithAndToAlias(Array)\n#4 C:\\API\\vendor\\limoncello-php\\flute\\src\\Api\\Crud.php(836): Limoncello\\Flute\\Api\\Crud->applyAliasFilters(Object(Limoncello\\Flute\\Adapters\\ModelQueryBuilder))\n#5 C:\\API\\vendor\\limoncello-php\\flute\\src\\Api\\Crud.php(873): Limoncello\\Flute\\Api\\Crud->createIndexModelBuilder()\n#6 C:\\API\\server\\app\\Api\\RolesApi.php(64): Limoncello\\Flute\\Api\\Crud->index()\n#7 C:\\API\\vendor\\limoncello-php\\flute\\src\\Http\\Traits\\DefaultControllerMethodsTrait.php(83): App\\Api\\RolesApi->index()\n#8 C:\\API\\vendor\\limoncello-php\\flute\\src\\Http\\BaseController.php(78): Limoncello\\Flute\\Http\\BaseController::defaultIndexHandler(Array, Object(Zend\\Diactoros\\Uri), Object(Limoncello\\Flute\\Validation\\JsonApi\\QueryParser), Object(Limoncello\\Flute\\Http\\Query\\ParametersMapper), Object(App\\Api\\RolesApi), Object(Limoncello\\Application\\Settings\\CacheSettingsProvider), Object(Limoncello\\Flute\\Schema\\JsonSchemes), Object(Limoncello\\Flute\\Encoder\\Encoder))\n#9 [internal function]: Limoncello\\Flute\\Http\\BaseController::index(Array, Object(Limoncello\\Container\\Container), Object(Zend\\Diactoros\\ServerRequest))\n#10 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(332): call_user_func(Array, Array, Object(Limoncello\\Container\\Container), Object(Zend\\Diactoros\\ServerRequest))\n#11 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(375): Limoncello\\Core\\Application\\Application->callHandler(Array, Array, Object(Limoncello\\Container\\Container), Object(Zend\\Diactoros\\ServerRequest))\n#12 C:\\API\\vendor\\limoncello-php\\passport\\src\\Authentication\\PassportMiddleware.php(82): Limoncello\\Core\\Application\\Application->Limoncello\\Core\\Application\\{closure}(Object(Zend\\Diactoros\\ServerRequest))\n#13 [internal function]: Limoncello\\Passport\\Authentication\\PassportMiddleware::handle(Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#14 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(480): call_user_func(Array, Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#15 C:\\API\\vendor\\limoncello-php\\application\\src\\Packages\\Cors\\CorsMiddleware.php(57): Limoncello\\Core\\Application\\Application->Limoncello\\Core\\Application\\{closure}(Object(Zend\\Diactoros\\ServerRequest))\n#16 [internal function]: Limoncello\\Application\\Packages\\Cors\\CorsMiddleware::handle(Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#17 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(480): call_user_func(Array, Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#18 C:\\API\\vendor\\limoncello-php\\application\\src\\Packages\\Cookies\\CookieMiddleware.php(42): Limoncello\\Core\\Application\\Application->Limoncello\\Core\\Application\\{closure}(Object(Zend\\Diactoros\\ServerRequest))\n#19 [internal function]: Limoncello\\Application\\Packages\\Cookies\\CookieMiddleware::handle(Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#20 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(480): call_user_func(Array, Object(Zend\\Diactoros\\ServerRequest), Object(Closure), Object(Limoncello\\Container\\Container))\n#21 [internal function]: Limoncello\\Core\\Application\\Application->Limoncello\\Core\\Application\\{closure}(Object(Zend\\Diactoros\\ServerRequest))\n#22 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(183): call_user_func(Object(Closure), Object(Zend\\Diactoros\\ServerRequest))\n#23 C:\\API\\vendor\\limoncello-php\\core\\src\\Application\\Application.php(140): Limoncello\\Core\\Application\\Application->handleRequest(Object(Closure), Object(Zend\\Diactoros\\ServerRequest))\n#24 C:\\API\\public\\index.php(5): Limoncello\\Core\\Application\\Application->run()\n#25 {main}"
    public static function getFilterRules(): ?array
    {
        return [
            Schema::RESOURCE_ID      => r::stringToInt(r::moreThan(0)),
            Schema::ATTR_NAME        => r::asSanitizedString(),
            Schema::ATTR_DESCRIPTION => r::asSanitizedString(),
            Schema::ATTR_DESCRIPTION => r::asSanitizedString(),
        ];
    }
neomerx commented 6 years ago

Validation rule asSanitizedString is defined here and does 2 things: firstly it checks input is a string and then applies filter_var with FILTER_SANITIZE_FULL_SPECIAL_CHARS

If you have #something as an input for ATTR_NAME it passes unchanged

$foo = filter_var('#something', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
// $foo === '#something'

What I can see from the error stack is that builder tries to read an input value for =/eq/equals operation and throws an exception from here which means you don't have actual input.

Can you please check you have a valid input and if you think so post it here?