Skip to content

Commit 57327bd

Browse files
authored
Split encoder and normalizer to fix Symfony 6.1 compatibility (#347)
* Split encoder and normalizer to fix Symfony 6.1 compatibility * Fix serializer tests * Fix code style * Rector fixes * More style fixes
1 parent 68fda8c commit 57327bd

File tree

9 files changed

+743
-452
lines changed

9 files changed

+743
-452
lines changed

src/Bundle/JoseFramework/DependencyInjection/Compiler/SymfonySerializerCompilerPass.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@
44

55
namespace Jose\Bundle\JoseFramework\DependencyInjection\Compiler;
66

7+
use Jose\Bundle\JoseFramework\Serializer\JWEEncoder;
78
use Jose\Bundle\JoseFramework\Serializer\JWESerializer;
9+
use Jose\Bundle\JoseFramework\Serializer\JWSEncoder;
810
use Jose\Bundle\JoseFramework\Serializer\JWSSerializer;
911
use Jose\Component\Encryption\Serializer\JWESerializerManagerFactory;
1012
use Jose\Component\Signature\Serializer\JWSSerializerManagerFactory;
@@ -15,22 +17,34 @@ class SymfonySerializerCompilerPass implements CompilerPassInterface
1517
{
1618
public function process(ContainerBuilder $container): void
1719
{
18-
if (! class_exists('Symfony\Component\Serializer\Serializer')) {
20+
if (! class_exists('Symfony\\Component\\Serializer\\Serializer')) {
1921
return;
2022
}
2123
if ($container->hasDefinition(JWSSerializerManagerFactory::class)) {
22-
$container->autowire(JWSSerializer::class, JWSSerializer::class)
24+
$container
25+
->autowire(JWSSerializer::class, JWSSerializer::class)
2326
->setPublic(false)
24-
->addTag('serializer.encoder')
2527
->addTag('serializer.normalizer')
2628
;
29+
30+
$container
31+
->autowire(JWSEncoder::class, JWSEncoder::class)
32+
->setPublic(false)
33+
->addTag('serializer.encoder')
34+
;
2735
}
2836
if ($container->hasDefinition(JWESerializerManagerFactory::class)) {
29-
$container->autowire(JWESerializer::class, JWESerializer::class)
37+
$container
38+
->autowire(JWESerializer::class, JWESerializer::class)
3039
->setPublic(false)
31-
->addTag('serializer.encoder')
3240
->addTag('serializer.normalizer')
3341
;
42+
43+
$container
44+
->autowire(JWEEncoder::class, JWEEncoder::class)
45+
->setPublic(false)
46+
->addTag('serializer.encoder')
47+
;
3448
}
3549
}
3650
}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jose\Bundle\JoseFramework\Serializer;
6+
7+
use Exception;
8+
use function in_array;
9+
use function is_int;
10+
use Jose\Component\Encryption\JWE;
11+
use Jose\Component\Encryption\Serializer\JWESerializerManager;
12+
use Jose\Component\Encryption\Serializer\JWESerializerManagerFactory;
13+
use LogicException;
14+
use function mb_strtolower;
15+
use Symfony\Component\Serializer\Encoder\DecoderInterface;
16+
use Symfony\Component\Serializer\Encoder\EncoderInterface;
17+
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
18+
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
19+
use Throwable;
20+
21+
final class JWEEncoder implements EncoderInterface, DecoderInterface, NormalizationAwareInterface
22+
{
23+
private JWESerializerManager $serializerManager;
24+
25+
public function __construct(
26+
JWESerializerManagerFactory $serializerManagerFactory,
27+
?JWESerializerManager $serializerManager = null
28+
) {
29+
if ($serializerManager === null) {
30+
$serializerManager = $serializerManagerFactory->create($serializerManagerFactory->names());
31+
}
32+
$this->serializerManager = $serializerManager;
33+
}
34+
35+
public function supportsEncoding(string $format): bool
36+
{
37+
return class_exists(JWESerializerManager::class) && $this->formatSupported($format);
38+
}
39+
40+
public function supportsDecoding(string $format): bool
41+
{
42+
return class_exists(JWESerializerManager::class) && $this->formatSupported($format);
43+
}
44+
45+
public function encode(mixed $data, string $format, array $context = []): string
46+
{
47+
if ($data instanceof JWE === false) {
48+
throw new LogicException('Expected data to be a JWE.');
49+
}
50+
51+
try {
52+
return $this->serializerManager->serialize(
53+
mb_strtolower($format),
54+
$data,
55+
$this->getRecipientIndex($context)
56+
);
57+
} catch (Throwable $ex) {
58+
throw new NotEncodableValueException(sprintf('Cannot encode JWE to %s format.', $format), 0, $ex);
59+
}
60+
}
61+
62+
public function decode(string $data, string $format, array $context = []): JWE
63+
{
64+
try {
65+
return $this->serializerManager->unserialize($data);
66+
} catch (Exception $ex) {
67+
throw new NotEncodableValueException(sprintf('Cannot decode JWE from %s format.', $format), 0, $ex);
68+
}
69+
}
70+
71+
/**
72+
* Get JWE recipient index from context.
73+
*/
74+
private function getRecipientIndex(array $context): int
75+
{
76+
if (isset($context['recipient_index']) && is_int($context['recipient_index'])) {
77+
return $context['recipient_index'];
78+
}
79+
80+
return 0;
81+
}
82+
83+
/**
84+
* Check if format is supported.
85+
*/
86+
private function formatSupported(?string $format): bool
87+
{
88+
return $format !== null
89+
&& in_array(mb_strtolower($format), $this->serializerManager->names(), true);
90+
}
91+
}

src/Bundle/JoseFramework/Serializer/JWESerializer.php

Lines changed: 2 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -4,22 +4,15 @@
44

55
namespace Jose\Bundle\JoseFramework\Serializer;
66

7-
use Exception;
87
use function in_array;
9-
use function is_int;
108
use Jose\Component\Encryption\JWE;
119
use Jose\Component\Encryption\Serializer\JWESerializerManager;
1210
use Jose\Component\Encryption\Serializer\JWESerializerManagerFactory;
1311
use LogicException;
1412
use function mb_strtolower;
15-
use Symfony\Component\Serializer\Encoder\DecoderInterface;
16-
use Symfony\Component\Serializer\Encoder\EncoderInterface;
17-
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
18-
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
1913
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
20-
use Throwable;
2114

22-
final class JWESerializer implements DenormalizerInterface, EncoderInterface, DecoderInterface, NormalizationAwareInterface
15+
final class JWESerializer implements DenormalizerInterface
2316
{
2417
private JWESerializerManager $serializerManager;
2518

@@ -33,49 +26,13 @@ public function __construct(
3326
$this->serializerManager = $serializerManager;
3427
}
3528

36-
public function supportsEncoding(string $format): bool
37-
{
38-
return $this->formatSupported($format);
39-
}
40-
41-
public function supportsDecoding(string $format): bool
42-
{
43-
return $this->formatSupported($format);
44-
}
45-
4629
public function supportsDenormalization(mixed $data, string $type, string $format = null): bool
4730
{
4831
return $type === JWE::class
49-
&& $this->componentInstalled()
32+
&& class_exists(JWESerializerManager::class)
5033
&& $this->formatSupported($format);
5134
}
5235

53-
public function encode(mixed $data, string $format, array $context = []): string
54-
{
55-
if ($data instanceof JWE === false) {
56-
throw new LogicException('Expected data to be a JWE.');
57-
}
58-
59-
try {
60-
return $this->serializerManager->serialize(
61-
mb_strtolower($format),
62-
$data,
63-
$this->getRecipientIndex($context)
64-
);
65-
} catch (Throwable $ex) {
66-
throw new NotEncodableValueException(sprintf('Cannot encode JWE to %s format.', $format), 0, $ex);
67-
}
68-
}
69-
70-
public function decode(string $data, string $format, array $context = []): JWE
71-
{
72-
try {
73-
return $this->serializerManager->unserialize($data);
74-
} catch (Exception $ex) {
75-
throw new NotEncodableValueException(sprintf('Cannot decode JWE from %s format.', $format), 0, $ex);
76-
}
77-
}
78-
7936
public function denormalize(mixed $data, string $type, string $format = null, array $context = []): JWE
8037
{
8138
if ($data instanceof JWE === false) {
@@ -85,26 +42,6 @@ public function denormalize(mixed $data, string $type, string $format = null, ar
8542
return $data;
8643
}
8744

88-
/**
89-
* Get JWE recipient index from context.
90-
*/
91-
private function getRecipientIndex(array $context): int
92-
{
93-
if (isset($context['recipient_index']) && is_int($context['recipient_index'])) {
94-
return $context['recipient_index'];
95-
}
96-
97-
return 0;
98-
}
99-
100-
/**
101-
* Check if encryption component is installed.
102-
*/
103-
private function componentInstalled(): bool
104-
{
105-
return class_exists(JWESerializerManager::class);
106-
}
107-
10845
/**
10946
* Check if format is supported.
11047
*/
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Jose\Bundle\JoseFramework\Serializer;
6+
7+
use Exception;
8+
use function in_array;
9+
use function is_int;
10+
use Jose\Component\Signature\JWS;
11+
use Jose\Component\Signature\Serializer\JWSSerializerManager;
12+
use Jose\Component\Signature\Serializer\JWSSerializerManagerFactory;
13+
use LogicException;
14+
use function mb_strtolower;
15+
use Symfony\Component\Serializer\Encoder\DecoderInterface;
16+
use Symfony\Component\Serializer\Encoder\EncoderInterface;
17+
use Symfony\Component\Serializer\Encoder\NormalizationAwareInterface;
18+
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
19+
20+
final class JWSEncoder implements EncoderInterface, DecoderInterface, NormalizationAwareInterface
21+
{
22+
private JWSSerializerManager $serializerManager;
23+
24+
public function __construct(
25+
JWSSerializerManagerFactory $serializerManagerFactory,
26+
?JWSSerializerManager $serializerManager = null
27+
) {
28+
if ($serializerManager === null) {
29+
$serializerManager = $serializerManagerFactory->create($serializerManagerFactory->names());
30+
}
31+
$this->serializerManager = $serializerManager;
32+
}
33+
34+
public function supportsEncoding(string $format): bool
35+
{
36+
return class_exists(JWSSerializerManager::class) && $this->formatSupported($format);
37+
}
38+
39+
public function supportsDecoding(string $format): bool
40+
{
41+
return class_exists(JWSSerializerManager::class) && $this->formatSupported($format);
42+
}
43+
44+
public function encode($data, $format, array $context = []): string
45+
{
46+
if ($data instanceof JWS === false) {
47+
throw new LogicException('Expected data to be a JWS.');
48+
}
49+
50+
try {
51+
return $this->serializerManager->serialize(
52+
mb_strtolower($format),
53+
$data,
54+
$this->getSignatureIndex($context)
55+
);
56+
} catch (Exception $ex) {
57+
throw new NotEncodableValueException(sprintf('Cannot encode JWS to %s format.', $format), 0, $ex);
58+
}
59+
}
60+
61+
public function decode($data, $format, array $context = []): JWS
62+
{
63+
try {
64+
return $this->serializerManager->unserialize($data);
65+
} catch (Exception $ex) {
66+
throw new NotEncodableValueException(sprintf('Cannot decode JWS from %s format.', $format), 0, $ex);
67+
}
68+
}
69+
70+
/**
71+
* Get JWS signature index from context.
72+
*/
73+
private function getSignatureIndex(array $context): int
74+
{
75+
if (isset($context['signature_index']) && is_int($context['signature_index'])) {
76+
return $context['signature_index'];
77+
}
78+
79+
return 0;
80+
}
81+
82+
/**
83+
* Check if format is supported.
84+
*/
85+
private function formatSupported(?string $format): bool
86+
{
87+
return $format !== null
88+
&& in_array(mb_strtolower($format), $this->serializerManager->list(), true);
89+
}
90+
}

0 commit comments

Comments
 (0)