Compare commits
2 Commits
v0.34.8
...
dev-config
| Author | SHA1 | Date | |
|---|---|---|---|
| 14739500f4 | |||
| 0aee4ae7df |
8
.env
8
.env
@@ -51,3 +51,11 @@ OIDC_CLIENT_ID="Enter your OIDC client id"
|
||||
OIDC_CLIENT_SECRET="Enter your OIDC client secret"
|
||||
OIDC_BYPASS_FORM_LOGIN=false
|
||||
###< drenso/symfony-oidc-bundle ###
|
||||
|
||||
|
||||
SMTP_HOST=
|
||||
SMTP_USER=
|
||||
SMTP_PASS=
|
||||
SMTP_PORT=
|
||||
SMTP_FROM=
|
||||
SMTP_FROM_NAME=""
|
||||
@@ -43,6 +43,7 @@
|
||||
"symfony/mailer": "7.3.*",
|
||||
"symfony/mercure-bundle": "^0.3.9",
|
||||
"symfony/messenger": "7.3.*",
|
||||
"symfony/monolog-bundle": "^3.10",
|
||||
"symfony/runtime": "7.3.*",
|
||||
"symfony/scheduler": "7.3.*",
|
||||
"symfony/security-bundle": "7.3.*",
|
||||
|
||||
264
composer.lock
generated
264
composer.lock
generated
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "0f98dada0a01d471cebf4eb1b51b9006",
|
||||
"content-hash": "cf9a5b3cdb6e21e270da6c4efee09005",
|
||||
"packages": [
|
||||
{
|
||||
"name": "1tomany/rich-bundle",
|
||||
@@ -2681,6 +2681,109 @@
|
||||
},
|
||||
"time": "2025-02-06T08:48:15+00:00"
|
||||
},
|
||||
{
|
||||
"name": "monolog/monolog",
|
||||
"version": "3.9.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Seldaek/monolog.git",
|
||||
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||
"reference": "10d85740180ecba7896c87e06a166e0c95a0e3b6",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": ">=8.1",
|
||||
"psr/log": "^2.0 || ^3.0"
|
||||
},
|
||||
"provide": {
|
||||
"psr/log-implementation": "3.0.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"aws/aws-sdk-php": "^3.0",
|
||||
"doctrine/couchdb": "~1.0@dev",
|
||||
"elasticsearch/elasticsearch": "^7 || ^8",
|
||||
"ext-json": "*",
|
||||
"graylog2/gelf-php": "^1.4.2 || ^2.0",
|
||||
"guzzlehttp/guzzle": "^7.4.5",
|
||||
"guzzlehttp/psr7": "^2.2",
|
||||
"mongodb/mongodb": "^1.8",
|
||||
"php-amqplib/php-amqplib": "~2.4 || ^3",
|
||||
"php-console/php-console": "^3.1.8",
|
||||
"phpstan/phpstan": "^2",
|
||||
"phpstan/phpstan-deprecation-rules": "^2",
|
||||
"phpstan/phpstan-strict-rules": "^2",
|
||||
"phpunit/phpunit": "^10.5.17 || ^11.0.7",
|
||||
"predis/predis": "^1.1 || ^2",
|
||||
"rollbar/rollbar": "^4.0",
|
||||
"ruflin/elastica": "^7 || ^8",
|
||||
"symfony/mailer": "^5.4 || ^6",
|
||||
"symfony/mime": "^5.4 || ^6"
|
||||
},
|
||||
"suggest": {
|
||||
"aws/aws-sdk-php": "Allow sending log messages to AWS services like DynamoDB",
|
||||
"doctrine/couchdb": "Allow sending log messages to a CouchDB server",
|
||||
"elasticsearch/elasticsearch": "Allow sending log messages to an Elasticsearch server via official client",
|
||||
"ext-amqp": "Allow sending log messages to an AMQP server (1.0+ required)",
|
||||
"ext-curl": "Required to send log messages using the IFTTTHandler, the LogglyHandler, the SendGridHandler, the SlackWebhookHandler or the TelegramBotHandler",
|
||||
"ext-mbstring": "Allow to work properly with unicode symbols",
|
||||
"ext-mongodb": "Allow sending log messages to a MongoDB server (via driver)",
|
||||
"ext-openssl": "Required to send log messages using SSL",
|
||||
"ext-sockets": "Allow sending log messages to a Syslog server (via UDP driver)",
|
||||
"graylog2/gelf-php": "Allow sending log messages to a GrayLog2 server",
|
||||
"mongodb/mongodb": "Allow sending log messages to a MongoDB server (via library)",
|
||||
"php-amqplib/php-amqplib": "Allow sending log messages to an AMQP server using php-amqplib",
|
||||
"rollbar/rollbar": "Allow sending log messages to Rollbar",
|
||||
"ruflin/elastica": "Allow sending log messages to an Elastic Search server"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-main": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Monolog\\": "src/Monolog"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Jordi Boggiano",
|
||||
"email": "j.boggiano@seld.be",
|
||||
"homepage": "https://seld.be"
|
||||
}
|
||||
],
|
||||
"description": "Sends your logs to files, sockets, inboxes, databases and various web services",
|
||||
"homepage": "https://github.com/Seldaek/monolog",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging",
|
||||
"psr-3"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/Seldaek/monolog/issues",
|
||||
"source": "https://github.com/Seldaek/monolog/tree/3.9.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://github.com/Seldaek",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/monolog/monolog",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-24T10:02:05+00:00"
|
||||
},
|
||||
{
|
||||
"name": "nesbot/carbon",
|
||||
"version": "3.10.0",
|
||||
@@ -7578,6 +7681,165 @@
|
||||
],
|
||||
"time": "2025-02-19T08:51:26+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/monolog-bridge",
|
||||
"version": "v7.3.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/monolog-bridge.git",
|
||||
"reference": "1b188c8abbbef25b111da878797514b7a8d33990"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/monolog-bridge/zipball/1b188c8abbbef25b111da878797514b7a8d33990",
|
||||
"reference": "1b188c8abbbef25b111da878797514b7a8d33990",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"monolog/monolog": "^3",
|
||||
"php": ">=8.2",
|
||||
"symfony/http-kernel": "^6.4|^7.0",
|
||||
"symfony/service-contracts": "^2.5|^3"
|
||||
},
|
||||
"conflict": {
|
||||
"symfony/console": "<6.4",
|
||||
"symfony/http-foundation": "<6.4",
|
||||
"symfony/security-core": "<6.4"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^6.4|^7.0",
|
||||
"symfony/http-client": "^6.4|^7.0",
|
||||
"symfony/mailer": "^6.4|^7.0",
|
||||
"symfony/messenger": "^6.4|^7.0",
|
||||
"symfony/mime": "^6.4|^7.0",
|
||||
"symfony/security-core": "^6.4|^7.0",
|
||||
"symfony/var-dumper": "^6.4|^7.0"
|
||||
},
|
||||
"type": "symfony-bridge",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bridge\\Monolog\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Provides integration for Monolog with various Symfony components",
|
||||
"homepage": "https://symfony.com",
|
||||
"support": {
|
||||
"source": "https://github.com/symfony/monolog-bridge/tree/v7.3.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2025-03-21T12:17:46+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/monolog-bundle",
|
||||
"version": "v3.10.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/symfony/monolog-bundle.git",
|
||||
"reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/symfony/monolog-bundle/zipball/414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
|
||||
"reference": "414f951743f4aa1fd0f5bf6a0e9c16af3fe7f181",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"monolog/monolog": "^1.25.1 || ^2.0 || ^3.0",
|
||||
"php": ">=7.2.5",
|
||||
"symfony/config": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/dependency-injection": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/http-kernel": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/monolog-bridge": "^5.4 || ^6.0 || ^7.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"symfony/console": "^5.4 || ^6.0 || ^7.0",
|
||||
"symfony/phpunit-bridge": "^6.3 || ^7.0",
|
||||
"symfony/yaml": "^5.4 || ^6.0 || ^7.0"
|
||||
},
|
||||
"type": "symfony-bundle",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "3.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Symfony\\Bundle\\MonologBundle\\": ""
|
||||
},
|
||||
"exclude-from-classmap": [
|
||||
"/Tests/"
|
||||
]
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Fabien Potencier",
|
||||
"email": "fabien@symfony.com"
|
||||
},
|
||||
{
|
||||
"name": "Symfony Community",
|
||||
"homepage": "https://symfony.com/contributors"
|
||||
}
|
||||
],
|
||||
"description": "Symfony MonologBundle",
|
||||
"homepage": "https://symfony.com",
|
||||
"keywords": [
|
||||
"log",
|
||||
"logging"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/symfony/monolog-bundle/issues",
|
||||
"source": "https://github.com/symfony/monolog-bundle/tree/v3.10.0"
|
||||
},
|
||||
"funding": [
|
||||
{
|
||||
"url": "https://symfony.com/sponsor",
|
||||
"type": "custom"
|
||||
},
|
||||
{
|
||||
"url": "https://github.com/fabpot",
|
||||
"type": "github"
|
||||
},
|
||||
{
|
||||
"url": "https://tidelift.com/funding/github/packagist/symfony/symfony",
|
||||
"type": "tidelift"
|
||||
}
|
||||
],
|
||||
"time": "2023-11-06T17:08:13+00:00"
|
||||
},
|
||||
{
|
||||
"name": "symfony/options-resolver",
|
||||
"version": "v7.3.0",
|
||||
|
||||
@@ -23,4 +23,5 @@ return [
|
||||
SymfonyCasts\Bundle\ResetPassword\SymfonyCastsResetPasswordBundle::class => ['all' => true],
|
||||
Drenso\OidcBundle\DrensoOidcBundle::class => ['all' => true],
|
||||
SpomkyLabs\PwaBundle\SpomkyLabsPwaBundle::class => ['all' => true],
|
||||
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
|
||||
];
|
||||
|
||||
78
config/packages/monolog.yaml
Normal file
78
config/packages/monolog.yaml
Normal file
@@ -0,0 +1,78 @@
|
||||
monolog:
|
||||
channels:
|
||||
- deprecation # Deprecations are logged in the dedicated "deprecation" channel when it exists
|
||||
- monitor
|
||||
|
||||
when@dev:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
channels: ["!event"]
|
||||
# uncomment to get logging in your browser
|
||||
# you may have to allow bigger header sizes in your Web server configuration
|
||||
#firephp:
|
||||
# type: firephp
|
||||
# level: info
|
||||
#chromephp:
|
||||
# type: chromephp
|
||||
# level: info
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine", "!console"]
|
||||
monitor:
|
||||
type: stream
|
||||
action_level: debug
|
||||
path: "%kernel.logs_dir%/monitors.log"
|
||||
channels: [monitor]
|
||||
|
||||
when@test:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
channels: ["!event"]
|
||||
nested:
|
||||
type: stream
|
||||
path: "%kernel.logs_dir%/%kernel.environment%.log"
|
||||
level: debug
|
||||
monitor:
|
||||
type: stream
|
||||
action_level: info
|
||||
path: "%kernel.logs_dir%/monitors.log"
|
||||
channels: [monitor]
|
||||
|
||||
when@prod:
|
||||
monolog:
|
||||
handlers:
|
||||
main:
|
||||
type: fingers_crossed
|
||||
action_level: error
|
||||
handler: nested
|
||||
excluded_http_codes: [404, 405]
|
||||
buffer_size: 50 # How many messages should be saved? Prevent memory leaks
|
||||
nested:
|
||||
type: stream
|
||||
path: php://stderr
|
||||
level: debug
|
||||
formatter: monolog.formatter.json
|
||||
console:
|
||||
type: console
|
||||
process_psr_3_messages: false
|
||||
channels: ["!event", "!doctrine"]
|
||||
deprecation:
|
||||
type: stream
|
||||
channels: [deprecation]
|
||||
path: php://stderr
|
||||
formatter: monolog.formatter.json
|
||||
monitor:
|
||||
type: stream
|
||||
action_level: info
|
||||
path: "%kernel.logs_dir%/monitors.log"
|
||||
channels: [monitor]
|
||||
@@ -6,6 +6,7 @@
|
||||
parameters:
|
||||
# App
|
||||
app.url: '%env(APP_URL)%'
|
||||
app.env: '%env(default:app.default.env:APP_ENV)%'
|
||||
app.version: '%env(default:app.default.version:APP_VERSION)%'
|
||||
|
||||
# Debrid Services
|
||||
@@ -32,6 +33,7 @@ parameters:
|
||||
app.cache.redis.host.default: 'redis://redis'
|
||||
|
||||
# Various configs
|
||||
app.default.env: 'prod'
|
||||
app.default.version: '0.dev'
|
||||
app.default.timezone: 'America/Chicago'
|
||||
|
||||
|
||||
105
src/Base/Config/AppConfig.php
Normal file
105
src/Base/Config/AppConfig.php
Normal file
@@ -0,0 +1,105 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Config;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
class AppConfig implements ConfigInterface
|
||||
{
|
||||
private array $messages = [];
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(param: 'app.env')]
|
||||
private readonly ?string $appEnv = null,
|
||||
|
||||
#[Autowire(param: 'app.url')]
|
||||
private readonly ?string $appUrl = null,
|
||||
|
||||
#[Autowire(param: 'app.debrid.real_debrid.key')]
|
||||
private readonly ?string $realDebridApiKey = null,
|
||||
|
||||
#[Autowire(param: 'app.meta_provider.tmdb.key')]
|
||||
private readonly ?string $tmdbApiKey = null,
|
||||
|
||||
#[Autowire(param: 'media.movies_path')]
|
||||
private readonly ?string $moviesPath = null,
|
||||
|
||||
#[Autowire(param: 'media.tvshows_path')]
|
||||
private readonly ?string $tvshowsPath = null,
|
||||
) {}
|
||||
|
||||
public function isValid(): bool
|
||||
{
|
||||
$valid = true;
|
||||
|
||||
if (false === $this->isVariableValid('APP_ENV', $this->appEnv)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid('APP_URL', $this->appUrl)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid('REAL_DEBRID_KEY', $this->realDebridApiKey)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid('TMDB_API', $this->tmdbApiKey)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid('MOVIES_PATH', $this->moviesPath)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid('TVSHOWS_PATH', $this->tvshowsPath)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
public function getMessages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
private function isVariableValid($key, $value): bool
|
||||
{
|
||||
if ("" === $value || null === $value) {
|
||||
$this->messages[] = "Your system is misconfigured. Please set the $key environment variable appropriately.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getAppEnv(): ?string
|
||||
{
|
||||
return $this->appEnv;
|
||||
}
|
||||
|
||||
public function getAppUrl(): ?string
|
||||
{
|
||||
return $this->appUrl;
|
||||
}
|
||||
|
||||
public function getRealDebridApiKey(): ?string
|
||||
{
|
||||
return $this->realDebridApiKey;
|
||||
}
|
||||
|
||||
public function getTmdbApiKey(): ?string
|
||||
{
|
||||
return $this->tmdbApiKey;
|
||||
}
|
||||
|
||||
public function getMoviesPath(): ?string
|
||||
{
|
||||
return $this->moviesPath;
|
||||
}
|
||||
|
||||
public function getTvshowsPath(): ?string
|
||||
{
|
||||
return $this->tvshowsPath;
|
||||
}
|
||||
}
|
||||
88
src/Base/Config/Auth/OidcConfig.php
Normal file
88
src/Base/Config/Auth/OidcConfig.php
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Config\Auth;
|
||||
|
||||
use App\Base\Config\ConfigInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
class OidcConfig implements ConfigInterface
|
||||
{
|
||||
private array $messages = [];
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(param: 'auth.method')]
|
||||
private readonly ?string $authMethod = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.well_known_url')]
|
||||
private readonly ?string $wellKnownUrl = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.client_id')]
|
||||
private readonly ?string $clientId = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.client_secret')]
|
||||
private readonly ?string $clientSecret = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.bypass_form_login')]
|
||||
private readonly ?bool $bypassFormLogin = null,
|
||||
) {}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return "oidc" === strtolower($this->authMethod);
|
||||
}
|
||||
|
||||
public function isValid(): bool
|
||||
{
|
||||
$valid = true;
|
||||
|
||||
if (true === $this->isEnabled()) {
|
||||
if (false === $this->isVariableValid("OIDC_CLIENT_ID", $this->clientId)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid("OIDC_CLIENT_SECRET", $this->clientSecret)) {
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->isVariableValid("OIDC_WELL_KNOWN_URL", $this->wellKnownUrl)) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
public function getWellKnownUrl(): ?string
|
||||
{
|
||||
return $this->wellKnownUrl;
|
||||
}
|
||||
|
||||
public function getClientId(): ?string
|
||||
{
|
||||
return $this->clientId;
|
||||
}
|
||||
|
||||
public function getClientSecret(): ?string
|
||||
{
|
||||
return $this->clientSecret;
|
||||
}
|
||||
|
||||
public function getBypassFormLogin(): ?bool
|
||||
{
|
||||
return $this->bypassFormLogin;
|
||||
}
|
||||
|
||||
public function getMessages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
private function isVariableValid(string $key, mixed $value): bool
|
||||
{
|
||||
if ("" === $value || null === $value) {
|
||||
$this->messages[] = "Your OIDC is misconfigured. Please set the $key environment variable to the required value.";
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
62
src/Base/Config/AuthConfig.php
Normal file
62
src/Base/Config/AuthConfig.php
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Config;
|
||||
|
||||
use App\Base\Config\Auth\OidcConfig;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
class AuthConfig implements ConfigInterface
|
||||
{
|
||||
const AUTH_METHODS = ['form_login', 'oidc'];
|
||||
|
||||
private array $messages = [];
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(param: 'auth.method')]
|
||||
private readonly ?string $authMethod,
|
||||
private readonly OidcConfig $oidcConfig,
|
||||
) {}
|
||||
|
||||
public function isMethod(string $method): bool
|
||||
{
|
||||
return $this->getAuthMethod() === strtolower($method);
|
||||
}
|
||||
|
||||
public function getAuthMethod(): string
|
||||
{
|
||||
return strtolower($this->authMethod);
|
||||
}
|
||||
|
||||
public function getOidcConfig(): OidcConfig
|
||||
{
|
||||
return $this->oidcConfig;
|
||||
}
|
||||
|
||||
public function isValid(): bool
|
||||
{
|
||||
$valid = true;
|
||||
if (null === $this->getAuthMethod() || "" === $this->getAuthMethod()) {
|
||||
$this->messages[] = "Your auth method is missing. Please set the AUTH_METHOD environment variable to your desired value. Valid options: [form_login, oidc].";
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!in_array($this->getAuthMethod(), self::AUTH_METHODS, true)) {
|
||||
$this->messages[] = "Your auth method is incorrect. Please set the AUTH_METHOD environment variable to your desired value. Valid options: [form_login, oidc].";
|
||||
return false;
|
||||
}
|
||||
|
||||
if ("oidc" === $this->getAuthMethod()) {
|
||||
if (false === $this->oidcConfig->isValid()) {
|
||||
$this->messages += $this->oidcConfig->getMessages();
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
public function getMessages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
}
|
||||
12
src/Base/Config/ConfigInterface.php
Normal file
12
src/Base/Config/ConfigInterface.php
Normal file
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Config;
|
||||
|
||||
interface ConfigInterface
|
||||
{
|
||||
/** Validates the config values are present and as expected */
|
||||
public function isValid(): bool;
|
||||
|
||||
/** Holds the error messages so they can be logged */
|
||||
public function getMessages(): array;
|
||||
}
|
||||
113
src/Base/Config/SmtpConfig.php
Normal file
113
src/Base/Config/SmtpConfig.php
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Config;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
|
||||
class SmtpConfig implements ConfigInterface
|
||||
{
|
||||
private array $messages = [];
|
||||
|
||||
/*
|
||||
* SMTP is considered enabled if any of
|
||||
* the parameters are set. If none are set,
|
||||
* then the User must not need it.
|
||||
*/
|
||||
private bool $isEnabled = false;
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(env: 'SMTP_HOST')]
|
||||
private readonly ?string $smtpHost,
|
||||
#[Autowire(env: 'SMTP_USER')]
|
||||
private readonly ?string $smtpUser,
|
||||
#[Autowire(env: 'SMTP_PASS')]
|
||||
private readonly ?string $smtpPass,
|
||||
#[Autowire(env: 'SMTP_PORT')]
|
||||
private readonly ?string $smtpPort,
|
||||
#[Autowire(env: 'SMTP_FROM')]
|
||||
private readonly ?string $smtpFrom,
|
||||
#[Autowire(env: 'SMTP_FROM_NAME')]
|
||||
private readonly ?string $smtpFromName,
|
||||
) {
|
||||
foreach (func_get_args() as $key => $value) {
|
||||
if ("" !== $value && $value !== null) {
|
||||
$this->isEnabled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public function isEnabled(): bool
|
||||
{
|
||||
return $this->isEnabled;
|
||||
}
|
||||
|
||||
public function getMessages(): array
|
||||
{
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
public function isValid(): bool
|
||||
{
|
||||
if (false === $this->isEnabled) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$valid = true;
|
||||
|
||||
$params = [
|
||||
'SMTP_HOST' => $this->smtpHost,
|
||||
'SMTP_USER' => $this->smtpUser,
|
||||
'SMTP_PASS' => $this->smtpPass,
|
||||
'SMTP_PORT' => $this->smtpPort,
|
||||
'SMTP_FROM' => $this->smtpFrom,
|
||||
'SMTP_FROM_NAME' => $this->smtpFromName,
|
||||
];
|
||||
|
||||
foreach ($params as $key => $value) {
|
||||
if (false === $this->isVariableValid($key, $value)) {
|
||||
$valid = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
private function isVariableValid($key, $value): bool
|
||||
{
|
||||
if ("" === $value || null === $value) {
|
||||
$this->messages[] = "Your SMTP is misconfigured. Please set the $key environment variable appropriately.";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getSmtpHost(): ?string
|
||||
{
|
||||
return $this->smtpHost;
|
||||
}
|
||||
|
||||
public function getSmtpUser(): ?string
|
||||
{
|
||||
return $this->smtpUser;
|
||||
}
|
||||
|
||||
public function getSmtpPass(): ?string
|
||||
{
|
||||
return $this->smtpPass;
|
||||
}
|
||||
|
||||
public function getSmtpPort(): ?string
|
||||
{
|
||||
return $this->smtpPort;
|
||||
}
|
||||
|
||||
public function getSmtpFrom(): ?string
|
||||
{
|
||||
return $this->smtpFrom;
|
||||
}
|
||||
|
||||
public function getSmtpFromName(): ?string
|
||||
{
|
||||
return $this->smtpFromName;
|
||||
}
|
||||
}
|
||||
@@ -2,58 +2,60 @@
|
||||
|
||||
namespace App\Base;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Attribute\Autowire;
|
||||
use App\Base\Config\AppConfig;
|
||||
use App\Base\Config\AuthConfig;
|
||||
use App\Base\Config\SmtpConfig;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Contracts\Cache\TagAwareCacheInterface;
|
||||
|
||||
final class ConfigResolver
|
||||
{
|
||||
private array $messages = [];
|
||||
|
||||
public function __construct(
|
||||
#[Autowire(param: 'app.url')]
|
||||
private readonly ?string $appUrl = null,
|
||||
|
||||
#[Autowire(param: 'app.debrid.real_debrid.key')]
|
||||
private readonly ?string $realDebridApiKey = null,
|
||||
|
||||
#[Autowire(param: 'app.meta_provider.tmdb.key')]
|
||||
private readonly ?string $tmdbApiKey = null,
|
||||
|
||||
#[Autowire(param: 'media.movies_path')]
|
||||
private readonly ?string $moviesPath = null,
|
||||
|
||||
#[Autowire(param: 'media.tvshows.path')]
|
||||
private readonly ?string $tvshowsPath = null,
|
||||
|
||||
#[Autowire(param: 'auth.method')]
|
||||
private readonly ?string $authMethod = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.well_known_url')]
|
||||
private readonly ?string $authOidcWellKnownUrl = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.client_id')]
|
||||
private readonly ?string $authOidcClientId = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.client_secret')]
|
||||
private readonly ?string $authOidcClientSecret = null,
|
||||
|
||||
#[Autowire(param: 'auth.oidc.bypass_form_login')]
|
||||
private ?bool $authOidcBypassFormLogin = null,
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly TagAwareCacheInterface $cache,
|
||||
private readonly AuthConfig $authConfig,
|
||||
private readonly SmtpConfig $smtpConfig,
|
||||
private readonly AppConfig $appConfig,
|
||||
) {}
|
||||
|
||||
public function validate(): bool
|
||||
{
|
||||
if ("prod" === strtolower($this->appConfig->getAppEnv())) {
|
||||
return $this->cache->get('app.valid_config', function () {
|
||||
return $this->doValidate();
|
||||
});
|
||||
} else {
|
||||
return $this->doValidate();
|
||||
}
|
||||
}
|
||||
|
||||
private function doValidate(): bool
|
||||
{
|
||||
$valid = true;
|
||||
|
||||
if (null === $this->realDebridApiKey || "" === $this->realDebridApiKey) {
|
||||
$this->messages[] = "Your Real Debrid API key is missing. Please set it to the 'REAL_DEBRID_KEY' environment variable.";
|
||||
if (false === $this->appConfig->isValid()) {
|
||||
$this->messages += $this->appConfig->getMessages();
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (null === $this->tmdbApiKey || "" === $this->tmdbApiKey) {
|
||||
$this->messages[] = "Your TMDB API key is missing. Please set it to the 'TMDB_API' environment variable.";
|
||||
if (false === $this->authConfig->isValid()) {
|
||||
$this->messages += $this->authConfig->getMessages();
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $this->smtpConfig->isValid()) {
|
||||
$this->messages += $this->smtpConfig->getMessages();
|
||||
$valid = false;
|
||||
}
|
||||
|
||||
if (false === $valid) {
|
||||
foreach ($this->messages as $message) {
|
||||
$this->logger->error('> [ConfigResolver] ' . $message);
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
@@ -62,34 +64,18 @@ final class ConfigResolver
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
public function getAuthConfig(): AuthConfig
|
||||
{
|
||||
return $this->authConfig;
|
||||
}
|
||||
|
||||
public function authIs(string $method): bool
|
||||
{
|
||||
if (strtolower($method) === strtolower($this->getAuthMethod())) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $this->authConfig->isMethod($method);
|
||||
}
|
||||
|
||||
public function getAuthMethod(): string
|
||||
{
|
||||
return strtolower($this->authMethod);
|
||||
}
|
||||
|
||||
public function bypassFormLogin(): bool
|
||||
{
|
||||
return $this->authOidcBypassFormLogin;
|
||||
}
|
||||
|
||||
public function getAuthConfig(): array
|
||||
{
|
||||
return [
|
||||
'method' => $this->authMethod,
|
||||
'oidc' => [
|
||||
'well_known_url' => $this->authOidcWellKnownUrl,
|
||||
'client_id' => $this->authOidcClientId,
|
||||
'client_secret' => $this->authOidcClientSecret,
|
||||
'bypass_form_login' => $this->authOidcBypassFormLogin,
|
||||
]
|
||||
];
|
||||
return $this->authConfig->getAuthMethod();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
namespace App\Base\Framework\EventListener;
|
||||
|
||||
use App\Base\ConfigResolver;
|
||||
use App\Base\Service\Broadcaster;
|
||||
use Symfony\Component\EventDispatcher\Attribute\AsEventListener;
|
||||
use Symfony\Component\HttpKernel\Event\RequestEvent;
|
||||
|
||||
final class KernelRequestValidateConfig
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ConfigResolver $configResolver,
|
||||
private readonly Broadcaster $broadcaster,
|
||||
) {}
|
||||
|
||||
#[AsEventListener(event: 'kernel.request', priority: 20)]
|
||||
public function validateConfig(RequestEvent $event): void
|
||||
{
|
||||
if (false === $this->configResolver->validate()) {
|
||||
$this->broadcaster->systemAlert('Ruh-roh', 'It looks like your system is misconfigured. Please search the application logs for strings starting with "[error] > [ConfigResolver]" to find more information.');
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,8 @@ readonly class Broadcaster
|
||||
private Environment $renderer,
|
||||
private HubInterface $hub,
|
||||
private RequestStack $requestStack,
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
|
||||
public function alert(string $title, string $message, string $type = "success"): void
|
||||
{
|
||||
@@ -31,4 +32,18 @@ readonly class Broadcaster
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
}
|
||||
|
||||
public function systemAlert(string $title, string $message, string $type = "warning"): void
|
||||
{
|
||||
$update = new Update(
|
||||
'system_alerts',
|
||||
$this->renderer->render('broadcast/Alert.stream.html.twig', [
|
||||
'alert_id' => uniqid(),
|
||||
'title' => $title,
|
||||
'message' => $message,
|
||||
'type' => $type,
|
||||
])
|
||||
);
|
||||
$this->hub->publish($update);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace App\Monitor\Action\Handler;
|
||||
|
||||
use App\Download\Action\Command\DownloadMediaCommand;
|
||||
use App\Monitor\Action\Command\MonitorMovieCommand;
|
||||
use App\Monitor\Action\Result\MonitorMovieResult;
|
||||
use App\Monitor\Framework\Entity\Monitor;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use App\Monitor\Service\MonitorOptionEvaluator;
|
||||
use App\Torrentio\Action\Command\GetMovieOptionsCommand;
|
||||
use App\Torrentio\Action\Handler\GetMovieOptionsHandler;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
use OneToMany\RichBundle\Contract\HandlerInterface;
|
||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
|
||||
/** @implements HandlerInterface<MonitorMovieCommand> */
|
||||
readonly class MonitorMovieHandler implements HandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
private MonitorRepository $movieMonitorRepository,
|
||||
private GetMovieOptionsHandler $getMovieOptionsHandler,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private MessageBusInterface $bus,
|
||||
private LoggerInterface $logger,
|
||||
private Security $security,
|
||||
) {}
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
{
|
||||
$this->logger->info('> [MonitorMovieHandler] Executing MonitorMovieHandler');
|
||||
/** @var Monitor $monitor */
|
||||
$monitor = $this->movieMonitorRepository->find($command->movieMonitorId);
|
||||
$monitor->setStatus('In Progress');
|
||||
|
||||
$this->logger->info('> [MonitorMovieHandler] Searching for "' . $monitor->getTitle() . '" download options');
|
||||
$results = $this->getMovieOptionsHandler->handle(
|
||||
new GetMovieOptionsCommand($monitor->getTmdbId(), $monitor->getImdbId())
|
||||
);
|
||||
$this->logger->info('> [MonitorMovieHandler] Found ' . count($results->results) . ' download options');
|
||||
|
||||
$result = $this->monitorOptionEvaluator->evaluateOptions($monitor, $results->results);
|
||||
|
||||
if (null !== $result) {
|
||||
$this->logger->info('> [MonitorMovieHandler] 1 result found: dispatching DownloadMediaCommand for "' . $result->title . '"');
|
||||
$this->bus->dispatch(new DownloadMediaCommand(
|
||||
$result->url,
|
||||
$monitor->getTitle(),
|
||||
$result->filename,
|
||||
'movies',
|
||||
$monitor->getImdbId(),
|
||||
$monitor->getUser()->getId(),
|
||||
));
|
||||
$monitor->setStatus('Complete');
|
||||
$monitor->setDownloadedAt(new DateTimeIMmutable());
|
||||
} else {
|
||||
$monitor->setStatus('Active');
|
||||
}
|
||||
|
||||
$monitor->setLastSearch(new DateTimeImmutable());
|
||||
$monitor->incrementSearchCount();
|
||||
$this->entityManager->flush();
|
||||
|
||||
return new MonitorMovieResult(
|
||||
status: 'OK',
|
||||
result: [
|
||||
'monitor' => $monitor,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,6 @@ namespace App\Monitor\Action\Handler;
|
||||
use App\Base\Util\EpisodeId;
|
||||
use App\Download\Action\Command\DownloadMediaCommand;
|
||||
use App\Download\DownloadOptionEvaluator;
|
||||
use App\Download\Framework\Entity\Download;
|
||||
use App\Download\Framework\Repository\DownloadRepository;
|
||||
use App\Monitor\Action\Command\MonitorMovieCommand;
|
||||
use App\Monitor\Action\Result\MonitorTvEpisodeResult;
|
||||
@@ -16,7 +15,6 @@ use App\Torrentio\Action\Handler\GetTvShowOptionsHandler;
|
||||
use App\User\Dto\UserPreferencesFactory;
|
||||
use Carbon\Carbon;
|
||||
use DateTimeImmutable;
|
||||
use Doctrine\ORM\EntityManagerInterface;
|
||||
use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
use OneToMany\RichBundle\Contract\HandlerInterface;
|
||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
||||
@@ -29,7 +27,6 @@ readonly class MonitorTvEpisodeHandler implements HandlerInterface
|
||||
public function __construct(
|
||||
private GetTvShowOptionsHandler $getTvShowOptionsHandler,
|
||||
private DownloadOptionEvaluator $downloadOptionEvaluator,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private MessageBusInterface $bus,
|
||||
private LoggerInterface $logger,
|
||||
private MonitorRepository $monitorRepository,
|
||||
|
||||
@@ -18,19 +18,22 @@ use OneToMany\RichBundle\Contract\CommandInterface;
|
||||
use OneToMany\RichBundle\Contract\HandlerInterface;
|
||||
use OneToMany\RichBundle\Contract\ResultInterface;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Target;
|
||||
|
||||
/** @implements HandlerInterface<MonitorMovieCommand> */
|
||||
readonly class MonitorTvShowHandler implements HandlerInterface
|
||||
{
|
||||
public function __construct(
|
||||
#[Target('monitorLogger')]
|
||||
private LoggerInterface $logger,
|
||||
private MonitorRepository $monitorRepository,
|
||||
private EntityManagerInterface $entityManager,
|
||||
private MonitorTvEpisodeHandler $monitorTvEpisodeHandler,
|
||||
private MediaFiles $mediaFiles,
|
||||
private LoggerInterface $logger,
|
||||
private Tmdb $tmdb,
|
||||
) {}
|
||||
|
||||
|
||||
public function handle(CommandInterface $command): ResultInterface
|
||||
{
|
||||
$this->logger->info('> [MonitorTvShowHandler] Executing MonitorTvShowHandler');
|
||||
|
||||
@@ -9,6 +9,7 @@ use App\Monitor\Action\Command\MonitorTvShowCommand;
|
||||
use App\Monitor\Framework\Repository\MonitorRepository;
|
||||
use Carbon\Carbon;
|
||||
use Psr\Log\LoggerInterface;
|
||||
use Symfony\Component\DependencyInjection\Attribute\Target;
|
||||
use Symfony\Component\Messenger\MessageBusInterface;
|
||||
use Symfony\Component\Scheduler\Attribute\AsCronTask;
|
||||
|
||||
@@ -16,13 +17,14 @@ use Symfony\Component\Scheduler\Attribute\AsCronTask;
|
||||
class MonitorDispatcher
|
||||
{
|
||||
public function __construct(
|
||||
#[Target('monitorLogger')]
|
||||
private readonly LoggerInterface $logger,
|
||||
private readonly MonitorRepository $monitorRepository,
|
||||
private readonly MessageBusInterface $bus,
|
||||
) {}
|
||||
|
||||
public function __invoke() {
|
||||
$this->logger->info('[MonitorDispatcher] Executing MonitorDispatcher');
|
||||
$this->logger->info('[MonitorDispatcher] > Executing MonitorDispatcher');
|
||||
|
||||
$this->cleanupStuckMonitors();
|
||||
|
||||
@@ -34,15 +36,19 @@ class MonitorDispatcher
|
||||
];
|
||||
|
||||
$monitors = $this->monitorRepository->findBy(['status' => ['New', 'Active']]);
|
||||
$this->logger->info('[MonitorDispatcher] ' . count($monitors) . ' monitors found');
|
||||
|
||||
foreach ($monitors as $monitor) {
|
||||
$this->logger->info('[MonitorDispatcher] - Evaluating monitor ' . $monitor->getId() . ' for "' . $monitor->getTitle() . '"');
|
||||
$monitor->setStatus('In Progress');
|
||||
$this->monitorRepository->getEntityManager()->flush();
|
||||
|
||||
$command = $monitorHandlers[$monitor->getMonitorType()];
|
||||
$this->logger->info('[MonitorDispatcher] Dispatching ' . $command . ' for ' . $monitor->getTitle());
|
||||
$this->logger->info('[MonitorDispatcher] Dispatching ' . $command . ' for ' . $monitor->getTitle());
|
||||
$this->bus->dispatch(new $command($monitor->getId()));
|
||||
}
|
||||
|
||||
$this->logger->info('[MonitorDispatcher] < Complete');
|
||||
}
|
||||
|
||||
private function cleanupStuckMonitors(): void
|
||||
|
||||
@@ -22,7 +22,7 @@ class LoginController extends AbstractController
|
||||
return $this->redirectToRoute('app_getting_started');
|
||||
}
|
||||
|
||||
if ($config->authIs('oidc') && $config->bypassFormLogin()) {
|
||||
if ($config->authIs('oidc') && true === $config->getAuthConfig()->getOidcConfig()->getBypassFormLogin()) {
|
||||
return $this->redirectToRoute('app_login_oidc');
|
||||
}
|
||||
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
namespace App\User\Framework\Controller\Web;
|
||||
|
||||
use App\Base\ConfigResolver;
|
||||
use App\Base\Service\Broadcaster;
|
||||
use Drenso\OidcBundle\OidcClientInterface;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
@@ -15,13 +16,15 @@ class LoginOidcController extends AbstractController
|
||||
|
||||
public function __construct(
|
||||
private ConfigResolver $configResolver,
|
||||
private Broadcaster $broadcaster,
|
||||
) {}
|
||||
|
||||
#[Route('/login/oidc', name: 'app_login_oidc')]
|
||||
public function oidcStart(OidcClientInterface $oidcClient): RedirectResponse
|
||||
{
|
||||
if (false === $this->configResolver->authIs('oidc')) {
|
||||
throw new \Exception('You must configure the OIDC environment variables before logging in at this route.');
|
||||
$this->broadcaster->systemAlert('Your authentication must be set to "oidc" in order to login with OIDC.', 'warning');
|
||||
return $this->redirectToRoute('app_login');
|
||||
}
|
||||
|
||||
// Redirect to authorization @ OIDC provider
|
||||
|
||||
@@ -4,13 +4,9 @@ namespace App\User\Framework\Security;
|
||||
|
||||
use App\User\Framework\Entity\User;
|
||||
use App\User\Framework\Repository\UserRepository;
|
||||
use Drenso\OidcBundle\Exception\OidcException;
|
||||
use Drenso\OidcBundle\Model\OidcTokens;
|
||||
use Drenso\OidcBundle\Model\OidcUserData;
|
||||
use Drenso\OidcBundle\Security\UserProvider\OidcUserProviderInterface;
|
||||
use Symfony\Component\PasswordHasher\PasswordHasherInterface;
|
||||
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
|
||||
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
|
||||
use Symfony\Component\Security\Core\User\OidcUser;
|
||||
use Symfony\Component\Security\Core\User\UserInterface;
|
||||
|
||||
@@ -47,7 +43,7 @@ class OidcUserProvider implements OidcUserProviderInterface
|
||||
|
||||
public function supportsClass(string $class): bool
|
||||
{
|
||||
return User::class === $class || OidcUser::class === $class;
|
||||
return User::class === $class || OidcUser::class === $class || is_subclass_of($class, User::class);
|
||||
}
|
||||
|
||||
public function loadUserByIdentifier(string $identifier): UserInterface
|
||||
|
||||
12
symfony.lock
12
symfony.lock
@@ -217,6 +217,18 @@
|
||||
"config/packages/messenger.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/monolog-bundle": {
|
||||
"version": "3.10",
|
||||
"recipe": {
|
||||
"repo": "github.com/symfony/recipes",
|
||||
"branch": "main",
|
||||
"version": "3.7",
|
||||
"ref": "aff23899c4440dd995907613c1dd709b6f59503f"
|
||||
},
|
||||
"files": [
|
||||
"config/packages/monolog.yaml"
|
||||
]
|
||||
},
|
||||
"symfony/property-info": {
|
||||
"version": "7.3",
|
||||
"recipe": {
|
||||
|
||||
@@ -23,5 +23,17 @@
|
||||
<span class="text-sm">v{{ version }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div {{ turbo_stream_listen('system_alerts') }} class="fixed z-40 top-10 right-10">
|
||||
<div class="z-40">
|
||||
<ul id="alert_list" class="flex flex-col gap-2">
|
||||
{% for message in app.flashes('warning') %}
|
||||
<twig:Alert :title="'Warning'" :message="message" :alert_id="''" type="warning" data-controller="alert" />
|
||||
{% endfor %}
|
||||
{% for message in app.flashes('success') %}
|
||||
<twig:Alert :title="'Success'" :message="message" :alert_id="''" type="warning" data-controller="alert" />
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
|
||||
@@ -26,6 +26,18 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div {{ turbo_stream_listen('system_alerts') }} class="fixed z-40 top-10 right-10">
|
||||
<div class="z-40">
|
||||
<ul id="alert_list" class="flex flex-col gap-2">
|
||||
{% for message in app.flashes('system_warning') %}
|
||||
<twig:Alert :title="'Warning'" :message="message" :alert_id="''" type="warning" data-controller="alert" />
|
||||
{% endfor %}
|
||||
{% for message in app.flashes('system_success') %}
|
||||
<twig:Alert :title="'Success'" :message="message" :alert_id="''" type="warning" data-controller="alert" />
|
||||
{% endfor %}
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
<div {{ turbo_stream_listen(app.session.get('mercure_alert_topic')) }} class="fixed z-40 top-10 right-10">
|
||||
<div class="z-40">
|
||||
<ul id="alert_list" class="flex flex-col gap-2">
|
||||
|
||||
Reference in New Issue
Block a user