Skip to content

Security TokenInterface depends on Stringable interface but does not require polyfill-php80 as dependency #36403

@clement-michelet

Description

@clement-michelet

Symfony version(s) affected: 4.4.7

Description

In a project using Symfony components (not framework).
After upgrading symfony/security-core from 4.4.4 to 4.4.7, PHPStan started complaining about invalid types for a class extending Symfony\Component\Security\Core\Authentication\Token\TokenInterface

  83   Return typehint of method My\Namespace\BridgeToken::getUser() has invalid type Stringable.
  88   Parameter $user of method My\Namespace\BridgeToken::setUser() has invalid typehint type Stringable.

How to reproduce

Create a class extending TokenInterface :

<?php

use InvalidArgumentException;
use LogicException;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Role\Role;

final class BridgeToken implements TokenInterface
{
    public function getRoles()
    {
        return [new Role('foo')];
    }

    public function getUsername()
    {
        return '';
    }

    public function isAuthenticated()
    {
        return true;
    }

    public function setAuthenticated($isAuthenticated)
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function getCredentials()
    {
        return '';
    }

    public function eraseCredentials()
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function getAttributes()
    {
        return [];
    }

    public function setAttribute($name, $value)
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function setAttributes(array $attributes)
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function hasAttribute($name)
    {
        return false;
    }

    public function getAttribute($name)
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function getUser()
    {
        return $this->getUsername();
    }

    public function setUser($user)
    {
        throw $this->notImplementException(__METHOD__);
    }

    public function serialize()
    {
        return serialize([]);
    }

    public function unserialize($serialized)
    {
       throw $this->notImplementException(__METHOD__);
    }

    public function __toString()
    {
        return '';
    }
    private function notImplementException(string $method): LogicException
    {
        return new LogicException(sprintf('The method "%s" is not implemented.', $method));
    }
}

Run PHPStan analyse with 0.11 (not tested with higher)

parameters:
  level: 6
  polluteScopeWithLoopInitialAssignments: false
  checkAlwaysTrueCheckTypeFunctionCall: true
  checkAlwaysTrueInstanceof: true
  checkAlwaysTrueStrictComparison: true
  checkFunctionNameCase: true

Possible Solution

Add explicit dependency to symfony/polyfill-php80

Additional context

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions