Skip to content

Instantly share code, notes, and snippets.

@Majkl578
Last active May 10, 2017 17:07
Show Gist options
  • Save Majkl578/6882b5bf59075e9f8ebc8af1a1912a84 to your computer and use it in GitHub Desktop.
Save Majkl578/6882b5bf59075e9f8ebc8af1a1912a84 to your computer and use it in GitHub Desktop.
Composite authenticator for Nette (proof of concept, no tests, just an idea)
<?php
declare(strict_types=1);
use Nette\Security\AuthenticationException;
use Nette\Security\IIdentity;
class CompositeAuthenticator implements CompositeAuthenticatorInterface
{
public const TYPE_KEY = 'type';
/** @var SpecializedAuthenticatorInterface[] */
private $authenticators;
public function addAuthenticator(SpecializedAuthenticatorInterface $authenticator) : void
{
$this->authenticators[] = $authenticator;
}
/**
* @param string[] $credentials
*/
public function authenticate(array $credentials) : IIdentity
{
assert(isset($credentials[self::TYPE_KEY]));
foreach ($this->authenticators as $authenticator) {
if (!$authenticator->supports($credentials[self::TYPE_KEY])) {
continue;
}
unset($credentials[self::TYPE_KEY]);
return $authenticator->authenticate($credentials);
}
throw new AuthenticationException(sprintf('No matching authenticator could handle type "%s".', $credentials[self::TYPE_KEY]));
}
}
<?php
declare(strict_types=1);
use Nette\Security\IAuthenticator;
interface CompositeAuthenticatorInterface extends IAuthenticator
{
}
<?php
declare(strict_types=1);
use Nette\Security\IIdentity;
class EmailAndPasswordAuthenticator implements SpecializedAuthenticatorInterface
{
private const NAME = 'emailAndPassword';
public function authenticate(array $credentials) : IIdentity
{
// ...
}
public function supports(string $type) : bool
{
return $type === self::NAME;
}
}
<?php
declare(strict_types=1);
use Nette\Security\IIdentity;
class RandomLuckAuthenticator implements SpecializedAuthenticatorInterface
{
private const NAME = 'randomLuck';
public function authenticate(array $credentials) : IIdentity
{
if (random_int(0, 999999) !== 0) {
throw new NoLuckException(); // extends AuthenticationException
}
// ...
}
public function supports(string $type) : bool
{
return $type === self::NAME;
}
}
<?php
declare(strict_types=1);
use Nette\Security\IAuthenticator;
use Nette\Security\IIdentity;
interface SpecializedAuthenticatorInterface extends IAuthenticator
{
public function supports(string $type) : bool;
}
<?php
declare(strict_types=1);
// initialize
$authenticator = new CompositeAuthenticator();
$authenticator->addAuthenticator(new EmailAndPasswordAuthenticator());
$authenticator->addAuthenticator(new RandomLuckAuthenticator());
// execute
try {
$identity = $autenticator->authenticate(['type' => 'randomLuck', 'name' => 'luckyGansta']);
echo 'Authenticated!', PHP_EOL;
} catch (AuthenticationException $e) {
echo 'Could not authenticate. :(', PHP_EOL;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment