Skip to content

Commit e45656d

Browse files
committed
WIP phpstan level 6
1 parent c82825f commit e45656d

File tree

16 files changed

+341
-23
lines changed

16 files changed

+341
-23
lines changed

phpstan.neon

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11

22
parameters:
3-
level: 4
3+
level: 6
44
paths:
55
- src
66
tmpDir: build/phpstan

src/Codebooks/MetadataPolicyOperatorsEnum.php

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,17 @@ enum MetadataPolicyOperatorsEnum: string
2020
case SupersetOf = 'superset_of';
2121
case Essential = 'essential';
2222

23+
/**
24+
* @return string[]
25+
*/
2326
public static function values(): array
2427
{
2528
return array_column(self::cases(), 'value');
2629
}
2730

31+
/**
32+
* @return string[]
33+
*/
2834
public function getSupportedOperatorValueTypes(): array
2935
{
3036
return match ($this) {
@@ -54,6 +60,9 @@ public function getSupportedOperatorValueTypes(): array
5460
};
5561
}
5662

63+
/**
64+
* @return string[]
65+
*/
5766
public function getSupportedParameterValueTypes(): array
5867
{
5968
return match ($this) {
@@ -79,6 +88,7 @@ public function getSupportedParameterValueTypes(): array
7988
}
8089

8190
/**
91+
* @return string[]
8292
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
8393
*/
8494
public function getSupportedOperatorContainedValueTypes(): array
@@ -96,6 +106,7 @@ public function getSupportedOperatorContainedValueTypes(): array
96106
}
97107

98108
/**
109+
* @return string[]
99110
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
100111
*/
101112
public function getSupportedParameterContainedValueTypes(): array
@@ -113,13 +124,19 @@ public function getSupportedParameterContainedValueTypes(): array
113124
};
114125
}
115126

127+
/**
128+
* @phpstan-ignore missingType.iterableValue (We can handle mixed type using array_diff)
129+
*/
116130
public function isValueSubsetOf(mixed $value, array $superset): bool
117131
{
118132
$value = is_array($value) ? $value : [$value];
119133

120134
return array_diff($value, $superset) === [];
121135
}
122136

137+
/**
138+
* @phpstan-ignore missingType.iterableValue (We can handle mixed type using array_diff)
139+
*/
123140
public function isValueSupersetOf(mixed $value, array $subset): bool
124141
{
125142
$value = is_array($value) ? $value : [$value];
@@ -178,6 +195,9 @@ public function isParameterValueTypeSupported(mixed $parameterValue): bool
178195
return true;
179196
}
180197

198+
/**
199+
* @return string[]
200+
*/
181201
public function getSupportedOperatorCombinations(): array
182202
{
183203
return [
@@ -226,6 +246,9 @@ public function getSupportedOperatorCombinations(): array
226246
];
227247
}
228248

