Skip to content
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
services:
App\EventSubscriber\InteractiveLoginSubscriber:
App\EventSubscriber\AuthenticationTokenCreatedSubscriber:
arguments:
$userMap:
from_memory_user: generic_customer
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,12 @@

use Ibexa\Contracts\Core\Repository\UserService;
use Ibexa\Contracts\Core\SiteAccess\ConfigResolverInterface;
//use Ibexa\Core\MVC\Symfony\Security\User;
use Ibexa\Core\MVC\Symfony\Security\UserWrapped;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Security\Core\User\InMemoryUser;
use Symfony\Component\Security\Http\Event\InteractiveLoginEvent;
use Symfony\Component\Security\Http\SecurityEvents;
use Symfony\Component\Security\Http\Event\AuthenticationTokenCreatedEvent;

final readonly class InteractiveLoginSubscriber implements EventSubscriberInterface
final readonly class AuthenticationTokenCreatedSubscriber implements EventSubscriberInterface
{
/** @param array<string, string> $userMap */
public function __construct(
Expand All @@ -24,17 +22,18 @@ public function __construct(
public static function getSubscribedEvents(): array
{
return [
SecurityEvents::INTERACTIVE_LOGIN => 'onInteractiveLogin',
AuthenticationTokenCreatedEvent::class => ['onAuthenticationTokenCreated', 10],
];
}

public function onInteractiveLogin(InteractiveLoginEvent $event): void
public function onAuthenticationTokenCreated(AuthenticationTokenCreatedEvent $event): void
{
$tokenUser = $event->getAuthenticationToken()->getUser();
$token = $event->getAuthenticatedToken();
$tokenUser = $token->getUser();
if (!$tokenUser instanceof InMemoryUser) {
return;
}
$userIdentifier = $event->getAuthenticationToken()->getUserIdentifier();
$userIdentifier = $token->getUserIdentifier();
$ibexaUser = null;
if (array_key_exists($userIdentifier, $this->userMap)) {
$ibexaUser = $this->userService->loadUserByLogin($this->userMap[$userIdentifier]);
Expand All @@ -43,7 +42,6 @@ public function onInteractiveLogin(InteractiveLoginEvent $event): void
$anonymousUserId = (int)$this->configResolver->getParameter('anonymous_user_id');
$ibexaUser = $this->userService->loadUser($anonymousUserId);
}
//$event->getAuthenticationToken()->setUser(new User($ibexaUser));
$event->getAuthenticationToken()->setUser(new UserWrapped($tokenUser, $ibexaUser));
$token->setUser(new UserWrapped($tokenUser, $ibexaUser));

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@konradoboza Did you mean something like this?:

Suggested change
$token->setUser(new UserWrapped($tokenUser, $ibexaUser));
$this->permissionResolver->setCurrentUserReference($ibexaUser);
$token->setUser(new UserWrapped($tokenUser, $ibexaUser));

(after injecting the PermissionResolver in constructor as well)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, I am not sure about the priority. It would be good to check if this comes before OnAuthenticationTokenCreatedRepositoryUserSubscriber so setting the repository user isn't needed here as it will be done anyway.

}
}
5 changes: 2 additions & 3 deletions deptrac.baseline.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,8 @@ deptrac:
App\EventListener\TextAnchorMenuTabListener:
- Ibexa\AdminUi\Menu\ContentEditAnchorMenuBuilder
- Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent
App\EventSubscriber\AuthenticationTokenCreatedSubscriber:
- Ibexa\Core\MVC\Symfony\Security\UserWrapped
Comment thread
adriendupuis marked this conversation as resolved.
App\EventSubscriber\BreadcrumbsMenuSubscriber:
- Ibexa\Bundle\Storefront\Menu\Builder\BreadcrumbsMenuBuilder
App\EventSubscriber\FormFieldDefinitionSubscriber:
Expand All @@ -128,9 +130,6 @@ deptrac:
- Ibexa\FormBuilder\Event\FormEvents
App\EventSubscriber\HelpMenuSubscriber:
- Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent
App\EventSubscriber\InteractiveLoginSubscriber:
#- Ibexa\Core\MVC\Symfony\Security\User
- Ibexa\Core\MVC\Symfony\Security\UserWrapped
App\EventSubscriber\MyMenuSubscriber:
- Ibexa\AdminUi\Menu\Event\ConfigureMenuEvent
- Ibexa\AdminUi\Menu\MainMenuBuilder
Expand Down
8 changes: 4 additions & 4 deletions docs/users/user_authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@

Depending on your context, you either want to create and return an Ibexa user, or return an existing user, even a generic one.

Whenever a user is matched, Symfony initiates a `SecurityEvents::INTERACTIVE_LOGIN` event.
Every service listening to this event receives an `InteractiveLoginEvent` object which contains the original security token (that holds the matched user) and the request.
Whenever a user is matched and authenticated, Symfony initiates an `AuthenticationTokenCreatedEvent`.

Check notice on line 17 in docs/users/user_authentication.md

View workflow job for this annotation

GitHub Actions / vale

[vale] docs/users/user_authentication.md#L17

[Ibexa.Passive] Try to avoid passive tense, when possible.
Raw output
{"message": "[Ibexa.Passive] Try to avoid passive tense, when possible.", "location": {"path": "docs/users/user_authentication.md", "range": {"start": {"line": 17, "column": 17}}}, "severity": "INFO"}
Every service listening to this event receives an object which contains the original security token (that holds the matched user) and a [passport]([[= symfony_doc =]]/security/custom_authenticator.html#security-passports).

Then, it's up to a listener to retrieve an Ibexa user from the repository.

Expand All @@ -32,11 +32,11 @@
maps memory user to Ibexa repository user,
and [chains]([[= symfony_doc =]]/security/user_providers.html#chain-user-provider) with the Ibexa user provider to be able to use both:

Create as `src/EventSubscriber/InteractiveLoginSubscriber.php` subscribing to the `SecurityEvents::INTERACTIVE_LOGIN` event
Create as `src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php` subscribing to the `AuthenticationTokenCreatedEvent` event
and mapping when needed an in-memory authenticated user to an Ibexa user:

``` php
[[= include_file('code_samples/user_management/in_memory/src/EventSubscriber/InteractiveLoginSubscriber.php') =]]
[[= include_file('code_samples/user_management/in_memory/src/EventSubscriber/AuthenticationTokenCreatedSubscriber.php') =]]
```

In `config/packages/security.yaml`,
Expand Down
Loading