• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

api-platform / core / 7581037639

19 Jan 2024 08:03AM UTC coverage: 59.207% (-0.1%) from 59.351%
7581037639

push

github

web-flow
feat(symfony): Link security (#5290)

* [Link] Start Link Security

* feat(provider): Auto Resolve Get Operation and Parameters

* chore(CS): fix CS

* feat(tests): Add DenyAccessListener tests

* feat(tests): Add link security behat tests

* fix(test): fix mongodb document configuration

* fix(readlistner): fix error 500 on not existing entity

* feat(linksecurity): expand functionality to cover all combinations of to and from property and add optional object name

* feat(linksecurity): add more tests

* chore: fix cs

* chore: phpstan fix

* fix: Move logic to refactored, now used, classes

* fix: refactor unit tests

* fix: backport for legacy event system as well

* Revert "fix: backport for legacy event system as well"

This reverts commit 16f14c836.

* refactor: Refactor ReadProvider.php and AccessCheckerProvider.php to extract link security into their own providers

* mark providers final, disable feature by default

42 of 74 new or added lines in 5 files covered. (56.76%)

200 existing lines in 3 files now uncovered.

16427 of 27745 relevant lines covered (59.21%)

32.77 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

64.29
/src/Metadata/Link.php
1
<?php
2

3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <dunglas@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace ApiPlatform\Metadata;
15

16
#[\Attribute(\Attribute::TARGET_PROPERTY | \Attribute::TARGET_METHOD | \Attribute::TARGET_PARAMETER)]
17
final class Link
18
{
19
    public function __construct(private ?string $parameterName = null, private ?string $fromProperty = null, private ?string $toProperty = null, private ?string $fromClass = null, private ?string $toClass = null, private ?array $identifiers = null, private ?bool $compositeIdentifier = null, private ?string $expandedValue = null, private ?string $security = null, private ?string $securityMessage = null, private ?string $securityObjectName = null)
20
    {
21
        // For the inverse property shortcut
22
        if ($this->parameterName && class_exists($this->parameterName)) {
148✔
23
            $this->fromClass = $this->parameterName;
×
24
        }
25
    }
26

27
    public function getParameterName(): ?string
28
    {
29
        return $this->parameterName;
64✔
30
    }
31

32
    public function withParameterName(string $parameterName): self
33
    {
34
        $self = clone $this;
32✔
35
        $self->parameterName = $parameterName;
32✔
36

37
        return $self;
32✔
38
    }
39

40
    public function getFromClass(): ?string
41
    {
42
        return $this->fromClass;
128✔
43
    }
44

45
    public function withFromClass(string $fromClass): self
46
    {
47
        $self = clone $this;
60✔
48
        $self->fromClass = $fromClass;
60✔
49

50
        return $self;
60✔
51
    }
52

53
    public function getToClass(): ?string
54
    {
55
        return $this->toClass;
24✔
56
    }
57

58
    public function withToClass(string $toClass): self
59
    {
60
        $self = clone $this;
24✔
61
        $self->toClass = $toClass;
24✔
62

63
        return $self;
24✔
64
    }
65

66
    public function getFromProperty(): ?string
67
    {
68
        return $this->fromProperty;
56✔
69
    }
70

71
    public function withFromProperty(string $fromProperty): self
72
    {
73
        $self = $this;
28✔
74
        $self->fromProperty = $fromProperty;
28✔
75

76
        return $self;
28✔
77
    }
78

79
    public function getToProperty(): ?string
80
    {
81
        return $this->toProperty;
80✔
82
    }
83

84
    public function withToProperty(string $toProperty): self
85
    {
86
        $self = clone $this;
×
87
        $self->toProperty = $toProperty;
×
88

89
        return $self;
×
90
    }
91

92
    public function getIdentifiers(): ?array
93
    {
94
        return $this->identifiers;
92✔
95
    }
96

97
    public function withIdentifiers(array $identifiers): self
98
    {
99
        $self = clone $this;
60✔
100
        $self->identifiers = $identifiers;
60✔
101

102
        return $self;
60✔
103
    }
104

105
    public function getCompositeIdentifier(): ?bool
106
    {
107
        return $this->compositeIdentifier;
44✔
108
    }
109

110
    public function withCompositeIdentifier(bool $compositeIdentifier): self
111
    {
112
        $self = clone $this;
8✔
113
        $self->compositeIdentifier = $compositeIdentifier;
8✔
114

115
        return $self;
8✔
116
    }
117

118
    public function getExpandedValue(): ?string
119
    {
120
        return $this->expandedValue;
56✔
121
    }
122

123
    public function withExpandedValue(string $expandedValue): self
124
    {
125
        $self = clone $this;
×
126
        $self->expandedValue = $expandedValue;
×
127

128
        return $self;
×
129
    }
130

131
    public function getSecurity(): ?string
132
    {
133
        return $this->security;
35✔
134
    }
135

136
    public function getSecurityMessage(): ?string
137
    {
138
        return $this->securityMessage;
12✔
139
    }
140

141
    public function withSecurity(?string $security): self
142
    {
NEW
143
        $self = clone $this;
×
NEW
144
        $self->security = $security;
×
145

NEW
146
        return $self;
×
147
    }
148

149
    public function withSecurityMessage(?string $securityMessage): self
150
    {
NEW
151
        $self = clone $this;
×
NEW
152
        $self->securityMessage = $securityMessage;
×
153

NEW
154
        return $self;
×
155
    }
156

157
    public function getSecurityObjectName(): ?string
158
    {
159
        return $this->securityObjectName;
16✔
160
    }
161

162
    public function withSecurityObjectName(?string $securityObjectName): self
163
    {
NEW
164
        $self = clone $this;
×
NEW
165
        $self->securityObjectName = $securityObjectName;
×
166

NEW
167
        return $self;
×
168
    }
169

170
    public function withLink(self $link): self
171
    {
172
        $self = clone $this;
4✔
173

174
        if (!$self->getToProperty() && ($toProperty = $link->getToProperty())) {
4✔
175
            $self->toProperty = $toProperty;
4✔
176
        }
177

178
        if (!$self->getCompositeIdentifier() && ($compositeIdentifier = $link->getCompositeIdentifier())) {
4✔
179
            $self->compositeIdentifier = $compositeIdentifier;
×
180
        }
181

182
        if (!$self->getFromClass() && ($fromClass = $link->getFromClass())) {
4✔
183
            $self->fromClass = $fromClass;
×
184
        }
185

186
        if (!$self->getToClass() && ($toClass = $link->getToClass())) {
4✔
187
            $self->toClass = $toClass;
×
188
        }
189

190
        if (!$self->getIdentifiers() && ($identifiers = $link->getIdentifiers())) {
4✔
191
            $self->identifiers = $identifiers;
×
192
        }
193

194
        if (!$self->getFromProperty() && ($fromProperty = $link->getFromProperty())) {
4✔
195
            $self->fromProperty = $fromProperty;
×
196
        }
197

198
        if (!$self->getParameterName() && ($parameterName = $link->getParameterName())) {
4✔
199
            $self->parameterName = $parameterName;
4✔
200
        }
201

202
        if (!$self->getExpandedValue() && ($expandedValue = $link->getExpandedValue())) {
4✔
203
            $self->expandedValue = $expandedValue;
×
204
        }
205

206
        if (!$self->getSecurity() && ($security = $link->getSecurity())) {
4✔
NEW
207
            $self->security = $security;
×
208
        }
209

210
        if (!$self->getSecurityMessage() && ($securityMessage = $link->getSecurityMessage())) {
4✔
NEW
211
            $self->securityMessage = $securityMessage;
×
212
        }
213

214
        if (!$self->getSecurityObjectName() && ($securityObjectName = $link->getSecurityObjectName())) {
4✔
NEW
215
            $self->securityObjectName = $securityObjectName;
×
216
        }
217

218
        return $self;
4✔
219
    }
220
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc