10000 feature #30052 [Security] Replace serialization API (renanbr) · symfony/symfony@e8c3f9e · GitHub
[go: up one dir, main page]

Skip to content

Commit e8c3f9e

Browse files
feature #30052 [Security] Replace serialization API (renanbr)
This PR was merged into the 4.3-dev branch. Discussion ---------- [Security] Replace serialization API | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | no | BC breaks? | no | Deprecations? | yes | Tests pass? | yes | Fixed tickets | n/a | License | MIT | Doc PR | n/a New `getState()` and `setState()` methods in `AbstractToken` and `AuthenticationException` allow users to append data to the serialization payload. It allow us to have zero impact in user land when changing the serialization engine. Commits ------- 006c6dd makes serialize methods final
2 parents 974cab3 + 006c6dd commit e8c3f9e

13 files changed

+222
-84
lines changed

UPGRADE-4.3.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,41 @@ HttpFoundation
4545
* The `FileinfoMimeTypeGuesser` class has been deprecated,
4646
use `Symfony\Component\Mime\FileinfoMimeTypeGuesser` instead.
4747

48+
Security
49+
--------
50+
51+
* The `AbstractToken::serialize()`, `AbstractToken::unserialize()`,
52+
`AuthenticationException::serialize()` and `AuthenticationException::unserialize()`
53+
methods are now final, use `getState()` and `setState()` instead.
54+
55+
Before:
56+
```php
57+
public function serialize()
58+
{
59+
return [$this->myLocalVar, parent::serialize()];
60+
}
61+
62+
public function unserialize($serialized)
63+
{
64+
[$this->myLocalVar, $parentSerialized] = unserialize($serialized);
65+
parent::unserialize($parentSerialized);
66+
}
67+
```
68+
69+
After:
70+
```php
71+
protected function getState(): array
72+
{
73+
return [$this->myLocalVar, parent::getState()];
74+
}
75+
76+
protected function setState(array $data)
77+
{
78+
[$this->myLocalVar, $parentData] = $data;
79+
parent::setState($parentData);
80+
}
81+
```
82+
4883
Yaml
4984
----
5085

UPGRADE-5.0.md

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,37 @@ Security
232232
* `SimpleAuthenticatorInterface`, `SimpleFormAuthenticatorInterface`, `SimplePreAuthenticatorInterface`,
233233
`SimpleAuthenticationProvider`, `SimpleAuthenticationHandler`, `SimpleFormAuthenticationListener` and
234234
`SimplePreAuthenticationListener` have been removed. Use Guard instead.
235+
* `\Serializable` interface has been removed from `AbstractToken` and `AuthenticationException`,
236+
thus `serialize()` and `unserialize()` aren't available.
237+
Use `getState()` and `setState()` instead.
238+
239+
Before:
240+
```php
241+
public function serialize()
242+
{
243+
return [$this->myLocalVar, parent::serialize()];
244+
}
245+
246+
public function unserialize($serialized)
247+
{
248+
[$this->myLocalVar, $parentSerialized] = unserialize($serialized);
249+
parent::unserialize($parentSerialized);
250+
}
251+
```
252+
253+
After:
254+
```php
255+
protected function getState(): array
256+
{
257+
return [$this->myLocalVar, parent::getState()];
258+
}
259+
260+
protected function setState(array $data)
261+
{
262+
[$this->myLocalVar, $parentData] = $data;
263+
parent::setState($parentData);
264+
}
265+
```
235266

236267
SecurityBundle
237268
--------------

src/Symfony/Component/Security/CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
CHANGELOG
22
=========
33

4+
4.3.0
5+
-----
6+
7+
* Made the `serialize()` and `unserialize()` methods of `AbstractToken` and
8+
`AuthenticationException` final, use `getState()`/`setState()` instead
9+
410
4.2.0
511
-----
612

src/Symfony/Component/Security/Core/Authentication/Token/AbstractToken.php

Lines changed: 51 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -133,20 +133,67 @@ public function eraseCredentials()
133133

134134
/**
135135
* {@inheritdoc}
136+
*
137+
* @final since Symfony 4.3, use getState() instead
138+
*
139+
* @internal since Symfony 4.3, use getState() instead
136140
*/
137141
public function serialize()
138142
{
139-
$serialized = [$this->user, $this->authenticated, $this->roles, $this->attributes];
140-
141-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
143+
return $this->doSerialize($this->getState(), \func_num_args() ? \func_get_arg(0) : null);
142144
}
143145

