8000 [Security] Ban \DateTime from Security component by WebMamba · Pull Request #47772 · symfony/symfony · GitHub
[go: up one dir, main page]

Skip to content

[Security] Ban \DateTime from Security component #47772

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed

[Security] Ban \DateTime from Security component #47772

wants to merge 1 commit into from

Conversation

WebMamba
Copy link
Contributor
@WebMamba WebMamba commented Oct 3, 2022
Q A
Branch? 6.2 for features
Bug fix? no
New feature? yes
Deprecations? yes
Tickets #47580
License MIT

This PR is next to: #47730

The purpose here is to remove the use of \DateTime in the security component. I don't think we can remove it completely without leading any BC break. So I propose to use DateTimeInterface with a deprecation notice.
Feel free to discuss!

@@ -39,7 +39,7 @@ public function deleteTokenBySeries(string $series);
*
* @throws TokenNotFoundException if the token is not found
*/
public function updateToken(string $series, #[\SensitiveParameter] string $tokenValue, \DateTime $lastUsed);
public function updateToken(string $series, #[\SensitiveParameter] string $tokenValue, \DateTimeInterface $lastUsed);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC break for implementors of the interface

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we remove the param from 6.2 and replace it with an @paramannotation? I think you said we cannot but I forgot the reasoning once again 😬

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It doesn't have a default value, which means removing the param is not allowed as that would mean the implementors are flagged as incompatible with the interface?

@@ -37,7 +37,7 @@ public function getTokenValue(): string;
/**
* Returns the time the token was last used.
*/
public function getLastUsed(): \DateTime;
public function getLastUsed(): \DateTimeInterface;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC breaks for consumers of the interface

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I try to do here is to use the covariance feature of PHP. I don't get why is it a BC breaks ? If someone consumes this interface with DateTime he still can because DateTime is a child of DateTimeInterface.

Copy link
Member
@wouterj wouterj Oct 3, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a BC break for the caller, as they could rely on the method returning DateTime before. E.g. this code works before this change, but breaks after:

$lastUsed = $token->getLastUsed();
$lastUsed->modify('+30 minutes');

if ($lastUsed < new \DateTimeImmutable('now')) {
    throw new \RuntimeException('This token was last used 30 minutes ago');
}

(or simpler use-cases e.g. where this is passed in a function requiring DateTime).

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The consumer of a return type is not choosing whether it uses DateTime or a DateTimeInterface. It has to handle everything.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok thanks both of you. I understand your point. But I don't see any way to it without leading to a BC break. Maybe we should target the next major version?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also next major versions cannot have BC breaks that didn't have a deprecation (and way to get out of deprecation) in the last minor before it.

We would have to create a new method with the new return type and deprecate the old method. But I'm personally not sure if that is worth is: What about delaying to remove mutable DateTime in user-facing code?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas I ping you here. I think you should be part of this discussion

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've no perfect solution to this. We would document a way to detect all such uses of DateTime and rewrite them automatically:

Before:

$lastUsed = $token->getLastUsed();
$lastUsed->modify('+30 minutes');

After:

$lastUsed = $token->getLastUsed();
$lastUsed = $lastUsed->modify('+30 minutes');

That'd make the code the same whether DateTime or DateTimeImmutable is used.
Can Rector do that? /cc @TomasVotruba
Should the PHP engine trigger a deprecation when the return value of one of DateTime's setters is not used? I'm not sure how this would be possible technically, but let's just dream a bit :) /cc @derickr

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nicolas-grekas If the type is known, Rector can handle it :)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

And regarding the widened type, we might need something like ReturnTypeWillChange to indicate that this interface will change its return type in the future. But there is no userland solution for that.

@carsonbot carsonbot changed the title Ban \DateTime from Security component [Security] Ban \DateTime from Security component Oct 3, 2022
@fabpot fabpot modified the milestones: 6.2, 6.3 Nov 1, 2022
@nicolas-grekas nicolas-grekas modified the milestones: 6.3, 6.4 May 23, 2023
@nicolas-grekas
Copy link
Member

I'm closing because I think we went as far as possible on the topic already. Thanks for the interest in pushing this forward 🙏

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants
0