Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3c1253ee45 | ||
|
|
70bf811b1d | ||
|
|
3269151e9b | ||
|
|
1da2188bdf | ||
|
|
7cf7e04d17 |
@@ -0,0 +1,34 @@
|
||||
name: Push Develop
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- 'main'
|
||||
- 'develop'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
${{ vars.DOCKERHUB_TARGET }}:develop
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
name: Push Docker
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*.*.*'
|
||||
|
||||
jobs:
|
||||
docker:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to Docker Hub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Build image
|
||||
uses: docker/build-push-action@v5
|
||||
with:
|
||||
context: .
|
||||
push: true
|
||||
platforms: linux/amd64,linux/arm64
|
||||
tags: |
|
||||
${{ vars.DOCKERHUB_TARGET }}:latest
|
||||
${{ vars.DOCKERHUB_TARGET }}:${{ github.ref_name }}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Sync GitHub
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- '**'
|
||||
|
||||
jobs:
|
||||
sync:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Configure Git
|
||||
run: |
|
||||
git config --global user.name "Andrew Sync"
|
||||
git config --global user.email "sync@digitaladapt.com"
|
||||
|
||||
- name: Add GitHub Remote
|
||||
env:
|
||||
SYNC_TOKEN: ${{ secrets.SYNC_GITHUB_TOKEN }}
|
||||
SYNC_TARGET: ${{ vars.SYNC_GITHUB_TARGET }}
|
||||
run: |
|
||||
git remote add github "https://digitaladapt:${SYNC_TOKEN}@github.com/$SYNC_TARGET"
|
||||
|
||||
- name: Push Current Branch
|
||||
run: |
|
||||
git push github HEAD:${GITHUB_REF_NAME}
|
||||
|
||||
- name: Push Tags
|
||||
run: |
|
||||
git push github --tags
|
||||
|
||||
@@ -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