[PropertyFilter] Fix whitelist comparison#1379
Conversation
| * | ||
| * @return array an array containing all of the values in array1 recursively whose values exist in array2 | ||
| */ | ||
| private function intersectArrayRecursive(array $array1, array $array2): array |
There was a problem hiding this comment.
This function and partitionAssocAndNumericArrayKeys() may not really fit into this class, if you want me to extract them into some generic utils class, let me know...
There was a problem hiding this comment.
Huum, what about something easier (should be tested):
private function getProperties(array $properties, array $whitelist = null)
{
$whitelist = $whitelist ?? $this->whitelist;
$result = [];
foreach ($properties as $key => $value) {
if (is_numeric($key)) {
if (in_array($value, $whitelist, true)) {
$result[] = $value;
}
continue;
}
if (isset($whitelist[$key]) && is_array($value) && $recursiveResult = $this->getProperties($value, $whitelist[$key])) {
$result[$key] = $recursiveResult;
}
}
return $result;
}|
Class are not always used with YAML config, IMO it makes sense to support both the old and the new behavior. |
|
Instead of introducing a dotted notation and a lot of code to maintain, I propose to support those syntaxes: # Use values (no nested properties)
arguments:
- whitelisted_properties
- false
- [ foo, bar ]# Use keys (support nested properties)
arguments:
- whitelisted_properties
- false
- { foo: ~, bar: [ a, b ] }This way, it will be in sync with how Symfony handles such cases. WDYT @antograssiot? Can you add the following examples to the test suite and remove the support for the dotted notation? |
With foo:
0: foo
1: bar
group: [baz, fuz] |
|
Thanks @meyerbaptiste, even if I feel dumb now 😛 Ok @dunglas I'll remove the dot notation. [
'foo',
'bar' => ['a', 'b']
]because that's this this how the parameters are retrieved from an url like |
|
@antograssiot maybe can you juste copy this snippet of mine: https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php#L247-L254. It looks it deals with the exact same problem. |
|
@dunglas I'll be on connected on slack in the next days, would you jump by and ping me maybe so we can figure this out ? |
| $this->overrideDefaultProperties = $overrideDefaultProperties; | ||
| $this->parameterName = $parameterName; | ||
| $this->whitelist = $whitelist; | ||
| $this->whitelist = null === $whitelist ? null : $this->formatWhitelist($whitelist); |
There was a problem hiding this comment.
This should be done in your ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection\Configuration class with the NodeDefinition::beforeNormalization() method.
There was a problem hiding this comment.
Sorry @meyerbaptiste I don't get this one. From my understanding this is only when using configuration key no ? I mean here it is just services that can be defined multiple time without using any config parameter..
There was a problem hiding this comment.
My bad! I spoke too fast and in my head whitelist was a config key... 😛
| * | ||
| * @return array an array containing all of the values in array1 recursively whose values exist in array2 | ||
| */ | ||
| private function intersectArrayRecursive(array $array1, array $array2): array |
There was a problem hiding this comment.
Huum, what about something easier (should be tested):
private function getProperties(array $properties, array $whitelist = null)
{
$whitelist = $whitelist ?? $this->whitelist;
$result = [];
foreach ($properties as $key => $value) {
if (is_numeric($key)) {
if (in_array($value, $whitelist, true)) {
$result[] = $value;
}
continue;
}
if (isset($whitelist[$key]) && is_array($value) && $recursiveResult = $this->getProperties($value, $whitelist[$key])) {
$result[$key] = $recursiveResult;
}
}
return $result;
}|
Looks cleaner/simpler indeed. |
02b549d to
2461cf2
Compare
2461cf2 to
a0025ef
Compare
|
@dunglas is it good to go now or you still want me to refractor some parts ? |
|
Thanks @antograssiot |
* GraphQL Query support (api-platform#1358) * Fix missing service when no Varnish URL is defined * [PropertyFilter] Fix whitelist comparison (api-platform#1379) * Remove wrong doc * Swagger subcollection documentation issue (api-platform#1395) * Make the requirements configurable Closes api-platform#1401 * Provide a better exception message and type Getting "Not found" on a route where you are getting an object can get really confusing. * Bump branch alias to 2.2.x-dev 2.1.x-dev is already taken by the 2.1 branch, and this should represent the next minor version anyway. * Fix tests * Reuse PriorityTaggedServiceTrait from symfony * Improve payload support and remove duplicate code in ConstraintViolationListNormalizer (api-platform#1416) * Filter Annotation implementation Parent class filters (needs test) Support for nested properties Tests Fix some comments and remove id=>id in compiler pass * Throw on abstract data providers / filters * Remove an unused var * Remove useless badges * Enable the coverage * Fix some quality issues * Add job to test upstream libs deprecations If api-platform uses upstream libs in a deprecated way, we should be aware of it. * Add job to test upstream libs deprecations If api-platform uses upstream libs in a deprecated way, we should be aware of it. * Fix missing cache tag on empty collections * Allow plain IDs with `allow_plain_identifiers` * Fix indentation for GraphQL features. * Add JSON API basic support (api-platform#785, api-platform#1036, api-platform#1175) * Clean Behat tests * Fix tags addition with an empty value * Document swagger-specific description options … and where to find them should there be newer ones. * Fix PHPUnit tests * Fix missing return statement * Support & compatibility for PHP7.2 * Add feature to update swagger context for properties * Generator compat improvements (api-platform#1429) * Add support for resource names without namespace * [SF 4.0] Make actions explicitly public * Allow phpdocumentor/reflection-docblock 4 * fix hydra documentation normalizer with subresources * Create a base collection normalizer * Fix request auto-runner * Update the changelog * Update changelog
I'm using the GroupFilter with whitelist since it got merged but never really tried/used the ProprertyFilter whitelist in an application and just relied on the tests I wrote initially. When trying to use it in a real application last week I noticed that the behavior was not the expected one.
An example to reproduce the issue is to whitelist a
fooproperty. Then when requesting/resource?properties[]=bar,foowill be present in the serialized entity.Another thing I've been trying to fix is the filter declaration and it might be considered as a BC break but given the actual implementation is unusable, I'm pretty sure that we would know if someone would have tried/implemented it already.
The thing is that the array containing properties has numeric and non-numeric keys like:
[ 'foo', 'bar', 'group' => ['baz, 'fuz'], ]I'm no expert but I didn't found a way to generate an array of this kind in yml. The old given example was generating the following:
[ 'foo', 'bar', ['group' => ['baz, 'fuz']], ]So in order to ease the array intersection, I went to a whitelist definition of the following form
Even if this is sort of a a BC break, the actual implementation has no chance to work, and using this format will be more inline with the other filter.