Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 17 additions & 0 deletions dependencies.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
"recipesEndpoint": "https://api.github.com/repos/ibexa/recipes-dev/contents/index.json?ref=flex/pull-118",
"packages": [
{
"requirement": "dev-ibx-8140-enable-authorization-with-new-authenticator-mechanisms as 5.0.x-dev",
"repositoryUrl": "https://github.com/ibexa/rest",
"package": "ibexa/rest",
"shouldBeAddedAsVCS": false
},
{
"requirement": "dev-ibx-8140-enable-authorization-with-new-authenticator-mechanisms as 5.0.x-dev",
"repositoryUrl": "https://github.com/ibexa/admin-ui",
"package": "ibexa/admin-ui",
"shouldBeAddedAsVCS": false
}
]
}
222 changes: 1 addition & 221 deletions phpstan-baseline.neon

Large diffs are not rendered by default.

77 changes: 9 additions & 68 deletions src/bundle/Core/DependencyInjection/Compiler/SecurityPass.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,8 @@
namespace Ibexa\Bundle\Core\DependencyInjection\Compiler;

use Ibexa\Contracts\Core\Repository\PermissionResolver;
use Ibexa\Contracts\Core\Repository\UserService;
use Ibexa\Core\MVC\Symfony\Security\Authentication\AnonymousAuthenticationProvider;
use Ibexa\Core\MVC\Symfony\Security\Authentication\DefaultAuthenticationSuccessHandler;
use Ibexa\Core\MVC\Symfony\Security\Authentication\GuardRepositoryAuthenticationProvider;
use Ibexa\Core\MVC\Symfony\Security\Authentication\RememberMeRepositoryAuthenticationProvider;
use Ibexa\Core\MVC\Symfony\Security\Authentication\RepositoryAuthenticationProvider;
use Ibexa\Core\MVC\Symfony\Security\HttpUtils;
use Ibexa\Core\MVC\Symfony\SiteAccess;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
Expand All @@ -22,52 +18,24 @@

/**
* Security related compiler pass.
* Manipulates Symfony core security services to adapt them to eZ security needs.
* Manipulates Symfony core security services to adapt them to Ibexa security needs.
*/
class SecurityPass implements CompilerPassInterface
final class SecurityPass implements CompilerPassInterface
{
public const CONSTANT_AUTH_TIME_SETTING = 'ibexa.security.authentication.constant_auth_time';
public const string CONSTANT_AUTH_TIME_SETTING = 'ibexa.security.authentication.constant_auth_time';

public const CONSTANT_AUTH_TIME_DEFAULT = 1.0;
public const float CONSTANT_AUTH_TIME_DEFAULT = 1.0;

public function process(ContainerBuilder $container)
public function process(ContainerBuilder $container): void
{
if (!($container->hasDefinition('security.authentication.provider.dao') &&
$container->hasDefinition('security.authentication.provider.rememberme') &&
$container->hasDefinition('security.authentication.provider.guard') &&
$container->hasDefinition('security.authentication.provider.anonymous'))) {
if (
!$container->hasDefinition('security.authentication.provider.rememberme') ||
!$container->hasDefinition('security.authentication.provider.guard')
) {
return;
}

$configResolverRef = new Reference('ibexa.config.resolver');
$permissionResolverRef = new Reference(PermissionResolver::class);
$userServiceRef = new Reference(UserService::class);
$loggerRef = new Reference('logger');

// Override and inject the Repository in the authentication provider.
// We need it for checking user credentials
$daoAuthenticationProviderDef = $container->findDefinition('security.authentication.provider.dao');
$daoAuthenticationProviderDef->setClass(RepositoryAuthenticationProvider::class);
$daoAuthenticationProviderDef->addMethodCall(
'setPermissionResolver',
[$permissionResolverRef]
);
$daoAuthenticationProviderDef->addMethodCall(
'setUserService',
[$userServiceRef]
);
$daoAuthenticationProviderDef->addMethodCall(
'setConstantAuthTime',
[
$container->hasParameter(self::CONSTANT_AUTH_TIME_SETTING) ?
(float)$container->getParameter(self::CONSTANT_AUTH_TIME_SETTING) :
self::CONSTANT_AUTH_TIME_DEFAULT,
]
);
$daoAuthenticationProviderDef->addMethodCall(
'setLogger',
[$loggerRef]
);

$rememberMeAuthenticationProviderDef = $container->findDefinition('security.authentication.provider.rememberme');
$rememberMeAuthenticationProviderDef->setClass(RememberMeRepositoryAuthenticationProvider::class);
Expand All @@ -83,18 +51,6 @@ public function process(ContainerBuilder $container)
[$permissionResolverRef]
);

$anonymousAuthenticationProviderDef = $container->findDefinition('security.authentication.provider.anonymous');
$anonymousAuthenticationProviderDef->setClass(AnonymousAuthenticationProvider::class);
$anonymousAuthenticationProviderDef->addMethodCall(
'setPermissionResolver',
[$permissionResolverRef]
);

$anonymousAuthenticationProviderDef->addMethodCall(
'setConfigResolver',
[$configResolverRef]
);

if (!$container->hasDefinition('security.http_utils')) {
return;
}
Expand All @@ -105,20 +61,5 @@ public function process(ContainerBuilder $container)
'setSiteAccess',
[new Reference(SiteAccess::class)]
);

if (!$container->hasDefinition('security.authentication.success_handler')) {
return;
}

$successHandlerDef = $container->getDefinition('security.authentication.success_handler');
$successHandlerDef->setClass(DefaultAuthenticationSuccessHandler::class);
$successHandlerDef->addMethodCall(
'setConfigResolver',
[$configResolverRef]
);
$successHandlerDef->addMethodCall(
'setEventDispatcher',
[new Reference('event_dispatcher')]
);
}
}
23 changes: 0 additions & 23 deletions src/bundle/Core/DependencyInjection/Security/HttpBasicFactory.php

This file was deleted.

1 change: 1 addition & 0 deletions src/bundle/Core/Features/Content/content_preview.feature
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@javascript
Feature: Preview of content drafts

As a content editor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
@javascript
Feature: Handling of Unauthorized repository exceptions
Scenario: When a Repository UnauthorizedException is throw, anonymous users are shown the login screen
Given that I am not logged in
Expand Down
11 changes: 5 additions & 6 deletions src/bundle/Core/IbexaCoreBundle.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Bundle\Core;

Expand Down Expand Up @@ -37,7 +38,6 @@
use Ibexa\Bundle\Core\DependencyInjection\Configuration\Parser as ConfigParser;
use Ibexa\Bundle\Core\DependencyInjection\Configuration\Parser\Repository as RepositoryConfigParser;
use Ibexa\Bundle\Core\DependencyInjection\IbexaCoreExtension;
use Ibexa\Bundle\Core\DependencyInjection\Security\HttpBasicFactory;
use Ibexa\Contracts\Core\MVC\View\VariableProvider;
use Ibexa\Core\Base\Container\Compiler\FieldTypeRegistryPass;
use Ibexa\Core\Base\Container\Compiler\GenericFieldTypeConverterPass;
Expand All @@ -49,11 +49,12 @@
use Ibexa\Core\Base\Container\Compiler\Storage\Legacy\RoleLimitationConverterPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
use Symfony\Component\HttpKernel\Bundle\Bundle;

