Skip to content

Commit

Permalink
Merge pull request #1339 from antograssiot/property-filter-whitelist
Browse files Browse the repository at this point in the history
[2.1] Allow to specify a whitelist of properties for Property Filter
  • Loading branch information
Simperfit committed Aug 29, 2017
2 parents 12871f3 + 82ea3b7 commit 2fd1c35
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 2 deletions.
92 changes: 92 additions & 0 deletions features/serializer/property_filter.feature
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,98 @@ Feature: Filter with serialization attributes on items and collections
}
"""

Scenario: Get a collection of resources by attributes foo, bar, group.baz and group.qux
When I send a "GET" request to "/dummy_properties?whitelisted_properties[]=foo&whitelisted_properties[]=bar&whitelisted_properties[group][]=baz"
Then the response status code should be 200
And the response should be in JSON
And the header "Content-Type" should be equal to "application/ld+json; charset=utf-8"
And the JSON should be valid according to this schema:
"""
{
"type": "object",
"properties": {
"@context": {"pattern": "^/contexts/DummyProperty$"},
"@id": {"pattern": "^/dummy_properties$"},
"@type": {"pattern": "^hydra:Collection$"},
"hydra:member": {
"type": "array",
"items": [
{
"type": "object",
"properties": {
"@id": {},
"@type": {},
"foo": {},
"group": {
"type": "object",
"properties": {
"@id": {},
"@type": {},
"baz": {}
},
"additionalProperties": false,
"required": ["@id", "@type", "baz"]
}
},
"additionalProperties": false,
"required": ["@id", "@type", "foo"]
},
{
"type": "object",
"properties": {
"@id": {},
"@type": {},
"foo": {},
"group": {
"type": "object",
"properties": {
"@id": {},
"@type": {},
"baz": {}
},
"additionalProperties": false,
"required": ["@id", "@type", "baz"]
}
},
"additionalProperties": false,
"required": ["@id", "@type", "foo"]
},
{
"type": "object",
"properties": {
"@id": {},
"@type": {},
"foo": {},
"group": {
"type": "object",
"properties": {
"@id": {},
"@type": {},
"baz": {}
},
"additionalProperties": false,
"required": ["@id", "@type"]
}
},
"additionalProperties": false,
"required": ["@id", "@type", "foo"]
}
],
"additionalItems": false,
"maxItems": 3,
"minItems": 3
},
"hydra:view": {
"type": "object",
"properties": {
"@id": {"pattern": "^/dummy_properties\\?whitelisted_properties%5B%5D=foo&whitelisted_properties%5B%5D=bar&whitelisted_properties%5Bgroup%5D%5B%5D=baz&page=1$"},
"@type": {"pattern": "^hydra:PartialCollectionView$"}
}
}
}
}
"""

Scenario: Get a collection of resources by attributes empty
When I send a "GET" request to "/dummy_properties?properties[]=&properties[group][]="
Then the response status code should be 200
Expand Down
8 changes: 7 additions & 1 deletion src/Serializer/Filter/PropertyFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,13 @@ final class PropertyFilter implements FilterInterface
{
private $overrideDefaultProperties;
private $parameterName;
private $whitelist;

public function __construct(string $parameterName = 'properties', bool $overrideDefaultProperties = false)
public function __construct(string $parameterName = 'properties', bool $overrideDefaultProperties = false, array $whitelist = null)
{
$this->overrideDefaultProperties = $overrideDefaultProperties;
$this->parameterName = $parameterName;
$this->whitelist = $whitelist;
}

/**
Expand All @@ -40,6 +42,10 @@ public function apply(Request $request, bool $normalization, array $attributes,
return;
}

if (null !== $this->whitelist) {
$properties = array_intersect_key($this->whitelist, $properties);
}

if (!$this->overrideDefaultProperties && isset($context['attributes'])) {
$properties = array_merge_recursive((array) $context['attributes'], $properties);
}
Expand Down
3 changes: 2 additions & 1 deletion tests/Fixtures/TestBundle/Entity/DummyProperty.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
* "normalization_context"={"groups"={"dummy_read"}},
* "denormalization_context"={"groups"={"dummy_write"}},
* "filters"={
* "dummy_property.property"
* "dummy_property.property",
* "dummy_property.whitelist_property"
* }
* })
*/
Expand Down
5 changes: 5 additions & 0 deletions tests/Fixtures/app/config/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,11 @@ services:
parent: 'api_platform.serializer.property_filter'
tags: [ { name: 'api_platform.filter', id: 'dummy_property.property' } ]

app.entity.filter.dummy_property.whitelist_property:
parent: 'api_platform.serializer.property_filter'
arguments: [ 'whitelisted_properties', false, ['foo', {'group': ['baz', 'qux']}] ]
tags: [ { name: 'api_platform.filter', id: 'dummy_property.whitelist_property' } ]

app.entity.filter.dummy_group.group:
parent: 'api_platform.serializer.group_filter'
tags: [ { name: 'api_platform.filter', id: 'dummy_group.group' } ]
Expand Down
22 changes: 22 additions & 0 deletions tests/Serializer/Filter/PropertyFilterTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,28 @@ public function testApplyWithoutPropertiesInRequest()
$this->assertEquals(['attributes' => ['foo', 'bar']], $context);
}

public function testApplyWithPropertiesWhitelist()
{
$request = new Request(['properties' => ['foo', 'bar', 'group' => ['baz' => ['baz', 'qux'], 'qux']]]);
$context = ['attributes' => ['qux']];

$propertyFilter = new PropertyFilter('properties', false, ['foo', 'group' => ['baz' => ['qux']]]);
$propertyFilter->apply($request, true, [], $context);

$this->assertEquals(['attributes' => ['qux', 'foo', 'group' => ['baz' => ['qux']]]], $context);
}

public function testApplyWithoutPropertiesWhitelistWithOverriding()
{
$request = new Request(['properties' => ['foo', 'bar', 'baz']]);
$context = ['attributes' => ['qux']];

$propertyFilter = new PropertyFilter('properties', true, ['foo', 'baz']);
$propertyFilter->apply($request, true, [], $context);

$this->assertEquals(['attributes' => ['foo', 'baz']], $context);
}

public function testApplyWithInvalidPropertiesInRequest()
{
$request = new Request(['properties' => 'foo,bar,baz']);
Expand Down

0 comments on commit 2fd1c35

Please sign in to comment.