mirror of
https://github.com/kevinpapst/kimai2.git
synced 2025-04-03 04:55:25 +00:00

Make auth configuration available via UI, remove FOSUserBundle and SAML-Bundle dependency
227 lines
10 KiB
PHP
227 lines
10 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Kimai time-tracking app.
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace App;
|
|
|
|
use App\DependencyInjection\AppExtension;
|
|
use App\DependencyInjection\Compiler\ExportServiceCompilerPass;
|
|
use App\DependencyInjection\Compiler\InvoiceServiceCompilerPass;
|
|
use App\DependencyInjection\Compiler\TwigContextCompilerPass;
|
|
use App\DependencyInjection\Compiler\WidgetCompilerPass;
|
|
use App\Export\ExportRepositoryInterface;
|
|
use App\Export\RendererInterface as ExportRendererInterface;
|
|
use App\Export\TimesheetExportInterface;
|
|
use App\Invoice\CalculatorInterface as InvoiceCalculator;
|
|
use App\Invoice\InvoiceItemRepositoryInterface;
|
|
use App\Invoice\NumberGeneratorInterface;
|
|
use App\Invoice\RendererInterface as InvoiceRendererInterface;
|
|
use App\Ldap\FormLoginLdapFactory;
|
|
use App\Plugin\PluginInterface;
|
|
use App\Saml\Security\SamlFactory;
|
|
use App\Timesheet\CalculatorInterface as TimesheetCalculator;
|
|
use App\Timesheet\Rounding\RoundingInterface;
|
|
use App\Timesheet\TrackingMode\TrackingModeInterface;
|
|
use App\Validator\Constraints\TimesheetConstraint;
|
|
use App\Widget\WidgetInterface;
|
|
use App\Widget\WidgetRendererInterface;
|
|
use Symfony\Bundle\FrameworkBundle\Kernel\MicroKernelTrait;
|
|
use Symfony\Bundle\SecurityBundle\DependencyInjection\SecurityExtension;
|
|
use Symfony\Component\Config\Loader\LoaderInterface;
|
|
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
|
|
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
|
use Symfony\Component\Finder\Finder;
|
|
use Symfony\Component\Finder\SplFileInfo;
|
|
use Symfony\Component\HttpKernel\Kernel as BaseKernel;
|
|
use Symfony\Component\Routing\RouteCollectionBuilder;
|
|
|
|
class Kernel extends BaseKernel
|
|
{
|
|
use MicroKernelTrait;
|
|
|
|
public const CONFIG_EXTS = '.{php,xml,yaml,yml}';
|
|
|
|
public const TAG_PLUGIN = 'kimai.plugin';
|
|
public const TAG_WIDGET = 'widget';
|
|
public const TAG_WIDGET_RENDERER = 'widget.renderer';
|
|
public const TAG_EXPORT_RENDERER = 'export.renderer';
|
|
public const TAG_EXPORT_REPOSITORY = 'export.repository';
|
|
public const TAG_INVOICE_RENDERER = 'invoice.renderer';
|
|
public const TAG_INVOICE_NUMBER_GENERATOR = 'invoice.number_generator';
|
|
public const TAG_INVOICE_CALCULATOR = 'invoice.calculator';
|
|
public const TAG_INVOICE_REPOSITORY = 'invoice.repository';
|
|
public const TAG_TIMESHEET_CALCULATOR = 'timesheet.calculator';
|
|
public const TAG_TIMESHEET_VALIDATOR = 'timesheet.validator';
|
|
public const TAG_TIMESHEET_EXPORTER = 'timesheet.exporter';
|
|
public const TAG_TIMESHEET_TRACKING_MODE = 'timesheet.tracking_mode';
|
|
public const TAG_TIMESHEET_ROUNDING_MODE = 'timesheet.rounding_mode';
|
|
|
|
public function getCacheDir()
|
|
{
|
|
return $this->getProjectDir() . '/var/cache/' . $this->environment;
|
|
}
|
|
|
|
public function getLogDir()
|
|
{
|
|
return $this->getProjectDir() . '/var/log';
|
|
}
|
|
|
|
protected function build(ContainerBuilder $container)
|
|
{
|
|
$container->registerForAutoconfiguration(TimesheetCalculator::class)->addTag(self::TAG_TIMESHEET_CALCULATOR);
|
|
$container->registerForAutoconfiguration(ExportRendererInterface::class)->addTag(self::TAG_EXPORT_RENDERER);
|
|
$container->registerForAutoconfiguration(ExportRepositoryInterface::class)->addTag(self::TAG_EXPORT_REPOSITORY);
|
|
$container->registerForAutoconfiguration(InvoiceRendererInterface::class)->addTag(self::TAG_INVOICE_RENDERER);
|
|
$container->registerForAutoconfiguration(NumberGeneratorInterface::class)->addTag(self::TAG_INVOICE_NUMBER_GENERATOR);
|
|
$container->registerForAutoconfiguration(InvoiceCalculator::class)->addTag(self::TAG_INVOICE_CALCULATOR);
|
|
$container->registerForAutoconfiguration(InvoiceItemRepositoryInterface::class)->addTag(self::TAG_INVOICE_REPOSITORY);
|
|
$container->registerForAutoconfiguration(PluginInterface::class)->addTag(self::TAG_PLUGIN);
|
|
$container->registerForAutoconfiguration(WidgetRendererInterface::class)->addTag(self::TAG_WIDGET_RENDERER);
|
|
$container->registerForAutoconfiguration(WidgetInterface::class)->addTag(self::TAG_WIDGET);
|
|
$container->registerForAutoconfiguration(TimesheetExportInterface::class)->addTag(self::TAG_TIMESHEET_EXPORTER);
|
|
$container->registerForAutoconfiguration(TrackingModeInterface::class)->addTag(self::TAG_TIMESHEET_TRACKING_MODE);
|
|
$container->registerForAutoconfiguration(RoundingInterface::class)->addTag(self::TAG_TIMESHEET_ROUNDING_MODE);
|
|
$container->registerForAutoconfiguration(TimesheetConstraint::class)->addTag(self::TAG_TIMESHEET_VALIDATOR);
|
|
|
|
/** @var SecurityExtension $extension */
|
|
$extension = $container->getExtension('security');
|
|
$extension->addSecurityListenerFactory(new FormLoginLdapFactory());
|
|
$extension->addSecurityListenerFactory(new SamlFactory());
|
|
}
|
|
|
|
public function registerBundles()
|
|
{
|
|
$contents = require $this->getProjectDir() . '/config/bundles.php';
|
|
foreach ($contents as $class => $envs) {
|
|
if (isset($envs['all']) || isset($envs[$this->environment])) {
|
|
yield new $class();
|
|
}
|
|
}
|
|
|
|
if ($this->environment === 'test' && getenv('TEST_WITH_BUNDLES') === false) {
|
|
return;
|
|
}
|
|
|
|
// we can either define all kimai bundles hardcoded ...
|
|
if (is_file($this->getProjectDir() . '/config/bundles-local.php')) {
|
|
$contents = require $this->getProjectDir() . '/config/bundles-local.php';
|
|
foreach ($contents as $class => $envs) {
|
|
if (isset($envs['all']) || isset($envs[$this->environment])) {
|
|
yield new $class();
|
|
}
|
|
}
|
|
} else {
|
|
// ... or we load them dynamically from the plugins directory
|
|
foreach ($this->getBundleDirectories() as $bundleDir) {
|
|
$bundleName = $bundleDir->getRelativePathname();
|
|
$pluginClass = 'KimaiPlugin\\' . $bundleName . '\\' . $bundleName;
|
|
yield new $pluginClass();
|
|
}
|
|
}
|
|
}
|
|
|
|
private function getBundleDirectories(): array
|
|
{
|
|
$pluginsDir = $this->getProjectDir() . '/var/plugins';
|
|
if (!file_exists($pluginsDir)) {
|
|
return [];
|
|
}
|
|
|
|
$directories = [];
|
|
$finder = new Finder();
|
|
$finder->ignoreUnreadableDirs()->directories()->name('*Bundle');
|
|
/** @var SplFileInfo $bundleDir */
|
|
foreach ($finder->in($pluginsDir) as $bundleDir) {
|
|
$bundleName = $bundleDir->getRelativePathname();
|
|
|
|
$bundleFilename = $bundleDir->getRealPath() . '/' . $bundleName . '.php';
|
|
if (!file_exists($bundleFilename)) {
|
|
continue;
|
|
}
|
|
|
|
if (file_exists($bundleDir->getRealPath() . '/.disabled')) {
|
|
continue;
|
|
}
|
|
|
|
$pluginClass = 'KimaiPlugin\\' . $bundleName . '\\' . $bundleName;
|
|
if (!class_exists($pluginClass)) {
|
|
continue;
|
|
}
|
|
|
|
$directories[] = $bundleDir;
|
|
}
|
|
|
|
return $directories;
|
|
}
|
|
|
|
protected function configureContainer(ContainerBuilder $container, LoaderInterface $loader)
|
|
{
|
|
$container->registerExtension(new AppExtension());
|
|
|
|
$container->setParameter('container.autowiring.strict_mode', true);
|
|
$container->setParameter('container.dumper.inline_class_loader', true);
|
|
$confDir = $this->getProjectDir() . '/config';
|
|
|
|
// if you want to prepend any config, you can do it here
|
|
$loader->load($confDir . '/packages/local_before' . self::CONFIG_EXTS, 'glob');
|
|
|
|
// using this one instead of $loader->load($confDir . '/packages/*' . self::CONFIG_EXTS, 'glob');
|
|
// to get rid of the local.yaml from the list, we load it afterwards explicit
|
|
$finder = (new Finder())
|
|
->files()
|
|
->in([$confDir . '/packages/'])
|
|
->name('*' . self::CONFIG_EXTS)
|
|
->notName('local*' . self::CONFIG_EXTS)
|
|
->depth('== 0')
|
|
->sortByName()
|
|
->followLinks()
|
|
;
|
|
|
|
/** @var SplFileInfo $file */
|
|
foreach ($finder as $file) {
|
|
$loader->load($file->getPathname());
|
|
}
|
|
|
|
if (is_dir($confDir . '/packages/' . $this->environment)) {
|
|
$loader->load($confDir . '/packages/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob');
|
|
}
|
|
$loader->load($confDir . '/packages/local' . self::CONFIG_EXTS, 'glob');
|
|
$loader->load($confDir . '/services' . self::CONFIG_EXTS, 'glob');
|
|
$loader->load($confDir . '/services-*' . self::CONFIG_EXTS, 'glob');
|
|
$loader->load($confDir . '/services_' . $this->environment . self::CONFIG_EXTS, 'glob');
|
|
|
|
$container->addCompilerPass(new TwigContextCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
|
|
$container->addCompilerPass(new InvoiceServiceCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
|
|
$container->addCompilerPass(new ExportServiceCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
|
|
$container->addCompilerPass(new WidgetCompilerPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, -1000);
|
|
}
|
|
|
|
protected function configureRoutes(RouteCollectionBuilder $routes)
|
|
{
|
|
$confDir = $this->getProjectDir() . '/config';
|
|
|
|
// load bundle specific route files
|
|
if (is_dir($confDir . '/routes/')) {
|
|
$routes->import($confDir . '/routes/*' . self::CONFIG_EXTS, '/', 'glob');
|
|
}
|
|
|
|
// load environment specific route files
|
|
if (is_dir($confDir . '/routes/' . $this->environment)) {
|
|
$routes->import($confDir . '/routes/' . $this->environment . '/**/*' . self::CONFIG_EXTS, '/', 'glob');
|
|
}
|
|
|
|
// load application routes
|
|
$routes->import($confDir . '/routes' . self::CONFIG_EXTS, '/', 'glob');
|
|
|
|
foreach ($this->bundles as $bundle) {
|
|
if (strpos(\get_class($bundle), 'KimaiPlugin\\') !== false) {
|
|
$routes->import($bundle->getPath() . '/Resources/config/routes' . self::CONFIG_EXTS, '/', 'glob');
|
|
}
|
|
}
|
|
}
|
|
}
|