249+
/**
250+
* @param string[] $operatorKeys
251+
*/
229252
public function isOperatorCombinationSupported(array $operatorKeys): bool
230253
{
231254
return array_diff($operatorKeys, $this->getSupportedOperatorCombinations()) === [];
@@ -234,6 +257,8 @@ public function isOperatorCombinationSupported(array $operatorKeys): bool
234257
/**
235258
* Validate general parameter operation rules like operator combinations and operator value type.
236259
*
260+
* @param array<string,mixed> $parameterOperations
261+
*
237262
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
238263
*/
239264
public static function validateGeneralParameterOperationRules(array $parameterOperations): void

src/Federation/EntityStatement.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,7 @@ public function getTrustMarks(): ?TrustMarkClaimBag
227227

228228
/** @psalm-suppress MixedAssignment */
229229
while (is_array($trustMarkClaimData = array_pop($trustMarksClaims))) {
230+
$trustMarkClaimData = $this->helpers->arr()->ensureStringKeys($trustMarkClaimData);
230231
$trustMarkClaimBag->add($this->trustMarkClaimFactory->buildFrom($trustMarkClaimData));
231232
}
232233

src/Federation/EntityStatement/Factories/TrustMarkClaimFactory.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ public function __construct(
1818
}
1919

2020
/**
21+
* @param array<string,mixed> $otherClaims
2122
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
2223
* @throws \SimpleSAML\OpenID\Exceptions\TrustMarkException
2324
* @throws \SimpleSAML\OpenID\Exceptions\TrustMarkClaimException
@@ -31,6 +32,7 @@ public function build(
3132
}
3233

3334
/**
35+
* @param array<string,mixed> $trustMarkClaimData
3436
* @throws \SimpleSAML\OpenID\Exceptions\TrustMarkClaimException
3537
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
3638
*/

src/Federation/EntityStatement/TrustMarkClaim.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
class TrustMarkClaim
1515
{
1616
/**
17+
* @param array<string,mixed> $otherClaims
1718
* @throws \SimpleSAML\OpenID\Exceptions\TrustMarkClaimException
1819
* @throws \SimpleSAML\OpenID\Exceptions\TrustMarkException
1920
* @throws \SimpleSAML\OpenID\Exceptions\JwsException

src/Federation/MetadataPolicyResolver.php

Lines changed: 39 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,43 @@ public function __construct(
1717
}
1818

1919
/**
20-
* @param array[] $metadataPolicies
20+
* @return array<string,array<string,array<string,mixed>>>
21+
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
22+
* @psalm-suppress MixedAssignment
23+
*/
24+
public function ensureFormat(array $metadataPolicies): array
25+
{
26+
foreach ($metadataPolicies as $entityType => $metadataPolicyEntityType) {
27+
if (!is_string($entityType)) {
28+
throw new MetadataPolicyException('Invalid metadata policy format (entity type key).');
29+
}
30+
if (!is_array($metadataPolicyEntityType)) {
31+
throw new MetadataPolicyException('Invalid metadata policy format (entity type value).');
32+
}
33+
34+
foreach ($metadataPolicyEntityType as $parameter => $metadataPolicyParameter) {
35+
if (!is_string($parameter)) {
36+
throw new MetadataPolicyException('Invalid metadata policy format (parameter key).');
37+
}
38+
if (!is_array($metadataPolicyParameter)) {
39+
throw new MetadataPolicyException('Invalid metadata policy format (parameter value).');
40+
}
41+
42+
$operators = array_keys($metadataPolicyParameter);
43+
foreach ($operators as $operator) {
44+
if (!is_string($operator)) {
45+
throw new MetadataPolicyException('Invalid metadata policy format (operator key).');
46+
}
47+
}
48+
}
49+
}
50+
51+
/** @var array<string,array<string,array<string,mixed>>> $metadataPolicies */
52+
return $metadataPolicies;
53+
}
54+
55+
/**
56+
* @param array<array<string,array<string,array<string,mixed>>>> $metadataPolicies
2157
* @param string[] $criticalMetadataPolicyOperators
2258
*
2359
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
@@ -28,6 +64,7 @@ public function for(
2864
array $metadataPolicies,
2965
array $criticalMetadataPolicyOperators = [],
3066
): array {
67+
/** @var array<string,array<string,mixed>> $currentPolicy */
3168
$currentPolicy = [];
3269
$supportedOperators = MetadataPolicyOperatorsEnum::values();
3370

@@ -63,15 +100,6 @@ public function for(
63100
// Go over each metadata parameter and resolve the policy.
64101
/** @psalm-suppress MixedAssignment We'll check if $nextPolicyParameterOperations is array type. */
65102
foreach ($nextPolicy as $nextPolicyParameter => $nextPolicyParameterOperations) {
66-
if (!is_array($nextPolicyParameterOperations)) {
67-
throw new MetadataPolicyException(
68-
sprintf(
69-
'Invalid format for metadata policy operations encountered: %s',
70-
var_export($nextPolicyParameterOperations, true),
71-
),
72-
);
73-
}
74-
75103
MetadataPolicyOperatorsEnum::validateGeneralParameterOperationRules($nextPolicyParameterOperations);
76104
MetadataPolicyOperatorsEnum::validateSpecificParameterOperationRules($nextPolicyParameterOperations);
77105

@@ -194,7 +222,7 @@ public function for(
194222
}
195223

196224
// Check if the current policy is in valid state after merge.
197-
/** @var array $currentPolicyParameterOperations We ensured this is array. */
225+
/** @var array<string,array<string,mixed>> $currentPolicy */
198226
foreach ($currentPolicy as $currentPolicyParameterOperations) {
199227
MetadataPolicyOperatorsEnum::validateGeneralParameterOperationRules(
200228
$currentPolicyParameterOperations,

src/Federation/TrustChain.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ class TrustChain implements JsonSerializable
3636
* issued by the most Superior Entity and ends with the Subordinate Statement issued by the Immediate Superior
3737
* of the Trust Chain subject.
3838
*
39-
* @var array[]
39+
* @var array<array<string,array<string,array<string,mixed>>>>
4040
*/
4141
protected array $metadataPolicies = [];
4242

@@ -359,10 +359,13 @@ protected function gatherCriticalMetadataPolicyOperators(EntityStatement $entity
359359

360360
/**
361361
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
362+
* @throws \SimpleSAML\OpenID\Exceptions\MetadataPolicyException
362363
*/
363364
protected function gatherMetadataPolicies(EntityStatement $entityStatement): void
364365
{
365-
$policy = $entityStatement->getMetadataPolicy() ?? [];
366+
$policy = $this->metadataPolicyResolver->ensureFormat(
367+
$entityStatement->getMetadataPolicy() ?? [],
368+
);
366369

367370
if ($policy !== []) {
368371
array_unshift($this->metadataPolicies, $policy);

src/Helpers/Arr.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,4 +27,15 @@ public function ensureArrayDepth(array &$array, int|string ...$keys): void
2727

2828
$this->ensureArrayDepth($array[$key], ...$keys);
2929
}
30+
31+
/**
32+
* @return array<string,mixed>
33+
*/
34+
public function ensureStringKeys(array $array): array
35+
{
36+
return array_combine(
37+
array_map('strval', array_keys($array)),
38+
$array,
39+
);
40+
}
3041
}

src/Jwks/JwksFetcher.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ public function __construct(
3131
}
3232

3333
/**
34+
* @return array{keys:array <string,mixed>}
3435
* @throws \SimpleSAML\OpenID\Exceptions\JwksException
3536
*/
3637
protected function decodeJwksJson(string $jwksJson): array
@@ -62,6 +63,8 @@ protected function decodeJwksJson(string $jwksJson): array
6263
throw new JwksException($message);
6364
}
6465

66+
$jwks[ClaimsEnum::Keys->value] = $this->helpers->arr()->ensureStringKeys($jwks[ClaimsEnum::Keys->value]);
67+
/** @var array{keys:array<string,mixed>} $jwks */
6568
return $jwks;
6669
}
6770

@@ -167,6 +170,7 @@ public function fromJwksUri(string $uri): ?JwksDecorator
167170

168171
/**
169172
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
173+
* @phpstan-ignore missingType.iterableValue (JWKS array is validated later)
170174
*/
171175
public function fromCacheOrSignedJwksUri(string $uri, array $federationJwks): ?JwksDecorator
172176
{
@@ -177,6 +181,7 @@ public function fromCacheOrSignedJwksUri(string $uri, array $federationJwks): ?J
177181
* @param string $uri URI from which to fetch SignedJwks statement.
178182
* @param array $federationJwks Federation JWKS which will be used to check signature on SignedJwks statement.
179183
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
184+
* @phpstan-ignore missingType.iterableValue (JWKS array is validated later)
180185
*/
181186
public function fromSignedJwksUri(string $uri, array $federationJwks): ?JwksDecorator
182187
{

src/Jwks/SignedJwks.php

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
class SignedJwks extends ParsedJws implements JsonSerializable
1414
{
1515
/**
16+
* @return array<array<string,mixed>>
1617
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
1718
* @throws \SimpleSAML\OpenID\Exceptions\SignedJwksException
1819
*/
@@ -28,7 +29,10 @@ public function getKeys(): array
2829
);
2930
}
3031

31-
return $keys;
32+
return array_map(
33+
$this->helpers->arr()->ensureStringKeys(...),
34+
$keys,
35+
);
3236
}
3337

3438
/**
@@ -82,6 +86,11 @@ protected function validate(): void
8286
);
8387
}
8488

89+
/**
90+
* @return array{keys: array<array<string, mixed>>}
91+
* @throws \SimpleSAML\OpenID\Exceptions\JwsException
92+
* @throws \SimpleSAML\OpenID\Exceptions\SignedJwksException
93+
*/
8594
public function jsonSerialize(): array
8695
{
8796
return [ClaimsEnum::Keys->value => $this->getKeys()];

0 commit comments

Comments
 (0)