From 76c6f05023bd2e27f134c3cb1a06a89fb8969037 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 16 Dec 2020 21:29:41 +0100 Subject: [PATCH 1/2] Use stable version of FOSRestBundle --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index c1832c5..cabde2a 100644 --- a/composer.json +++ b/composer.json @@ -44,7 +44,7 @@ "doctrine/common": "^2.4", "api-platform/core": "^2.1.2", - "friendsofsymfony/rest-bundle": "^2.0|^3.0@dev", + "friendsofsymfony/rest-bundle": "^2.0|^3.0", "willdurand/hateoas-bundle": "^1.0|^2.0", "jms/serializer-bundle": "^2.3|^3.0", "jms/serializer": "^1.14|^3.0" From 3895e17fe49bad6dcc3545e04e03c2609bc6b7a8 Mon Sep 17 00:00:00 2001 From: Guilhem Niot Date: Wed, 16 Dec 2020 23:44:26 +0100 Subject: [PATCH 2/2] Fix exposure of private/protected methods --- ModelDescriber/ObjectModelDescriber.php | 5 ++++ .../Entity/PrivateProtectedExposure.php | 30 +++++++++++++++++++ Tests/Functional/FunctionalTest.php | 15 ++++++++++ Tests/Functional/SwaggerUiTest.php | 1 + Tests/Functional/TestKernel.php | 5 ++++ 5 files changed, 56 insertions(+) create mode 100644 Tests/Functional/Entity/PrivateProtectedExposure.php diff --git a/ModelDescriber/ObjectModelDescriber.php b/ModelDescriber/ObjectModelDescriber.php index 0f41324..3d528d6 100644 --- a/ModelDescriber/ObjectModelDescriber.php +++ b/ModelDescriber/ObjectModelDescriber.php @@ -67,10 +67,15 @@ class ObjectModelDescriber implements ModelDescriberInterface, ModelRegistryAwar $annotationsReader->updateDefinition($reflClass, $schema); $propertyInfoProperties = $this->propertyInfo->getProperties($class, $context); + if (null === $propertyInfoProperties) { return; } + // Fix for https://github.com/nelmio/NelmioApiDocBundle/issues/1756 + // The SerializerExtractor does expose private/protected properties for some reason, so we eliminate them here + $propertyInfoProperties = array_intersect($propertyInfoProperties, $this->propertyInfo->getProperties($class, []) ?? []); + foreach ($propertyInfoProperties as $propertyName) { $serializedName = null !== $this->nameConverter ? $this->nameConverter->normalize($propertyName, $class, null, null !== $model->getGroups() ? ['groups' => $model->getGroups()] : []) : $propertyName; diff --git a/Tests/Functional/Entity/PrivateProtectedExposure.php b/Tests/Functional/Entity/PrivateProtectedExposure.php new file mode 100644 index 0000000..f0b30fb --- /dev/null +++ b/Tests/Functional/Entity/PrivateProtectedExposure.php @@ -0,0 +1,30 @@ + + */ +class PrivateProtectedExposure +{ + private $privateField; + protected $protectedField; + + /** + * @var string + */ + public $publicField; + + protected function setProtected(string $thing) + { + } +} diff --git a/Tests/Functional/FunctionalTest.php b/Tests/Functional/FunctionalTest.php index d501ff8..f1653fe 100644 --- a/Tests/Functional/FunctionalTest.php +++ b/Tests/Functional/FunctionalTest.php @@ -432,4 +432,19 @@ class FunctionalTest extends WebTestCase $operation = $this->getOperation('/api/invoke', 'get'); $this->assertSame('Invokable!', $operation->getResponses()->get(200)->getDescription()); } + + /** + * Related to https://github.com/nelmio/NelmioApiDocBundle/issues/1756 + * Ensures private/protected properties are not exposed, just like the symfony serializer does. + */ + public function testPrivateProtectedExposure() + { + // Ensure that groups are supported + $modelProperties = $this->getModel('PrivateProtectedExposure')->getProperties(); + $this->assertCount(1, $modelProperties); + $this->assertTrue($modelProperties->has('publicField')); + $this->assertFalse($modelProperties->has('privateField')); + $this->assertFalse($modelProperties->has('protectedField')); + $this->assertFalse($modelProperties->has('protected')); + } } diff --git a/Tests/Functional/SwaggerUiTest.php b/Tests/Functional/SwaggerUiTest.php index 209db31..bc845ac 100644 --- a/Tests/Functional/SwaggerUiTest.php +++ b/Tests/Functional/SwaggerUiTest.php @@ -70,6 +70,7 @@ class SwaggerUiTest extends WebTestCase 'Test' => ['type' => 'string'], 'JMSPicture_mini' => ['type' => 'object'], 'BazingaUser_grouped' => ['type' => 'object'], + 'PrivateProtectedExposure' => $expected['definitions']['PrivateProtectedExposure'], ]; $this->assertEquals($expected, json_decode($crawler->filterXPath('//script[@id="swagger-data"]')->text(), true)['spec']); diff --git a/Tests/Functional/TestKernel.php b/Tests/Functional/TestKernel.php index edf9e2e..afa4ccf 100644 --- a/Tests/Functional/TestKernel.php +++ b/Tests/Functional/TestKernel.php @@ -19,6 +19,7 @@ use JMS\SerializerBundle\JMSSerializerBundle; use Nelmio\ApiDocBundle\NelmioApiDocBundle; use Nelmio\ApiDocBundle\Tests\Functional\Entity\BazingaUser; use Nelmio\ApiDocBundle\Tests\Functional\Entity\NestedGroup\JMSPicture; +use Nelmio\ApiDocBundle\Tests\Functional\Entity\PrivateProtectedExposure; use Nelmio\ApiDocBundle\Tests\Functional\ModelDescriber\VirtualTypeClassDoesNotExistsHandlerDefinedDescriber; use Sensio\Bundle\FrameworkExtraBundle\SensioFrameworkExtraBundle; use Symfony\Bundle\FrameworkBundle\FrameworkBundle; @@ -213,6 +214,10 @@ class TestKernel extends Kernel ], 'models' => [ 'names' => [ + [ + 'alias' => 'PrivateProtectedExposure', + 'type' => PrivateProtectedExposure::class, + ], [ 'alias' => 'JMSPicture_mini', 'type' => JMSPicture::class,