Fix exposure of private/protected methods

This commit is contained in:
Guilhem Niot 2020-12-16 23:44:26 +01:00
parent 76c6f05023
commit 3895e17fe4
5 changed files with 56 additions and 0 deletions

View File

@ -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;

View File

@ -0,0 +1,30 @@
<?php
/*
* This file is part of the NelmioApiDocBundle package.
*
* (c) Nelmio
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Nelmio\ApiDocBundle\Tests\Functional\Entity;
/**
* @author Guilhem N. <guilhem.niot@gmail.com>
*/
class PrivateProtectedExposure
{
private $privateField;
protected $protectedField;
/**
* @var string
*/
public $publicField;
protected function setProtected(string $thing)
{
}
}

View File

@ -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'));
}
}

View File

@ -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']);

View File

@ -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,