144146
/**
145147
* {@inheritdoc}
148+
*
149+
* @final since Symfony 4.3, use setState() instead
150+
*
151+
* @internal since Symfony 4.3, use setState() instead
146152
*/
147153
public function unserialize($serialized)
148154
{
149-
list($this->user, $this->authenticated, $this->roles, $this->attributes) = \is_array($serialized) ? $serialized : unserialize($serialized);
155+
$this->setState(\is_array($serialized) ? $serialized : unserialize($serialized));
156+
}
157+
158+
/**
159+
* Returns all the necessary state of the object for serialization purposes.
160+
*
161+
* There is no need to serialize any entry, they should be returned as-is.
162+
* If you extend this method, keep in mind you MUST guarantee parent data is present in the state.
163+
* Here is an example of how to extend this method:
164+
* <code>
165+
* protected function getState(): array
166+
* {
167+
* return [$this->childAttribute, parent::getState()];
168+
* }
169+
* </code>
170+
*
171+
* @see setState()
172+
*/
173+
protected function getState(): array
174+
{
175+
return [$this->user, $this->authenticated, $this->roles, $this->attributes];
176+
}
177+
178+
/**
179+
* Restores the object state from an array given by getState().
180+
*
181+
* There is no need to unserialize any entry in $data, they are already ready-to-use.
182+
* If you extend this method, keep in mind you MUST pass the parent data to its respective class.
183+
* Here is an example of how to extend this method:
184+
* <code>
185+
* protected function setState(array $data)
186+
* {
187+
* [$this->childAttribute, $parentData] = $data;
188+
* parent::setState($parentData);
189+
* }
190+
* </code>
191+
*
192+
* @see getState()
193+
*/
194+
protected function setState(array $data)
195+
{
196+
[$this->user, $this->authenticated, $this->roles, $this->attributes] = $data;
150197
}
151198

152199
/**

src/Symfony/Component/Security/Core/Authentication/Token/AnonymousToken.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -57,19 +57,17 @@ public function getSecret()
5757
/**
5858
* {@inheritdoc}
5959
*/
60-
public function serialize()
60+
protected function getState(): array
6161
{
62-
$serialized = [$this->secret, parent::serialize(true)];
63-
64-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
62+
return [$this->secret, parent::getState()];
6563
}
6664

6765
/**
6866
* {@inheritdoc}
6967
*/
70-
public function unserialize($serialized)
68+
protected function setState(array $data)
7169
{
72-
list($this->secret, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
73-
parent::unserialize($parentStr);
70+
[$this->secret, $parentData] = $data;
71+
parent::setState($parentData);
7472
}
7573
}

src/Symfony/Component/Security/Core/Authentication/Token/PreAuthenticatedToken.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -77,19 +77,17 @@ public function eraseCredentials()
7777
/**
7878
* {@inheritdoc}
7979
*/
80-
public function serialize()
80+
protected function getState(): array
8181
{
82-
$serialized = [$this->credentials, $this->providerKey, parent::serialize(true)];
83-
84-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
82+
return [$this->credentials, $this->providerKey, parent::getState()];
8583
}
8684

8785
/**
8886
* {@inheritdoc}
8987
*/
90-
public function unserialize($str)
88+
protected function setState(array $data)
9189
{
92-
list($this->credentials, $this->providerKey, $parentStr) = \is_array($str) ? $str : unserialize($str);
93-
parent::unserialize($parentStr);
90+
[$this->credentials, $this->providerKey, $parentData] = $data;
91+
parent::setState($parentData);
9492
}
9593
}

src/Symfony/Component/Security/Core/Authentication/Token/RememberMeToken.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -92,19 +92,17 @@ public function getCredentials()
9292
/**
9393
* {@inheritdoc}
9494
*/
95-
public function serialize()
95+
protected function getState(): array
9696
{
97-
$serialized = [$this->secret, $this->providerKey, parent::serialize(true)];
98-
99-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
97+
return [$this->secret, $this->providerKey, parent::getState()];
10098
}
10199

102100
/**
103101
* {@inheritdoc}
104102
*/
105-
public function unserialize($serialized)
103+
protected function setState(array $data)
106104
{
107-
list($this->secret, $this->providerKey, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
108-
parent::unserialize($parentStr);
105+
[$this->secret, $this->providerKey, $parentData] = $data;
106+
parent::setState($parentData);
109107
}
110108
}

src/Symfony/Component/Security/Core/Authentication/Token/UsernamePasswordToken.php

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,19 +89,17 @@ public function eraseCredentials()
8989
/**
9090
* {@inheritdoc}
9191
*/
92-
public function serialize()
92+
protected function getState(): array
9393
{
94-
$serialized = [$this->credentials, $this->providerKey, parent::serialize(true)];
95-
96-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
94+
return [$this->credentials, $this->providerKey, parent::getState()];
9795
}
9896

