Skip to content

Commit 2c37219

Browse files
authored
feat: integrate security for the class and property (#138)
1 parent 35b4f9b commit 2c37219

File tree

10 files changed

+44
-6
lines changed

10 files changed

+44
-6
lines changed

src/AttributeGenerator/ApiPlatformCoreAttributeGenerator.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,9 @@ public function generateClassAttributes(Class_ $class): array
4444
$arguments['shortName'] = $localName;
4545
}
4646
$arguments['iri'] = $class->resourceUri();
47+
if ($class->security) {
48+
$arguments['security'] = $class->security;
49+
}
4750

4851
if ([] !== $class->operations()) {
4952
$operations = $this->validateClassOperations($class->operations());
@@ -106,7 +109,13 @@ function (Options $options, $value) {
106109
*/
107110
public function generatePropertyAttributes(Property $property, string $className): array
108111
{
109-
return $property->isCustom ? [] : [['ApiProperty' => ['iri' => $property->resourceUri()]]];
112+
$arguments['iri'] = $property->resourceUri();
113+
114+
if ($property->security) {
115+
$arguments['security'] = $property->security;
116+
}
117+
118+
return $property->isCustom ? [] : [['ApiProperty' => $arguments]];
110119
}
111120

112121
/**

src/Model/Class_.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ final class Class_
4242
/** @var bool|string|null */
4343
private $parent;
4444
private RdfResource $resource;
45+
public ?string $security = null;
4546

4647
private const SCHEMA_ORG_ENUMERATION = 'https://schema.org/Enumeration';
4748

src/Model/Property.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ final class Property
4242
public bool $isEnum = false;
4343
public ?string $adderRemoverTypeHint = null;
4444
public array $groups = [];
45+
public ?string $security = null;
4546
/** @var array<string, array>[] */
4647
private array $attributes = [];
4748
private array $annotations = [];

src/PropertyGenerator/PropertyGenerator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ public function __invoke(array $config, Class_ $class, RdfResource $type, array
145145
$schemaGeneratorProperty->mappedBy = $propertyConfig['mappedBy'] ?? null;
146146
$schemaGeneratorProperty->inversedBy = $propertyConfig['inversedBy'] ?? null;
147147
$schemaGeneratorProperty->groups = $propertyConfig['groups'] ?? [];
148+
$schemaGeneratorProperty->security = $propertyConfig['security'] ?? null;
148149
$schemaGeneratorProperty->isId = false;
149150
$class->addProperty($schemaGeneratorProperty);
150151

src/TypesGenerator.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,7 @@ public function generate(array $config): void
143143
$typeConfig = $config['types'][$typeName] ?? null;
144144
$parent = $typeConfig['parent'] ?? null;
145145
$class = new Class_($typeName, $type, $parent);
146+
$class->security = $typeConfig['security'] ?? null;
146147

147148
if ($class->isEnum()) {
148149
$class = (new EnumClassMutator(

src/TypesGeneratorConfiguration.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ static function ($rdf) {
169169
->end()
170170
->scalarNode('parent')->defaultFalse()->info('The parent class, set to false for a top level class')->end()
171171
->scalarNode('guessFrom')->defaultValue('Thing')->info('If declaring a custom class, this will be the class from which properties type will be guessed')->end()
172+
->scalarNode('security')->defaultNull()->info('Security directive for the class')->end()
172173
->booleanNode('allProperties')->defaultFalse()->info('Import all existing properties')->end()
173174
->arrayNode('properties')
174175
->info('Properties of this type to use')
@@ -194,6 +195,7 @@ static function ($rdf) {
194195
->example('{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}')
195196
->prototype('variable')->end()
196197
->end()
198+
->scalarNode('security')->defaultNull()->info('Security directive for the property')->end()
197199
->arrayNode('groups')
198200
->info('Symfony Serialization Groups')
199201
->prototype('scalar')->end()

tests/AttributeGenerator/ApiPlatformCoreAttributeGeneratorTest.php

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,14 +68,30 @@ public function provideGenerateClassAttributesCases(): \Generator
6868
yield 'abstract' => [(new Class_('Abstract', new Resource('https://schema.org/Abstract')))->setIsAbstract(true), []];
6969

7070
yield 'with short name' => [(new Class_('WithShortName', new Resource('https://schema.org/DifferentLocalName'))), [['ApiResource' => ['shortName' => 'DifferentLocalName', 'iri' => 'https://schema.org/DifferentLocalName']]]];
71+
72+
$class = new Class_('WithSecurity', new Resource('https://schema.org/WithSecurity'));
73+
$class->security = "is_granted('ROLE_USER')";
74+
yield 'with security' => [$class, [['ApiResource' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_USER')"]]]];
75+
}
76+
77+
/**
78+
* @dataProvider provideGeneratePropertyAttributesCases
79+
*/
80+
public function testGeneratePropertyAttributes(Property $property, array $attributes): void
81+
{
82+
$this->assertSame($attributes, $this->generator->generatePropertyAttributes($property, 'Res'));
7183
}
7284

73-
public function testGeneratePropertyAttributes(): void
85+
public function provideGeneratePropertyAttributesCases(): \Generator
7486
{
7587
$property = new Property('prop');
7688
$property->resource = new Resource('https://schema.org/prop');
89+
yield 'classical' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/prop']]]];
7790

78-
$this->assertSame([['ApiProperty' => ['iri' => 'https://schema.org/prop']]], $this->generator->generatePropertyAttributes($property, 'Res'));
91+
$property = new Property('WithSecurity');
92+
$property->resource = new Resource('https://schema.org/WithSecurity');
93+
$property->security = "is_granted('ROLE_ADMIN')";
94+
yield 'with security' => [$property, [['ApiProperty' => ['iri' => 'https://schema.org/WithSecurity', 'security' => "is_granted('ROLE_ADMIN')"]]]];
7995
}
8096

8197
public function testGenerateCustomPropertyAttributes(): void

tests/Command/DumpConfigurationTest.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,9 @@ interface: null
166166
# If declaring a custom class, this will be the class from which properties type will be guessed
167167
guessFrom: Thing
168168
169+
# Security directive for the class
170+
security: null
171+
169172
# Import all existing properties
170173
allProperties: false
171174
@@ -188,6 +191,9 @@ interface: null
188191
# The doctrine column attribute content
189192
ormColumn: [] # Example: '{type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}}'
190193
194+
# Security directive for the property
195+
security: null
196+
191197
# Symfony Serialization Groups
192198
groups: []
193199

tests/e2e/schema.yml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,15 @@ types:
77
properties:
88
name: ~
99
Person:
10+
security: "is_granted('ROLE_USER')"
1011
properties:
1112
familyName: ~
1213
givenName: ~
1314
additionalName: { groups: ['extra'] }
1415
address: { range: https://schema.org/PostalAddress }
1516
birthDate: ~
1617
telephone: ~
17-
email: { unique: true }
18+
email: { unique: true, security: "is_granted('ROLE_ADMIN')" }
1819
url: ~
1920
customColumn: { ormColumn: {type: "decimal", precision: 5, scale: 1, options: {comment: "my comment"}} }
2021
PostalAddress:

tests/e2e/src/App/Entity/Person.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* @see https://schema.org/Person
1818
*/
1919
#[ORM\Entity]
20-
#[ApiResource(iri: 'https://schema.org/Person')]
20+
#[ApiResource(iri: 'https://schema.org/Person', security: 'is_granted(\'ROLE_USER\')')]
2121
#[UniqueEntity('email')]
2222
class Person
2323
{
@@ -88,7 +88,7 @@ class Person
8888
* @see https://schema.org/email
8989
*/
9090
#[ORM\Column(type: 'text', nullable: true, unique: true)]
91-
#[ApiProperty(iri: 'https://schema.org/email')]
91+
#[ApiProperty(iri: 'https://schema.org/email', security: 'is_granted(\'ROLE_ADMIN\')')]
9292
#[Assert\Email]
9393
private ?string $email = null;
9494

0 commit comments

Comments
 (0)