|
|
@@ -0,0 +1,135 @@
|
|
|
+<?php
|
|
|
+/*
|
|
|
+ * Copyright 2026 Alessandro Chiapparini <sprint_planer_web@chiapparini.org>
|
|
|
+ * SPDX-License-Identifier: Apache-2.0
|
|
|
+ *
|
|
|
+ * Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
+ * you may not use this file except in compliance with the License.
|
|
|
+ * See the LICENSE file in the project root for the full license text.
|
|
|
+ */
|
|
|
+
|
|
|
+declare(strict_types=1);
|
|
|
+
|
|
|
+namespace App\Tests\Auth;
|
|
|
+
|
|
|
+use App\Auth\OidcClient;
|
|
|
+use App\Tests\TestCase;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Pins the OIDC env-driven gating: `isConfigured()` is true only when every
|
|
|
+ * ENTRA_* + APP_BASE_URL var is set AND `OIDC_ENABLED` isn't explicitly false.
|
|
|
+ * The `OIDC_ENABLED=false` path is the dev/testing kill-switch that lets
|
|
|
+ * operators run on the LOCAL_ADMIN_* fallback alone without unsetting the
|
|
|
+ * Entra creds in .env.
|
|
|
+ */
|
|
|
+final class OidcClientTest extends TestCase
|
|
|
+{
|
|
|
+ /** @var array<string, string|false> */
|
|
|
+ private array $envBackup = [];
|
|
|
+
|
|
|
+ /** @var string[] */
|
|
|
+ private array $envKeys = [
|
|
|
+ 'ENTRA_TENANT_ID',
|
|
|
+ 'ENTRA_CLIENT_ID',
|
|
|
+ 'ENTRA_CLIENT_SECRET',
|
|
|
+ 'APP_BASE_URL',
|
|
|
+ 'OIDC_ENABLED',
|
|
|
+ ];
|
|
|
+
|
|
|
+ protected function setUp(): void
|
|
|
+ {
|
|
|
+ parent::setUp();
|
|
|
+ foreach ($this->envKeys as $k) {
|
|
|
+ $this->envBackup[$k] = getenv($k);
|
|
|
+ putenv($k);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ protected function tearDown(): void
|
|
|
+ {
|
|
|
+ foreach ($this->envKeys as $k) {
|
|
|
+ $prev = $this->envBackup[$k] ?? false;
|
|
|
+ if ($prev === false) {
|
|
|
+ putenv($k);
|
|
|
+ } else {
|
|
|
+ putenv("{$k}={$prev}");
|
|
|
+ }
|
|
|
+ }
|
|
|
+ parent::tearDown();
|
|
|
+ }
|
|
|
+
|
|
|
+ private function setEntraVars(): void
|
|
|
+ {
|
|
|
+ putenv('ENTRA_TENANT_ID=tenant-guid');
|
|
|
+ putenv('ENTRA_CLIENT_ID=client-guid');
|
|
|
+ putenv('ENTRA_CLIENT_SECRET=secret');
|
|
|
+ putenv('APP_BASE_URL=https://example.com');
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testNotConfiguredWithoutEntraVars(): void
|
|
|
+ {
|
|
|
+ self::assertFalse(OidcClient::isConfigured());
|
|
|
+ self::assertFalse(OidcClient::isExplicitlyDisabled());
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testConfiguredWhenAllEntraVarsSet(): void
|
|
|
+ {
|
|
|
+ $this->setEntraVars();
|
|
|
+ self::assertTrue(OidcClient::isConfigured());
|
|
|
+ self::assertFalse(OidcClient::isExplicitlyDisabled());
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testConfiguredStaysTrueWhenFlagBlankOrUnset(): void
|
|
|
+ {
|
|
|
+ $this->setEntraVars();
|
|
|
+ // Unset (default of putenv with no =).
|
|
|
+ putenv('OIDC_ENABLED');
|
|
|
+ self::assertTrue(OidcClient::isConfigured());
|
|
|
+ // Explicit blank.
|
|
|
+ putenv('OIDC_ENABLED=');
|
|
|
+ self::assertTrue(OidcClient::isConfigured());
|
|
|
+ self::assertFalse(OidcClient::isExplicitlyDisabled());
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testConfiguredStaysTrueWhenFlagAnyTruthyValue(): void
|
|
|
+ {
|
|
|
+ $this->setEntraVars();
|
|
|
+ foreach (['true', '1', 'yes', 'on', 'TRUE', 'enabled', 'whatever'] as $v) {
|
|
|
+ putenv("OIDC_ENABLED={$v}");
|
|
|
+ self::assertTrue(
|
|
|
+ OidcClient::isConfigured(),
|
|
|
+ "isConfigured() should be true with OIDC_ENABLED={$v}",
|
|
|
+ );
|
|
|
+ self::assertFalse(
|
|
|
+ OidcClient::isExplicitlyDisabled(),
|
|
|
+ "isExplicitlyDisabled() should be false with OIDC_ENABLED={$v}",
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testFalseyFlagDisablesOidcEvenWithEntraVarsSet(): void
|
|
|
+ {
|
|
|
+ $this->setEntraVars();
|
|
|
+ foreach (['false', '0', 'no', 'off', 'FALSE', 'No', ' off '] as $v) {
|
|
|
+ putenv("OIDC_ENABLED={$v}");
|
|
|
+ self::assertFalse(
|
|
|
+ OidcClient::isConfigured(),
|
|
|
+ "isConfigured() should be false with OIDC_ENABLED={$v}",
|
|
|
+ );
|
|
|
+ self::assertTrue(
|
|
|
+ OidcClient::isExplicitlyDisabled(),
|
|
|
+ "isExplicitlyDisabled() should be true with OIDC_ENABLED={$v}",
|
|
|
+ );
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ public function testFalseyFlagWithoutEntraVarsStillReportsDisabled(): void
|
|
|
+ {
|
|
|
+ // No ENTRA_*. Flag set false. isConfigured stays false (already was);
|
|
|
+ // isExplicitlyDisabled tells the operator-facing page which message
|
|
|
+ // to show ("disabled" vs. "not configured").
|
|
|
+ putenv('OIDC_ENABLED=false');
|
|
|
+ self::assertFalse(OidcClient::isConfigured());
|
|
|
+ self::assertTrue(OidcClient::isExplicitlyDisabled());
|
|
|
+ }
|
|
|
+}
|