9997
/**
10098
* {@inheritdoc}
10199
*/
102-
public function unserialize($serialized)
100+
protected function setState(array $data)
103101
{
104-
list($this->credentials, $this->providerKey, $parentStr) = \is_array($serialized) ? $serialized : unserialize($serialized);
105-
parent::unserialize($parentStr);
102+
[$this->credentials, $this->providerKey, $parentData] = $data;
103+
parent::setState($parentData);
106104
}
107105
}

src/Symfony/Component/Security/Core/Exception/AccountStatusException.php

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,17 @@ public function setUser(UserInterface $user)
4242
/**
4343
* {@inheritdoc}
4444
*/
45-
public function serialize()
45+
protected function getState(): array
4646
{
47-
$serialized = [$this->user, parent::serialize(true)];
48-
49-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
47+
return [$this->user, parent::getState()];
5048
}
5149

5250
/**
5351
* {@inheritdoc}
5452
*/
55-
public function unserialize($str)
53+
protected function setState(array $data)
5654
{
57-
list($this->user, $parentData) = \is_array($str) ? $str : unserialize($str);
58-
59-
parent::unserialize($parentData);
55+
[$this->user, $parentData] = $data;
56+
parent::setState($parentData);
6057
}
6158
}

src/Symfony/Component/Security/Core/Exception/AuthenticationException.php

Lines changed: 57 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -40,18 +40,67 @@ public function setToken(TokenInterface $token)
4040

4141
/**
4242
* {@inheritdoc}
43+
*
44+
* @final since Symfony 4.3, use getState() instead
45+
*
46+
* @internal since Symfony 4.3, use getState() instead
4347
*/
4448
public function serialize()
4549
{
46-
$serialized = [
47-
$this->token,
48-
$this->code,
49-
$this->message,
50-
$this->file,
51-
$this->line,
52-
];
50+
return $this->doSerialize($this->getState(), \func_num_args() ? \func_get_arg(0) : null);
51+
}
52+
53+
/**
54+
* {@inheritdoc}
55+
*
56+
* @final since Symfony 4.3, use setState() instead
57+
*
58+
* @internal since Symfony 4.3, use setState() instead
59+
*/
60+
public function unserialize($serialized)
61+
{
62+
$this->setState(\is_array($serialized) ? $serialized : unserialize($serialized));
63+
}
64+
65+
/**
66+
* Returns all the necessary state of the object for serialization purposes.
67+
*
68+
* There is no need to serialize any entry, they should be returned as-is.
69+
* If you extend this method, keep in mind you MUST guarantee parent data is present in the state.
70+
* Here is an example of how to extend this method:
71+
* <code>
72+
* protected function getState(): array
73+
* {
74+
* return [$this->childAttribute, parent::getState()];
75+
* }
76+
* </code>
77+
*
78+
* @see setState()
79+
*/
80+
protected function getState(): array
81+
{
82+
return [$this->token, $this->code, $this->message, $this->file, $this->line];
83+
}
5384

54-
return $this->doSerialize($serialized, \func_num_args() ? \func_get_arg(0) : null);
85+
/**
86+
* Restores the object state from an array given by getState().
87+
*
88+
* There is no need to unserialize any entry in $data, they are already ready-to-use.
89+
* If you extend this method, keep in mind you MUST pass the parent data to its respective class.
90+
* Here is an example of how to extend this method:
91+
* <code>
92+
* protected function setState(array $data)
93+
* {
94+
* [$this->childAttribute, $parentData] = $data;
95+
* parent::setState($parentData);
96+
* }
97+
* </code>
98+
*
99+
* @see getState()
100+
*/
101+
protected function setState(array $data)
102+
{
103+
[$this->token, $this->code, $this->message, $this->file, $this->line] = $data;
55104
}
56105

57106
/**
@@ -67,17 +116,6 @@ protected function doSerialize($serialized, $isCalledFromOverridingMethod)
67116
return $isCalledFromOverridingMethod ? $serialized : serialize($serialized);
68117
}
69118

70-
public function unserialize($str)
71-
{
72-
list(
73-
$this->token,
74-
$this->code,
75-
$this->message,
76-
$this->file,
77-
$this->line
78-
) = \is_array($str) ? $str : unserialize($str);
79-
}
80-
81119
/**
82120
* Message key to be used by the translation component.
83121
*

0 commit comments

Comments
 (0)
0