<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <fabien@symfony.com>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Bundle\SecurityBundle\DependencyInjection\Compiler;

use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;

/**
 * Uses the session domain to restrict allowed redirection targets.
 *
 * @author Nicolas Grekas <p@tchwork.com>
 */
class AddSessionDomainConstraintPass implements CompilerPassInterface
{
    public function process(ContainerBuilder $container): void
    {
        if (!$container->has('security.http_utils')) {
            return;
        }

        // Without sessions, fall back to restricting redirections to the current host
        $sessionOptions = $container->hasParameter('session.storage.options') ? $container->getParameter('session.storage.options') : [];
        $domainRegexp = empty($sessionOptions['cookie_domain']) ? '%%s' : \sprintf('(?:%%%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));

        if ('auto' === ($sessionOptions['cookie_secure'] ?? null)) {
            $secureDomainRegexp = \sprintf('{^https://%s$}i', $domainRegexp);
            $domainRegexp = 'https?://'.$domainRegexp;
        } else {
            $secureDomainRegexp = null;
            $domainRegexp = (empty($sessionOptions['cookie_secure']) ? 'https?://' : 'https://').$domainRegexp;
        }

        $container->getDefinition('security.http_utils')
            ->addArgument(\sprintf('{^%s$}i', $domainRegexp))
            ->addArgument($secureDomainRegexp);
    }
}
