sulu icon indicating copy to clipboard operation
sulu copied to clipboard

Psalm crashes on class_alias in SecurityBundle/TwoFactor

Open veewee opened this issue 1 year ago • 1 comments

Q A
Sulu Version 2.6.3
PHP Version 8.3
Psalm Version 5.25.0

Actual Behavior

psalm --no-cache                                                                                                                                                          [9:37:11]
Target PHP version: 8.3 (set by config file).
Scanning files...
Analyzing files...

E░░░░░░░░░░░░░░░░░░░░EE░░░░░░░░░E░░░░░░░░░░░░░░E░░░░░░░░E░░░  60 / 287 (20%)
░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░E░░░░░░░░░░░░░░░░░░░░░░░░░ 120 / 287 (41%)
░E░░░░░░░░░░░░░░░░░░░░░░░░░░E░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░ 180 / 287 (62%)
░░░░░░░░░E░░░░░░░░░░░░░░░░░░░░E░░░░░░░░░░░░░E░░░░░░░░░░░░░░░ 240 / 287 (83%)

Uncaught Exception: InvalidArgumentException Could not get class storage for sulu\bundle\securitybundle\entity\twofactor\preferredproviderinterface
Emitted in /app/vendor/vimeo/psalm/src/Psalm/Internal/Provider/ClassLikeStorageProvider.php:45
Stack trace in the forked worker:
#0 /app/vendor/vimeo/psalm/src/Psalm/Internal/Codebase/AssertionsFromInheritanceResolver.php(46): Psalm\Internal\Provider\ClassLikeStorageProvider->get('Sulu\\Bundle\\Sec...')
#1 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/ExistingAtomicMethodCallAnalyzer.php(421): Psalm\Internal\Codebase\AssertionsFromInheritanceResolver->resolve(Object(Psalm\Storage\MethodStorage), Object(Psalm\Storage\ClassLikeStorage))
#2 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/Method/AtomicMethodCallAnalyzer.php(483): Psalm\Internal\Analyzer\Statements\Expression\Call\Method\ExistingAtomicMethodCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\MethodCall), Object(PhpParser\Node\Identifier), Array, Object(Psalm\Codebase), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Object(Psalm\Type\Atomic\TNamedObject), '$author', Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult), NULL)
#3 /app/vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/MethodCallAnalyzer.php(195): Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\MethodCall), Object(Psalm\Codebase), Object(Psalm\Context), Object(Psalm\Type\Union), Object(Psalm\Type\Atomic\TNamedObject), Object(Psalm\Type\Atomic\TNamedObject), false, '$author', Object(Psalm\Internal\Analyzer\Statements\Expression\Call\Method\AtomicMethodCallAnalysisResult), NULL)

Expected Behavior

Psalm should not crash

Steps to Reproduce

Run psalm on 2.6 with 2FA enabled.

Possible Solutions

The problem is related to the class_alias structures in various files:

namespace Sulu\Bundle\SecurityBundle\Entity\TwoFactor;

use Scheb\TwoFactorBundle\Model\PreferredProviderInterface as SchebPreferredProviderInterface;

/*
 * Bridge interface to the scheb/2fa-bundle PreferredProviderInterface.
 */
if (\interface_exists(SchebPreferredProviderInterface::class)) {
    /*
     * @internal
     */
    \class_alias(SchebPreferredProviderInterface::class, PreferredProviderInterface::class);
} else {
    /**
     * @internal
     */
    interface PreferredProviderInterface
    {
    }
}
  • https://github.com/sulu/sulu/blob/2.6/src/Sulu/Bundle/SecurityBundle/Entity/TwoFactor/PreferredProviderInterface.php
  • https://github.com/sulu/sulu/blob/2.6/src/Sulu/Bundle/SecurityBundle/Entity/TwoFactor/EmailInterface.php
  • https://github.com/sulu/sulu/blob/2.6/src/Sulu/Bundle/SecurityBundle/Entity/TwoFactor/TrustedDeviceInterface.php

This can be overcome by creating extended interfaces instead of class_aliases:

namespace Sulu\Bundle\SecurityBundle\Entity\TwoFactor;

use Scheb\TwoFactorBundle\Model\PreferredProviderInterface as SchebPreferredProviderInterface;
use Scheb\TwoFactorBundle\Model\Email\TwoFactorInterface as SchebTwoFactorInterface;
use Scheb\TwoFactorBundle\Model\TrustedDeviceInterface as SchebTrustedDeviceInterface;

interface PreferredProviderInterface extends SchebPreferredProviderInterface
{
}

interface EmailInterface extends SchebTwoFactorInterface
{
}

interface TrustedDeviceInterface extends SchebTrustedDeviceInterface
{
}

We currently fixed this by providing stubs, but it could be changed inside those linked files as well if you are interested in that. I'll be opening up an issue in psalm as well and link it afterwards.

veewee avatar Jul 11 '24 07:07 veewee

Linking to https://github.com/vimeo/psalm/issues/10895

veewee avatar Jul 11 '24 08:07 veewee