<p dir="auto"><strong>Description</strong><br>
Symfony currently uses:</p>
<p dir="auto"><code class="notranslate">if ('\\' !== DIRECTORY_SEPARATOR) { // PHP does not run in Windows }</code></p>
<p dir="auto">in many places. This could be changed to something like:</p>
<p dir="auto"><code class="notranslate">if (OperatingSystem::WINDOWS !== $os-&gt;getType()) { // PHP does not run in Windows }</code></p>
<p dir="auto">Is it worth my time to try to build something small like <a href="https://packagist.org/packages/operating-system/operating-system" rel="nofollow">https://packagist.org/packages/operating-system/operating-system</a> into Symfony? But since this simple thing was not done yet I suppose there is a good reason for it?</p>
<p dir="auto">My pros:</p>
<ul dir="auto">
<li>Better readability</li>
<li>One single place to change the detection (very unlikely that this will be needed)</li>
</ul>
<p dir="auto">My cons:</p>
<ul dir="auto">
<li>Performance loss</li>
<li>More complexity</li>
</ul>
<p dir="auto"><strong>Example</strong><br>
see "Description"</p>
<p dir="auto"><a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="430118081" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/30955" data-hovercard-type="pull_request" data-hovercard-url="/symfony/symfony/pull/30955/hovercard" href="https://github.com/symfony/symfony/pull/30955">#30955</a> is proposing adding a new event to hook into the password verification process and allow listeners to deal with clear text passwords. Thinking a bit about this approach, I have a different one to propose here.</p>
<p dir="auto">The most important drawback of <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="430118081" data-permission-text="Title is private" data-url="https://github.com/symfony/symfony/issues/30955" data-hovercard-type="pull_request" data-hovercard-url="/symfony/symfony/pull/30955/hovercard" href="https://github.com/symfony/symfony/pull/30955">#30955</a> is that it's still up to the application to implement some custom code to run a "needs rehash" logic then a "persist new encoded password" one. The 2nd drawback is that this gives a trivial way to hook into the process to leak clear text passwords (inadvertently or not).</p>
<p dir="auto">The boilerplate of a listener shouldn't be needed: security should be first class by default, and this means progressive migration of passwords should be built in and the default behavior.</p>
<p dir="auto">Instead of adding this hook, I'd suggest adding two new interfaces (names/etc are draft):</p>
<div class="highlight highlight-text-html-php notranslate position-relative overflow-auto" dir="auto" data-snippet-clipboard-copy-content="interface UpgradablePasswordInterface
{
    public function upgradePassword(string $encoded): void;
}

interface RehashAwarePasswordEncoderInterface extends PasswordEncoderInterface
{
    public function needsRehash(string $encoded): bool;
}"><pre class="notranslate"><span class="pl-k">interface</span> <span class="pl-v">UpgradablePasswordInterface</span>
{
    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">upgradePassword</span>(<span class="pl-smi">string</span> <span class="pl-s1"><span class="pl-c1">$</span>encoded</span>): <span class="pl-smi">void</span>;
}

<span class="pl-k">interface</span> <span class="pl-v">RehashAwarePasswordEncoderInterface</span> <span class="pl-k">extends</span> <span class="pl-v">PasswordEncoderInterface</span>
{
    <span class="pl-k">public</span> <span class="pl-k">function</span> <span class="pl-en">needsRehash</span>(<span class="pl-smi">string</span> <span class="pl-s1"><span class="pl-c1">$</span>encoded</span>): <span class="pl-smi">bool</span>;
}</pre></div>
<p dir="auto">Then, a <code class="notranslate">UserPasswordEncoder</code> could call both methods when applicable inside its <code class="notranslate">isPasswordValid</code> method, and done.</p>
<p dir="auto">WDYT?</p>