class IbexaCoreBundle extends Bundle
final class IbexaCoreBundle extends Bundle
{
public function build(ContainerBuilder $container)
public function build(ContainerBuilder $container): void
{
parent::build($container);
$container->addCompilerPass(new GenericFieldTypeConverterPass(), PassConfig::TYPE_OPTIMIZE);
Expand Down Expand Up @@ -92,15 +93,13 @@ public function build(ContainerBuilder $container)
$container->addCompilerPass(new RoleLimitationConverterPass());
$container->addCompilerPass(new QueryTypePass());

$securityExtension = $container->getExtension('security');
$securityExtension->addSecurityListenerFactory(new HttpBasicFactory());
$container->addCompilerPass(new TranslationCollectorPass());
$container->addCompilerPass(new SlugConverterConfigurationPass());

$container->registerForAutoconfiguration(VariableProvider::class)->addTag('ezplatform.view.variable_provider');
}

public function getContainerExtension()
public function getContainerExtension(): ?ExtensionInterface
{
if (!isset($this->extension)) {
$this->extension = new IbexaCoreExtension(
Expand Down
25 changes: 12 additions & 13 deletions src/bundle/Core/Resources/config/security.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,19 +40,18 @@ services:
class: Ibexa\Core\MVC\Symfony\Controller\SecurityController
arguments: ["@twig", '@ibexa.config.resolver', "@security.authentication_utils"]

Ibexa\Core\MVC\Symfony\Security\EventListener\SecurityListener:
class: Ibexa\Core\MVC\Symfony\Security\EventListener\SecurityListener
arguments:
- '@Ibexa\Contracts\Core\Repository\PermissionResolver'
- '@Ibexa\Contracts\Core\Repository\UserService'
- '@ibexa.config.resolver'
- "@event_dispatcher"
- "@security.token_storage"
- "@security.authorization_checker"
- "%fragment.path%"
tags:
- { name: kernel.event_subscriber }

ibexa.security.user_provider: '@Ibexa\Core\MVC\Symfony\Security\User\UsernameProvider'
ibexa.security.user_provider.username: '@Ibexa\Core\MVC\Symfony\Security\User\UsernameProvider'
ibexa.security.user_provider.email: '@Ibexa\Core\MVC\Symfony\Security\User\EmailProvider'

Ibexa\Core\MVC\Symfony\Security\Authentication\EventSubscriber\AccessDeniedSubscriber:
autowire: true
autoconfigure: true

Ibexa\Core\MVC\Symfony\Security\Authentication\DefaultAuthenticationSuccessHandler:
autowire: true
autoconfigure: true
abstract: true
decorates: security.authentication.success_handler
arguments:
$innerHandler: '@.inner'
Empty file removed src/lib/.gitkeep
Empty file.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,40 @@
* @copyright Copyright (C) Ibexa AS. All rights reserved.
* @license For full copyright and license information view LICENSE file distributed with this source code.
*/
declare(strict_types=1);

namespace Ibexa\Core\MVC\Symfony\Security\Authentication;

use Ibexa\Contracts\Core\Repository\PermissionResolver;
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
use Ibexa\Core\MVC\Symfony\Security\UserInterface;
use Psr\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Http\Authentication\DefaultAuthenticationSuccessHandler as BaseSuccessHandler;

class DefaultAuthenticationSuccessHandler extends BaseSuccessHandler
final class DefaultAuthenticationSuccessHandler extends BaseSuccessHandler
{
private EventDispatcherInterface $eventDispatcher;

private ConfigResolverInterface $configResolver;

/**
* Injects the ConfigResolver to potentially override default_target_path for redirections after authentication success.
*/
public function setConfigResolver(ConfigResolverInterface $configResolver): void
{
$this->configResolver = $configResolver;
public function __construct(
private readonly BaseSuccessHandler $innerHandler,
private readonly EventDispatcherInterface $eventDispatcher,
private readonly ConfigResolverInterface $configResolver,
private readonly PermissionResolver $permissionResolver,
) {
}

public function setEventDispatcher(EventDispatcherInterface $eventDispatcher): void
public function onAuthenticationSuccess(Request $request, TokenInterface $token): ?Response
{
$this->eventDispatcher = $eventDispatcher;
$user = $token->getUser();
if ($user instanceof UserInterface && isset($this->permissionResolver)) {
$this->permissionResolver->setCurrentUserReference($user->getAPIUser());
}

return $this->innerHandler->onAuthenticationSuccess($request, $token);
}

protected function determineTargetUrl(Request $request)
protected function determineTargetUrl(Request $request): string
{
if (isset($this->configResolver)) {
$defaultPage = $this->configResolver->getParameter('default_page');
Expand All @@ -41,12 +47,17 @@ protected function determineTargetUrl(Request $request)
}

if (isset($this->eventDispatcher)) {
$event = new DetermineTargetUrlEvent($request, $this->options, $this->getFirewallName());
$event = new DetermineTargetUrlEvent(
$request,
$this->options,
$this->getFirewallName() ?? ''
);

$this->eventDispatcher->dispatch($event);

$this->options = $event->getOptions();
}

return parent::determineTargetUrl($request);
return $this->innerHandler->determineTargetUrl($request);
}
}
Loading