extracted interfaces for services, to aid in creating tests
This commit is contained in:
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
namespace App\Command;
|
||||
|
||||
use App\PersistCache;
|
||||
use App\Service\BackupCodeManager;
|
||||
use App\Service\BackupCodeInterface;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Symfony\Component\Console\Command\Command;
|
||||
use Symfony\Component\Console\Input\InputArgument;
|
||||
@@ -15,8 +15,8 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
* usage: php bin/console app:generate-backup-codes [count] */
|
||||
final class GenerateBackupCodesCommand extends Command {
|
||||
public function __construct(
|
||||
private readonly BackupCodeManager $manager,
|
||||
private readonly PersistCache $persistCache,
|
||||
private readonly BackupCodeInterface $manager,
|
||||
private readonly PersistCache $persistCache,
|
||||
) {
|
||||
parent::__construct();
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace App\Listener;
|
||||
|
||||
use App\Service\DomainManager;
|
||||
use App\Service\DomainInterface;
|
||||
use App\Trait\CookieNameTrait;
|
||||
use App\Trait\HasLoggerTrait;
|
||||
use App\Trait\StringTrait;
|
||||
@@ -20,7 +20,7 @@ final readonly class AcceptListener {
|
||||
|
||||
public function __construct(
|
||||
private CacheItemPoolInterface $sessionCache,
|
||||
private DomainManager $domainManager,
|
||||
private DomainInterface $domainManager,
|
||||
) {}
|
||||
|
||||
/** @throws InvalidArgumentException */
|
||||
|
||||
@@ -4,7 +4,7 @@ declare(strict_types=1);
|
||||
namespace App\Listener;
|
||||
|
||||
use App\ConfigBag;
|
||||
use App\Service\DomainManager;
|
||||
use App\Service\DomainInterface;
|
||||
use App\Trait\CookieNameTrait;
|
||||
use App\Trait\HasLoggerTrait;
|
||||
use App\Trait\MakeNonceTrait;
|
||||
@@ -24,9 +24,9 @@ final readonly class InterceptListener {
|
||||
use MakeNonceTrait;
|
||||
|
||||
public function __construct(
|
||||
private ConfigBag $config,
|
||||
private DomainManager $domainManager,
|
||||
private Environment $twig,
|
||||
private ConfigBag $config,
|
||||
private DomainInterface $domainManager,
|
||||
private Environment $twig,
|
||||
) {}
|
||||
|
||||
/** @throws InvalidArgumentException|RuntimeError|SyntaxError|LoaderError */
|
||||
|
||||
@@ -5,8 +5,8 @@ namespace App\Listener;
|
||||
|
||||
use App\ConfigBag;
|
||||
use App\Data\Payload;
|
||||
use App\Service\DomainManager;
|
||||
use App\Service\LoginManager;
|
||||
use App\Service\DomainInterface;
|
||||
use App\Service\LoginInterface;
|
||||
use App\Trait\CookieNameTrait;
|
||||
use App\Trait\HasLoggerTrait;
|
||||
use App\Trait\MakeNonceTrait;
|
||||
@@ -34,8 +34,8 @@ final readonly class LoginListener {
|
||||
public function __construct(
|
||||
private Environment $twig,
|
||||
#[Target('login_limiter')] RateLimiterFactoryInterface $rateLimiter,
|
||||
private DomainManager $domainManager,
|
||||
private LoginManager $loginManager,
|
||||
private DomainInterface $domainManager,
|
||||
private LoginInterface $loginManager,
|
||||
private ConfigBag $config,
|
||||
) {
|
||||
$this->rateLimiter = $rateLimiter;
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
|
||||
use Exception;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
|
||||
/** backup-codes are case‑insensitive alphanumeric strings
|
||||
* they are single-use and marked as used after successful authentication */
|
||||
interface BackupCodeInterface {
|
||||
/** generate a set of backup-codes and return them
|
||||
* @param int $count Number of codes to generate
|
||||
* @return string[] Generated backup codes
|
||||
* @throws InvalidArgumentException|Exception */
|
||||
public function generate(int $count = 0): array;
|
||||
|
||||
/** @throws InvalidArgumentException */
|
||||
public function expire(): void;
|
||||
|
||||
/** check if backup-code is valid and mark it as used
|
||||
* @param string $code Code supplied by the client
|
||||
* @return bool true if the code is valid and unused
|
||||
* @throws InvalidArgumentException */
|
||||
public function verifyAndConsume(string $code): bool;
|
||||
}
|
||||
@@ -13,9 +13,8 @@ use Psr\Cache\InvalidArgumentException;
|
||||
use App\Trait\GetTotpTrait;
|
||||
|
||||
/** backup-codes are case‑insensitive alphanumeric strings
|
||||
* they are single-use and marked as used after successful authentication
|
||||
*/
|
||||
final readonly class BackupCodeManager {
|
||||
* they are single-use and marked as used after successful authentication */
|
||||
final readonly class BackupCodeManager implements BackupCodeInterface {
|
||||
use GetTotpTrait;
|
||||
use HasLoggerTrait;
|
||||
use StringTrait;
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
interface DomainInterface {
|
||||
/** IE: "auth.example.com" or null if not using a separate subdomain
|
||||
* @return ?string Returns auth subdomain if configured, otherwise null */
|
||||
public function getAuthSubdomain(): ?string;
|
||||
|
||||
/** check if given url is an acceptable url for redirection
|
||||
* @param string $url Where we are thinking of sending the user
|
||||
* @return bool Returns true if it is acceptable to send the user there */
|
||||
public function validReturn(string $url): bool;
|
||||
|
||||
/** check if host-base matches auth-base
|
||||
* @param string $host
|
||||
* @return bool returns true if and only if host matches base domain of auth */
|
||||
public function matchesAuth(string $host): bool;
|
||||
|
||||
/** IE: "example.com" if central auth is something like "auth.example.com"
|
||||
* @return string|null returns base domain if we are doing central auth */
|
||||
public function authBase(): ?string;
|
||||
}
|
||||
@@ -5,7 +5,7 @@ namespace App\Service;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
final readonly class DomainManager {
|
||||
final readonly class DomainManager implements DomainInterface {
|
||||
/* top-level-domains which are known to have multiple parts */
|
||||
private const array TLD = [
|
||||
'ai' => ['com','net','off','org'],
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace App\Service;
|
||||
|
||||
use App\Data\Payload;
|
||||
use Psr\Cache\InvalidArgumentException;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
|
||||
interface LoginInterface {
|
||||
/** @throws InvalidArgumentException */
|
||||
public function checkToken(Payload $payload, Request $request): ?Response;
|
||||
}
|
||||
@@ -18,7 +18,7 @@ use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Symfony\Component\Uid\Ulid;
|
||||
|
||||
final readonly class LoginManager {
|
||||
final readonly class LoginManager implements LoginInterface {
|
||||
use CookieNameTrait;
|
||||
use GetTotpTrait;
|
||||
use MakeNonceTrait;
|
||||
@@ -29,8 +29,8 @@ final readonly class LoginManager {
|
||||
/** @throws InvalidArgumentException */
|
||||
public function __construct(
|
||||
CacheItemPoolInterface $sessionCache,
|
||||
private BackupCodeManager $backupCodeManager,
|
||||
private DomainManager $domainManager,
|
||||
private BackupCodeInterface $backupCodeManager,
|
||||
private DomainInterface $domainManager,
|
||||
) {
|
||||
$this->sessionCache = new MonitorCacheKeys($sessionCache);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user