Merge branch '5.2' into 5.x

* 5.2:
  [HttpKernel] Configure `session.cookie_secure` earlier
  Make sure the Psalm review CI job is working
  Adding a Github action to run Psalm
This commit is contained in:
Nicolas Grekas 2021-02-25 18:20:06 +01:00
commit cd59bfa080
7 changed files with 144 additions and 5 deletions

2
.github/psalm/cache/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
*
!.gitignore

3
.github/psalm/psalm.baseline.xml vendored Normal file
View File

@ -0,0 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="4.x-dev@">
</files>

97
.github/workflows/psalm.yml vendored Normal file
View File

@ -0,0 +1,97 @@
name: Static analysis
on:
pull_request: ~
jobs:
psalm:
name: Psalm
runs-on: Ubuntu-20.04
steps:
- name: Set up PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.0'
extensions: "json,memcached,mongodb,redis,xsl,ldap,dom"
ini-values: "memory_limit=-1"
coverage: none
- name: Checkout PR
uses: actions/checkout@v2
with:
path: pr
- name: Checkout base
uses: actions/checkout@v2
with:
ref: ${{ github.base_ref }}
path: base
- name: Configure composer
run: |
cd base
COMPOSER_HOME="$(composer config home)"
([ -d "$COMPOSER_HOME" ] || mkdir "$COMPOSER_HOME") && cp .github/composer-config.json "$COMPOSER_HOME/config.json"
echo "COMPOSER_ROOT_VERSION=$(grep -m1 SYMFONY_VERSION .travis.yml | grep -o '[0-9.x]*').x-dev" >> $GITHUB_ENV
- name: Determine composer cache directory
id: composer-cache
run: echo "::set-output name=dir::$(composer config cache-files-dir)"
- name: Cache composer dependencies
uses: actions/cache@v2
with:
path: ${{ steps.composer-cache.outputs.dir }}
key: composer-${{ github.base_ref }}
restore-keys: composer-
- name: Install Psalm
run: |
composer require psalm/phar
cp ./vendor/bin/psalm.phar base/psalm.phar
cp ./vendor/bin/psalm.phar pr/psalm.phar
- name: Install dependencies for base
run: |
cd base
echo "::group::modify composer.json"
composer remove symfony/phpunit-bridge --no-interaction --no-update
composer require --no-update phpunit/phpunit php-http/discovery psr/event-dispatcher
echo "::endgroup::"
echo "::group::composer update"
composer update --no-progress --ansi
echo "::endgroup::"
- name: Generate Psalm baseline
run: |
cd base
./psalm.phar --set-baseline=.github/psalm/psalm.baseline.xml --no-progress
- name: Copy baseline
run: |
cp base/.github/psalm/psalm.baseline.xml pr/.github/psalm/psalm.baseline.xml
- name: Install dependencies for PR
run: |
cd pr
echo "::group::modify composer.json"
composer remove symfony/phpunit-bridge --no-interaction --no-update
composer require --no-update phpunit/phpunit php-http/discovery psr/event-dispatcher
echo "::endgroup::"
echo "::group::composer update"
composer update --no-progress --ansi
echo "::endgroup::"
- name: Cache Psalm
uses: actions/cache@v2
with:
path: pr/.github/psalm/cache/
key: psalm-${{ github.base_ref }}
restore-keys: psalm-
- name: Psalm
run: |
cd pr
./psalm.phar --version
./psalm.phar --output-format=github --no-progress

20
psalm.xml Normal file
View File

@ -0,0 +1,20 @@
<?xml version="1.0"?>
<psalm
errorLevel="5"
resolveFromConfigFile="true"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
cacheDirectory="./.github/psalm/cache/"
errorBaseline=".github/psalm/psalm.baseline.xml"
>
<projectFiles>
<directory name="src" />
<ignoreFiles>
<directory name="src/Symfony/*/*/Tests" />
<directory name="src/Symfony/*/*/*/Tests" />
<directory name="src/Symfony/*/*/*/*/Tests" />
<directory name="vendor" />
</ignoreFiles>
</projectFiles>
</psalm>

View File

@ -389,6 +389,9 @@ class NativeSessionStorage implements SessionStorageInterface
$this->emulateSameSite = $value; $this->emulateSameSite = $value;
continue; continue;
} }
if ('cookie_secure' === $key && 'auto' === $value) {
continue;
}
ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value); ini_set('url_rewriter.tags' !== $key ? 'session.'.$key : $key, $value);
} }
} }

View File

@ -14,6 +14,7 @@ namespace Symfony\Component\HttpKernel\EventListener;
use Psr\Container\ContainerInterface; use Psr\Container\ContainerInterface;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage; use Symfony\Component\HttpFoundation\Session\Storage\NativeSessionStorage;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
/** /**
* Sets the session in the request. * Sets the session in the request.
@ -33,10 +34,12 @@ class SessionListener extends AbstractSessionListener
parent::__construct($container, $debug); parent::__construct($container, $debug);
} }
protected function getSession(): ?SessionInterface public function onKernelRequest(GetResponseEvent $event)
{ {
if (!$this->container->has('session')) { parent::onKernelRequest($event);
return null;
if (!$event->isMasterRequest() || !$this->container->has('session')) {
return;
} }
if ($this->container->has('session_storage') if ($this->container->has('session_storage')
@ -46,6 +49,13 @@ class SessionListener extends AbstractSessionListener
) { ) {
$storage->setOptions(['cookie_secure' => true]); $storage->setOptions(['cookie_secure' => true]);
} }
}
protected function getSession(): ?SessionInterface
{
if (!$this->container->has('session')) {
return null;
}
return $this->container->get('session'); return $this->container->get('session');
} }

View File

@ -62,7 +62,7 @@ class SessionListenerTest extends TestCase
$listener = new SessionListener($container); $listener = new SessionListener($container);
$event = $this->createMock(RequestEvent::class); $event = $this->createMock(RequestEvent::class);
$event->expects($this->once())->method('isMasterRequest')->willReturn(true); $event->expects($this->exactly(2))->method('isMasterRequest')->willReturn(true);
$event->expects($this->once())->method('getRequest')->willReturn($request); $event->expects($this->once())->method('getRequest')->willReturn($request);
$listener->onKernelRequest($event); $listener->onKernelRequest($event);
@ -206,12 +206,16 @@ class SessionListenerTest extends TestCase
$listener = new SessionListener($container); $listener = new SessionListener($container);
$listener->onKernelRequest($event); $listener->onKernelRequest($event);
// storage->setOptions() should have been called already
$container->set('session_storage', null);
$sessionStorage = null;
$subRequest = $masterRequest->duplicate(); $subRequest = $masterRequest->duplicate();
// at this point both master and subrequest have a closure to build the session // at this point both master and subrequest have a closure to build the session
$masterRequest->getSession(); $masterRequest->getSession();
// calling the factory on the subRequest should not trigger a second call to storage->sesOptions() // calling the factory on the subRequest should not trigger a second call to storage->setOptions()
$subRequest->getSession(); $subRequest->getSession();
} }