Merge branch '5.2' into 5.x
* 5.2: Dont allow unserializing classes with a destructor Dont allow unserializing classes with a destructor - 4.4 [Cache] fix possible collision when writing tmp file in filesystem adapter a colon followed by spaces exclusively separates mapping keys and values Contracts: Remove ellipsis fix handling float-like key attribute values Fix transient test with HttpClient jitter Fix missing BCC recipients in SES bridge Move AuthenticationSuccessEvent outside try/catch block Dont allow unserializing classes with a destructor - 5.2 Dont allow unserializing classes with a destructor - 5.1
This commit is contained in:
commit
a176f8767c
@ -129,6 +129,16 @@ class ElasticsearchLogstashHandler extends AbstractHandler
|
||||
$this->wait(false);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->wait(true);
|
||||
|
@ -89,6 +89,12 @@ class AppKernel extends Kernel implements ExtensionInterface, ConfigurationInter
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
foreach ($this as $k => $v) {
|
||||
if (\is_object($v)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
}
|
||||
|
||||
$this->__construct($this->varDir, $this->testCase, $this->rootConfig, $this->environment, $this->debug);
|
||||
}
|
||||
|
||||
|
@ -93,9 +93,20 @@ trait FilesystemCommonTrait
|
||||
set_error_handler(__CLASS__.'::throwError');
|
||||
try {
|
||||
if (null === $this->tmp) {
|
||||
$this->tmp = $this->directory.uniqid('', true);
|
||||
$this->tmp = $this->directory.bin2hex(random_bytes(6));
|
||||
}
|
||||
file_put_contents($this->tmp, $data);
|
||||
try {
|
||||
$h = fopen($this->tmp, 'x');
|
||||
} catch (\ErrorException $e) {
|
||||
if (false === strpos($e->getMessage(), 'File exists')) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->tmp = $this->directory.bin2hex(random_bytes(6));
|
||||
$h = fopen($this->tmp, 'x');
|
||||
}
|
||||
fwrite($h, $data);
|
||||
fclose($h);
|
||||
|
||||
if (null !== $expiresAt) {
|
||||
touch($this->tmp, $expiresAt);
|
||||
|
@ -227,6 +227,10 @@ class PrototypedArrayNode extends ArrayNode
|
||||
} elseif (isset($v[$this->keyAttribute])) {
|
||||
$k = $v[$this->keyAttribute];
|
||||
|
||||
if (\is_float($k)) {
|
||||
$k = var_export($k, true);
|
||||
}
|
||||
|
||||
// remove the key attribute when required
|
||||
if ($this->removeKeyAttribute) {
|
||||
unset($v[$this->keyAttribute]);
|
||||
|
@ -201,6 +201,32 @@ class NormalizationTest extends TestCase
|
||||
$this->assertNormalized($tree, $data, $data);
|
||||
}
|
||||
|
||||
public function testFloatLikeValueAsMapKeyAttribute()
|
||||
{
|
||||
$tree = (new TreeBuilder('root'))
|
||||
->getRootNode()
|
||||
->useAttributeAsKey('number')
|
||||
->arrayPrototype()
|
||||
->children()
|
||||
->scalarNode('foo')->end()
|
||||
->end()
|
||||
->end()
|
||||
->end()
|
||||
->buildTree()
|
||||
;
|
||||
|
||||
$this->assertNormalized($tree, [
|
||||
[
|
||||
'number' => 3.0,
|
||||
'foo' => 'bar',
|
||||
],
|
||||
], [
|
||||
'3.0' => [
|
||||
'foo' => 'bar',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public static function assertNormalized(NodeInterface $tree, $denormalized, $normalized)
|
||||
{
|
||||
self::assertSame($normalized, $tree->normalize($denormalized));
|
||||
|
@ -40,6 +40,16 @@ abstract class AbstractConfigurator
|
||||
throw new \BadMethodCallException(sprintf('Call to undefined method "%s::%s()".', static::class, $method));
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value.
|
||||
*
|
||||
|
@ -35,6 +35,16 @@ class BufferingLogger extends AbstractLogger
|
||||
return $logs;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
foreach ($this->logs as [$level, $message, $context]) {
|
||||
|
@ -76,6 +76,16 @@ class OrderedHashMapIterator implements \Iterator
|
||||
$this->managedCursors[$this->cursorId] = &$this->cursor;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes the iterator's cursors from the managed cursors of the
|
||||
* corresponding {@link OrderedHashMap} instance.
|
||||
|
@ -120,6 +120,16 @@ class ErrorChunk implements ChunkInterface
|
||||
return $this->didThrow;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (!$this->didThrow) {
|
||||
|
@ -367,6 +367,16 @@ final class CurlHttpClient implements HttpClientInterface, LoggerAwareInterface,
|
||||
}
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->reset();
|
||||
|
@ -218,6 +218,16 @@ final class HttplugClient implements HttplugInterface, HttpAsyncClient, RequestF
|
||||
throw new \LogicException(sprintf('You cannot use "%s()" as the "nyholm/psr7" package is not installed. Try running "composer require nyholm/psr7".', __METHOD__));
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->wait();
|
||||
|
@ -142,6 +142,16 @@ final class AmpResponse implements ResponseInterface, StreamableInterface
|
||||
return null !== $type ? $this->info[$type] ?? null : $this->info;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
try {
|
||||
|
@ -127,6 +127,16 @@ trait CommonResponseTrait
|
||||
return $stream;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Closes the response and all its network handles.
|
||||
*/
|
||||
|
@ -44,6 +44,16 @@ class TraceableResponse implements ResponseInterface, StreamableInterface
|
||||
$this->event = $event;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
try {
|
||||
|
@ -93,19 +93,16 @@ class GenericRetryStrategyTest extends TestCase
|
||||
public function testJitter()
|
||||
{
|
||||
$strategy = new GenericRetryStrategy([], 1000, 1, 0, 1);
|
||||
$belowHalf = 0;
|
||||
$aboveHalf = 0;
|
||||
for ($i = 0; $i < 20; ++$i) {
|
||||
$min = 2000;
|
||||
$max = 0;
|
||||
for ($i = 0; $i < 50; ++$i) {
|
||||
$delay = $strategy->getDelay($this->getContext(0, 'GET', 'http://example.com/', 200), null, null);
|
||||
if ($delay < 500) {
|
||||
++$belowHalf;
|
||||
} elseif ($delay > 1500) {
|
||||
++$aboveHalf;
|
||||
}
|
||||
$min = min($min, $delay);
|
||||
$max = max($max, $delay);
|
||||
}
|
||||
|
||||
$this->assertGreaterThanOrEqual(1, $belowHalf);
|
||||
$this->assertGreaterThanOrEqual(1, $aboveHalf);
|
||||
$this->assertGreaterThanOrEqual(1000, $max - $min);
|
||||
$this->assertGreaterThanOrEqual(1000, $max);
|
||||
$this->assertLessThanOrEqual(1000, $min);
|
||||
}
|
||||
|
||||
private function getContext($retryCount, $method, $url, $statusCode): AsyncContext
|
||||
|
@ -179,7 +179,7 @@ class DumpDataCollector extends DataCollector implements DataDumperInterface
|
||||
$fileLinkFormat = array_pop($this->data);
|
||||
$this->dataCount = \count($this->data);
|
||||
|
||||
self::__construct($this->stopwatch, $fileLinkFormat, $charset);
|
||||
self::__construct($this->stopwatch, \is_string($fileLinkFormat) || $fileLinkFormat instanceof FileLinkFormatter ? $fileLinkFormat : null, \is_string($charset) ? $charset : null);
|
||||
}
|
||||
|
||||
public function getDumpsCount(): int
|
||||
|
@ -865,6 +865,10 @@ abstract class Kernel implements KernelInterface, RebootableInterface, Terminabl
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
if (\is_object($this->environment) || \is_object($this->debug)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
$this->__construct($this->environment, $this->debug);
|
||||
}
|
||||
}
|
||||
|
@ -35,6 +35,16 @@ class Connection extends AbstractConnection
|
||||
/** @var resource */
|
||||
private $connection;
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->disconnect();
|
||||
|
@ -38,6 +38,16 @@ class Query extends AbstractQuery
|
||||
parent::__construct($connection, $dn, $query, $options);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$con = $this->connection->getResource();
|
||||
|
@ -49,6 +49,16 @@ final class Lock implements SharedLockInterface, LoggerAwareInterface
|
||||
$this->logger = new NullLogger();
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
/**
|
||||
* Automatically releases the underlying lock when the object is destructed.
|
||||
*/
|
||||
|
@ -63,6 +63,12 @@ class SesHttpTransportTest extends TestCase
|
||||
$this->assertStringContainsString('AWS3-HTTPS AWSAccessKeyId=ACCESS_KEY,Algorithm=HmacSHA256,Signature=', $options['headers'][0] ?? $options['request_headers'][0]);
|
||||
|
||||
parse_str($options['body'], $body);
|
||||
|
||||
$this->assertArrayHasKey('Destinations_member_1', $body);
|
||||
$this->assertSame('saif.gmati@symfony.com', $body['Destinations_member_1']);
|
||||
$this->assertArrayHasKey('Destinations_member_2', $body);
|
||||
$this->assertSame('jeremy@derusse.com', $body['Destinations_member_2']);
|
||||
|
||||
$content = base64_decode($body['RawMessage_Data']);
|
||||
|
||||
$this->assertStringContainsString('Hello!', $content);
|
||||
@ -88,6 +94,7 @@ class SesHttpTransportTest extends TestCase
|
||||
$mail = new Email();
|
||||
$mail->subject('Hello!')
|
||||
->to(new Address('saif.gmati@symfony.com', 'Saif Eddin'))
|
||||
->bcc(new Address('jeremy@derusse.com', 'Jérémy Derussé'))
|
||||
->from(new Address('fabpot@symfony.com', 'Fabien'))
|
||||
->text('Hello There!');
|
||||
|
||||
|
@ -66,8 +66,14 @@ class SesHttpTransport extends AbstractHttpTransport
|
||||
],
|
||||
];
|
||||
|
||||
if (($message->getOriginalMessage() instanceof Message)
|
||||
&& $configurationSetHeader = $message->getOriginalMessage()->getHeaders()->get('X-SES-CONFIGURATION-SET')) {
|
||||
$index = 1;
|
||||
foreach ($message->getEnvelope()->getRecipients() as $recipient) {
|
||||
$request['body']['Destinations.member.'.$index++] = $recipient->getAddress();
|
||||
}
|
||||
|
||||
if ($message->getOriginalMessage() instanceof Message
|
||||
&& $configurationSetHeader = $message->getOriginalMessage()->getHeaders()->get('X-SES-CONFIGURATION-SET')
|
||||
) {
|
||||
$request['body']['ConfigurationSetName'] = $configurationSetHeader->getBodyAsString();
|
||||
}
|
||||
|
||||
|
@ -340,6 +340,16 @@ class SmtpTransport extends AbstractTransport
|
||||
$this->restartCounter = 0;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->stop();
|
||||
|
@ -66,6 +66,16 @@ class Connection
|
||||
$this->queueUrl = $queueUrl;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->reset();
|
||||
|
@ -155,7 +155,13 @@ class DataPart extends TextPart
|
||||
$r->setValue($this, $this->_headers);
|
||||
unset($this->_headers);
|
||||
|
||||
if (!\is_array($this->_parent)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
foreach (['body', 'charset', 'subtype', 'disposition', 'name', 'encoding'] as $name) {
|
||||
if (null !== $this->_parent[$name] && !\is_string($this->_parent[$name])) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
$r = new \ReflectionProperty(TextPart::class, $name);
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($this, $this->_parent[$name]);
|
||||
|
@ -35,6 +35,16 @@ class UnixPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
|
@ -88,6 +88,16 @@ class WindowsPipes extends AbstractPipes
|
||||
parent::__construct($input);
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->close();
|
||||
|
@ -195,6 +195,16 @@ class Process implements \IteratorAggregate
|
||||
return $process;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if ($this->options['create_new_console'] ?? false) {
|
||||
|
@ -104,6 +104,10 @@ final class TokenBucket implements LimiterStateInterface
|
||||
*/
|
||||
public function __wakeup(): void
|
||||
{
|
||||
if (!\is_string($this->stringRate)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
$this->rate = Rate::fromString($this->stringRate);
|
||||
unset($this->stringRate);
|
||||
}
|
||||
|
@ -38,6 +38,16 @@ class CollectionConfigurator
|
||||
$this->parentPrefixes = $parentPrefixes;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
if (null === $this->prefixes) {
|
||||
|
@ -30,6 +30,16 @@ class ImportConfigurator
|
||||
$this->route = $route;
|
||||
}
|
||||
|
||||
public function __sleep()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot serialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
$this->parent->addCollection($this->route);
|
||||
|
@ -185,18 +185,6 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->info('Authenticator successful!', ['token' => $authenticatedToken, 'authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
// success! (sets the token on the token storage, etc)
|
||||
$response = $this->handleAuthenticationSuccess($authenticatedToken, $passport, $request, $authenticator);
|
||||
if ($response instanceof Response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Authenticator set no success response: request continues.', ['authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
return null;
|
||||
} catch (AuthenticationException $e) {
|
||||
// oh no! Authentication failed!
|
||||
$response = $this->handleAuthenticationFailure($e, $request, $authenticator, $passport);
|
||||
@ -206,6 +194,18 @@ class AuthenticatorManager implements AuthenticatorManagerInterface, UserAuthent
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// success! (sets the token on the token storage, etc)
|
||||
$response = $this->handleAuthenticationSuccess($authenticatedToken, $passport, $request, $authenticator);
|
||||
if ($response instanceof Response) {
|
||||
return $response;
|
||||
}
|
||||
|
||||
if (null !== $this->logger) {
|
||||
$this->logger->debug('Authenticator set no success response: request continues.', ['authenticator' => \get_class($authenticator)]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private function handleAuthenticationSuccess(TokenInterface $authenticatedToken, PassportInterface $passport, Request $request, AuthenticatorInterface $authenticator): ?Response
|
||||
|
@ -12,11 +12,12 @@
|
||||
namespace Symfony\Component\Security\Http\EventListener;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PreAuthenticatedUserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\UserPassportInterface;
|
||||
use Symfony\Component\Security\Http\Event\CheckPassportEvent;
|
||||
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
|
||||
|
||||
/**
|
||||
* @author Wouter de Jong <wouter@wouterj.nl>
|
||||
@ -43,21 +44,21 @@ class UserCheckerListener implements EventSubscriberInterface
|
||||
$this->userChecker->checkPreAuth($passport->getUser());
|
||||
}
|
||||
|
||||
public function postCheckCredentials(LoginSuccessEvent $event): void
|
||||
public function postCheckCredentials(AuthenticationSuccessEvent $event): void
|
||||
{
|
||||
$passport = $event->getPassport();
|
||||
if (!$passport instanceof UserPassportInterface || null === $passport->getUser()) {
|
||||
$user = $event->getAuthenticationToken()->getUser();
|
||||
if (!$user instanceof UserInterface) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->userChecker->checkPostAuth($passport->getUser());
|
||||
$this->userChecker->checkPostAuth($user);
|
||||
}
|
||||
|
||||
public static function getSubscribedEvents(): array
|
||||
{
|
||||
return [
|
||||
CheckPassportEvent::class => ['preCheckCredentials', 256],
|
||||
LoginSuccessEvent::class => ['postCheckCredentials', 256],
|
||||
AuthenticationSuccessEvent::class => ['postCheckCredentials', 256],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -12,8 +12,8 @@
|
||||
namespace Symfony\Component\Security\Http\Tests\EventListener;
|
||||
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\PreAuthenticatedToken;
|
||||
use Symfony\Component\Security\Core\Event\AuthenticationSuccessEvent;
|
||||
use Symfony\Component\Security\Core\User\User;
|
||||
use Symfony\Component\Security\Core\User\UserCheckerInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\AuthenticatorInterface;
|
||||
@ -21,8 +21,8 @@ use Symfony\Component\Security\Http\Authenticator\Passport\Badge\PreAuthenticate
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\PassportInterface;
|
||||
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
|
||||
use Symfony\Component\Security\Http\Authenticator\Token\PostAuthenticationToken;
|
||||
use Symfony\Component\Security\Http\Event\CheckPassportEvent;
|
||||
use Symfony\Component\Security\Http\Event\LoginSuccessEvent;
|
||||
use Symfony\Component\Security\Http\EventListener\UserCheckerListener;
|
||||
|
||||
class UserCheckerListenerTest extends TestCase
|
||||
@ -63,14 +63,14 @@ class UserCheckerListenerTest extends TestCase
|
||||
{
|
||||
$this->userChecker->expects($this->once())->method('checkPostAuth')->with($this->user);
|
||||
|
||||
$this->listener->postCheckCredentials($this->createLoginSuccessEvent());
|
||||
$this->listener->postCheckCredentials(new AuthenticationSuccessEvent(new PostAuthenticationToken($this->user, 'main', [])));
|
||||
}
|
||||
|
||||
public function testPostAuthNoUser()
|
||||
{
|
||||
$this->userChecker->expects($this->never())->method('checkPostAuth');
|
||||
|
||||
$this->listener->postCheckCredentials($this->createLoginSuccessEvent($this->createMock(PassportInterface::class)));
|
||||
$this->listener->postCheckCredentials(new AuthenticationSuccessEvent(new PreAuthenticatedToken('nobody', null, 'main')));
|
||||
}
|
||||
|
||||
private function createCheckPassportEvent($passport = null)
|
||||
@ -82,12 +82,8 @@ class UserCheckerListenerTest extends TestCase
|
||||
return new CheckPassportEvent($this->createMock(AuthenticatorInterface::class), $passport);
|
||||
}
|
||||
|
||||
private function createLoginSuccessEvent($passport = null)
|
||||
private function createAuthenticationSuccessEvent()
|
||||
{
|
||||
if (null === $passport) {
|
||||
$passport = new SelfValidatingPassport(new UserBadge('test', function () { return $this->user; }));
|
||||
}
|
||||
|
||||
return new LoginSuccessEvent($this->createMock(AuthenticatorInterface::class), $passport, $this->createMock(TokenInterface::class), new Request(), null, 'main');
|
||||
return new AuthenticationSuccessEvent(new PostAuthenticationToken($this->user, 'main', []));
|
||||
}
|
||||
}
|
||||
|
@ -359,6 +359,10 @@ class UnicodeString extends AbstractUnicodeString
|
||||
|
||||
public function __wakeup()
|
||||
{
|
||||
if (!\is_string($this->string)) {
|
||||
throw new \BadMethodCallException('Cannot unserialize '.__CLASS__);
|
||||
}
|
||||
|
||||
normalizer_is_normalized($this->string) ?: $this->string = normalizer_normalize($this->string);
|
||||
}
|
||||
|
||||
|
@ -203,7 +203,7 @@ class Parser
|
||||
array_pop($this->refsBeingParsed);
|
||||
}
|
||||
} elseif (
|
||||
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:(\s++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
|
||||
self::preg_match('#^(?P<key>(?:![^\s]++\s++)?(?:'.Inline::REGEX_QUOTED_STRING.'|(?:!?!php/const:)?[^ \'"\[\{!].*?)) *\:( ++(?P<value>.+))?$#u', rtrim($this->currentLine), $values)
|
||||
&& (false === strpos($values['key'], ' #') || \in_array($values['key'][0], ['"', "'"]))
|
||||
) {
|
||||
if ($context && 'sequence' == $context) {
|
||||
|
@ -915,4 +915,21 @@ class InlineTest extends TestCase
|
||||
[['!'], '! ["!"]'],
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @dataProvider ideographicSpaceProvider
|
||||
*/
|
||||
public function testParseIdeographicSpace(string $yaml, string $expected)
|
||||
{
|
||||
$this->assertSame($expected, Inline::parse($yaml));
|
||||
}
|
||||
|
||||
public function ideographicSpaceProvider(): array
|
||||
{
|
||||
return [
|
||||
["\u{3000}", ' '],
|
||||
["'\u{3000}'", ' '],
|
||||
["'a b'", 'a b'],
|
||||
];
|
||||
}
|
||||
}
|
||||
|
@ -2732,6 +2732,22 @@ YAML;
|
||||
// (before, there was no \n after row2)
|
||||
$this->assertSame(['a' => ['b' => "row\nrow2\n"], 'c' => 'd'], $this->parser->parse($longDocument));
|
||||
}
|
||||
|
||||
public function testParseIdeographicSpaces()
|
||||
{
|
||||
$expected = <<<YAML
|
||||
unquoted: \u{3000}
|
||||
quoted: '\u{3000}'
|
||||
within_string: 'a b'
|
||||
regular_space: 'a b'
|
||||
YAML;
|
||||
$this->assertSame([
|
||||
'unquoted' => ' ',
|
||||
'quoted' => ' ',
|
||||
'within_string' => 'a b',
|
||||
'regular_space' => 'a b',
|
||||
], $this->parser->parse($expected));
|
||||
}
|
||||
}
|
||||
|
||||
class B
|
||||
|
@ -11,7 +11,7 @@ Design Principles
|
||||
|
||||
* contracts are split by domain, each into their own sub-namespaces;
|
||||
* contracts are small and consistent sets of PHP interfaces, traits, normative
|
||||
docblocks and reference test suites when applicable, ...;
|
||||
docblocks and reference test suites when applicable;
|
||||
* all contracts must have a proven implementation to enter this repository;
|
||||
* they must be backward compatible with existing Symfony components.
|
||||
|
||||
|
Reference in New Issue
Block a user