Skip to content

Commit

Permalink
nette/security 3.16
Browse files Browse the repository at this point in the history
- removed the whole `DoctrineIdentity` namespace
- added `IdentityHandler` in `Authentication` namespace
  • Loading branch information
tg666 committed Jan 6, 2023
1 parent 1d97670 commit d5f6bfe
Show file tree
Hide file tree
Showing 11 changed files with 119 additions and 478 deletions.
64 changes: 15 additions & 49 deletions src/Authentication/Authenticator/Authenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,42 +4,26 @@

namespace SixtyEightPublishers\User\Authentication\Authenticator;

use Nette\SmartObject;
use Nette\Security\IIdentity;
use Nette\Security\IAuthenticator;
use Nette\Security\IdentityHandler;
use Nette\Security\Authenticator as AuthenticatorInterface;
use Doctrine\ORM\NonUniqueResultException;
use Nette\Security\AuthenticationException;
use Doctrine\DBAL\Exception as DBALException;
use SixtyEightPublishers\User\Authentication\Entity\UserInterface;
use SixtyEightPublishers\DoctrineQueryObjects\ExecutableQueryObjectFactoryInterface;
use SixtyEightPublishers\User\Authentication\Query\AuthenticatorQueryObjectFactoryInterface;

final class Authenticator implements IAuthenticator
final class Authenticator implements AuthenticatorInterface, IdentityHandler
{
use SmartObject;
public function __construct(
private readonly ExecutableQueryObjectFactoryInterface $executableQueryObjectFactory,
private readonly AuthenticatorQueryObjectFactoryInterface $authenticatorQueryFactory,
private readonly IdentityHandler $identityHandler,
) {}

/** @var \SixtyEightPublishers\DoctrineQueryObjects\ExecutableQueryObjectFactoryInterface */
private $executableQueryObjectFactory;

/** @var \SixtyEightPublishers\User\Authentication\Query\AuthenticatorQueryObjectFactoryInterface */
private $authenticatorQueryFactory;

/**
* @param \SixtyEightPublishers\DoctrineQueryObjects\ExecutableQueryObjectFactoryInterface $executableQueryObjectFactory
* @param \SixtyEightPublishers\User\Authentication\Query\AuthenticatorQueryObjectFactoryInterface $authenticatorQueryFactory
*/
public function __construct(ExecutableQueryObjectFactoryInterface $executableQueryObjectFactory, AuthenticatorQueryObjectFactoryInterface $authenticatorQueryFactory)
{
$this->executableQueryObjectFactory = $executableQueryObjectFactory;
$this->authenticatorQueryFactory = $authenticatorQueryFactory;
}

/**
* {@inheritdoc}
*/
public function authenticate(array $credentials): IIdentity
public function authenticate(string $username, string $password): IIdentity
{
[ $username, $password ] = $this->validateCredentials($credentials);
$user = $this->findUser($username);

if (null === $user->getPassword() || !$user->getPassword()->verify($password)) {
Expand All @@ -52,32 +36,14 @@ public function authenticate(array $credentials): IIdentity
return $user;
}

/**
* @param array $credentials
*
* @return array
* @throws \Nette\Security\AuthenticationException
*/
private function validateCredentials(array $credentials): array
public function sleepIdentity(IIdentity $identity): IIdentity
{
if (!isset($credentials[self::USERNAME])) {
throw new AuthenticationException(sprintf(
'Missing username field in credentials (key %s)',
self::USERNAME
), self::FAILURE);
}

if (!isset($credentials[self::PASSWORD])) {
throw new AuthenticationException(sprintf(
'Missing password field in credentials (key %s)',
self::PASSWORD
), self::FAILURE);
}
return $this->identityHandler->sleepIdentity($identity);
}

return [
(string) $credentials[self::USERNAME],
(string) $credentials[self::PASSWORD],
];
public function wakeupIdentity(IIdentity $identity): ?IIdentity
{
return $this->identityHandler->wakeupIdentity($identity);
}

/**
Expand Down
64 changes: 24 additions & 40 deletions src/Authentication/Authenticator/AuthenticatorMount.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,64 +4,59 @@

namespace SixtyEightPublishers\User\Authentication\Authenticator;

use Nette\SmartObject;
use Nette\Utils\Strings;
use Nette\Security\IIdentity;
use Nette\Security\IAuthenticator;
use Nette\Security\IdentityHandler;
use Nette\Security\Authenticator as AuthenticatorInterface;
use Nette\Security\AuthenticationException;
use SixtyEightPublishers\User\Common\Exception\InvalidArgumentException;

final class AuthenticatorMount implements IAuthenticator
final class AuthenticatorMount implements AuthenticatorInterface, IdentityHandler
{
use SmartObject;

public const SEPARATOR = '://';

/** @var \Nette\Security\IAuthenticator[] */
private $authenticators;
/** @var array<AuthenticatorInterface> */
private array $authenticators = [];

/**
* @param \Nette\Security\IAuthenticator[] $authenticators
* @param array<AuthenticatorInterface> $authenticators
*/
public function __construct(array $authenticators)
{
public function __construct(
array $authenticators,
private readonly IdentityHandler $identityHandler
) {
foreach ($authenticators as $name => $authenticator) {
$this->addAuthenticator((string) $name, $authenticator);
}
}

/**
* {@inheritdoc}
*/
public function authenticate(array $credentials): IIdentity
public function authenticate(string $username, string $password): IIdentity
{
if (!isset($credentials[self::USERNAME])) {
throw new AuthenticationException(sprintf(
'Missing username field in credentials (key %s)',
self::USERNAME
), self::FAILURE);
}

[ $prefix, $username ] = $this->getPrefixAndUsername($credentials[self::USERNAME]);
[ $prefix, $username ] = $this->getPrefixAndUsername($username);

try {
$authenticator = $this->getAuthenticator($prefix);
} catch (InvalidArgumentException $e) {
throw new AuthenticationException($e->getMessage(), self::FAILURE, $e);
}

$credentials[self::USERNAME] = $username;
return $authenticator->authenticate($username, $password);
}

return $authenticator->authenticate($credentials);
public function sleepIdentity(IIdentity $identity): IIdentity
{
return $this->identityHandler->sleepIdentity($identity);
}

public function wakeupIdentity(IIdentity $identity): ?IIdentity
{
return $this->identityHandler->wakeupIdentity($identity);
}

/**
* @param string $name
*
* @return \Nette\Security\IAuthenticator
* @throws \SixtyEightPublishers\User\Common\Exception\InvalidArgumentException
*/
public function getAuthenticator(string $name): IAuthenticator
public function getAuthenticator(string $name): AuthenticatorInterface
{
if (!isset($this->authenticators[$name])) {
throw new InvalidArgumentException(sprintf(
Expand All @@ -73,22 +68,11 @@ public function getAuthenticator(string $name): IAuthenticator
return $this->authenticators[$name];
}

/**
* @param string $name
* @param \Nette\Security\IAuthenticator $authenticator
*
* @return void
*/
private function addAuthenticator(string $name, IAuthenticator $authenticator): void
private function addAuthenticator(string $name, AuthenticatorInterface $authenticator): void
{
$this->authenticators[$name] = $authenticator;
}

/**
* @param string $username
*
* @return array
*/
private function getPrefixAndUsername(string $username): array
{
if (Strings::contains($username, self::SEPARATOR)) {
Expand Down
10 changes: 9 additions & 1 deletion src/Authentication/DI/AuthenticationExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Nette\Schema\Schema;
use Nette\Security\IAuthenticator;
use Nette\DI\Definitions\Statement;
use Nette\DI\Definitions\Reference;
use SixtyEightPublishers\User\Common\DI\CommonExtension;
use SixtyEightPublishers\User\DI\AbstractCompilerExtensionPass;
use SixtyEightPublishers\User\Authentication\Entity\UserInterface;
Expand All @@ -18,6 +19,7 @@
use SixtyEightPublishers\User\Authentication\Control\SignIn\SignInControl;
use SixtyEightPublishers\User\Authentication\Csrf\CsrfTokenFactoryInterface;
use SixtyEightPublishers\User\Authentication\Query\AuthenticatorQueryObject;
use SixtyEightPublishers\User\Authentication\IdentityHandler\IdentityHandler;
use SixtyEightPublishers\DoctrineBridge\Bridge\Nette\DI\TargetEntityProviderInterface;
use SixtyEightPublishers\TranslationBridge\Bridge\Nette\DI\TranslationProviderInterface;
use SixtyEightPublishers\User\Authentication\Control\SignIn\SignInControlFactoryInterface;
Expand Down Expand Up @@ -72,9 +74,15 @@ public function loadConfiguration(): void
{
$builder = $this->getContainerBuilder();

$builder->addDefinition($this->prefix('identity_handler'))
->setType(IdentityHandler::class)
->setAutowired(false);

$builder->addDefinition($this->prefix('authenticator'))
->setType(IAuthenticator::class)
->setFactory($this->config->authenticator);
->setFactory($this->config->authenticator, [
'identityHandler' => new Reference($this->prefix('identity_handler')),
]);

if (isset($builder->getAliases()['nette.authenticator'])) {
$builder->removeAlias('nette.authenticator');
Expand Down
26 changes: 26 additions & 0 deletions src/Authentication/Event/IdentityNotFoundEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php

namespace SixtyEightPublishers\User\Authentication\Event;

use Nette\Security\IIdentity;
use Symfony\Contracts\EventDispatcher\Event;

final class IdentityNotFoundEvent extends Event
{
public const NAME = '68publishers.doctrine_identity.identity_not_found';

private IIdentity $identityReference;

/**
* @param \Nette\Security\IIdentity $identityReference
*/
public function __construct(IIdentity $identityReference)
{
$this->identityReference = $identityReference;
}

public function getIdentityReference(): IIdentity
{
return $this->identityReference;
}
}
45 changes: 45 additions & 0 deletions src/Authentication/IdentityHandler/IdentityHandler.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
<?php

namespace SixtyEightPublishers\User\Authentication\IdentityHandler;

use Nette\Security\IIdentity;
use Nette\Security\SimpleIdentity;
use Doctrine\ORM\EntityManagerInterface;
use SixtyEightPublishers\User\Common\Entity\UserInterface;
use Nette\Security\IdentityHandler as IdentityHandlerInterface;
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
use SixtyEightPublishers\User\Authentication\Event\IdentityNotFoundEvent;

final class IdentityHandler implements IdentityHandlerInterface
{
public function __construct(
private readonly EntityManagerInterface $em,
private readonly ?EventDispatcherInterface $eventDispatcher = null
) {}

public function sleepIdentity(IIdentity $identity): IIdentity
{
if ($identity instanceof UserInterface) {
$identity = new SimpleIdentity((string) $identity->getId(), $identity->getRoles(), []);
}

return $identity;
}

public function wakeupIdentity(IIdentity $identity): ?IIdentity
{
if ($identity instanceof UserInterface) {
return $identity;
}

$user = $this->em->find(UserInterface::class, $identity->getId());

if ($user instanceof UserInterface) {
return $user;
}

$this->eventDispatcher?->dispatch(new IdentityNotFoundEvent($identity));

return null;
}
}
1 change: 0 additions & 1 deletion src/DI/UserBundleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ public function __construct()
{
$this->extensions = [
'common' => new CommonExtension(),
'doctrine_identity' => new DoctrineIdentityExtension(),
'forgot_password' => new ForgotPasswordExtension(),
'authentication' => new AuthenticationExtension(),
];
Expand Down
82 changes: 0 additions & 82 deletions src/DoctrineIdentity/DI/DoctrineIdentityExtension.php

This file was deleted.

Loading

0 comments on commit d5f6bfe

Please sign in to comment.