Lines
93.93%
31 / 33
Methods
50.00%
2 / 4
Classes
0.00%
0 / 1
| Name | Lines | Methods | CRAP | ||||
|---|---|---|---|---|---|---|---|
| __construct | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 1 | ||
| create | 96.42% | 27 / 28 | 0.00% | 0 / 1 | 8 | ||
| buildDiscoveryUrl | 66.66% | 2 / 3 | 0.00% | 0 / 1 | 3.33 | ||
| toBool | 100.00% | 1 / 1 | 100.00% | 1 / 1 | 4 | ||
| 27 | final readonly class KeycloakProviderConfigFactory | |
| 28 | { | |
| 29 | public function __construct( | |
| 30 | private Configuration $configuration, | |
| 31 | ) { | |
| 32 | } | |
| 33 | ||
| 34 | public function create(): OidcProviderConfig | |
| 35 | { | |
| 36 | $baseUrl = rtrim(trim((string) $this->configuration->get('keycloak.baseUrl')), characters: '/'); | |
| 37 | $realm = trim((string) $this->configuration->get('keycloak.realm')); | |
| 38 | $redirectUri = trim((string) $this->configuration->get('keycloak.redirectUri')); | |
| 39 | $scopes = preg_split('/\s+/', trim((string) $this->configuration->get('keycloak.scopes'))); | |
| 40 | if ($scopes === false) { | |
| 41 | $scopes = []; | |
| 42 | } | |
| 43 | ||
| 44 | $enabled = $this->toBool($this->configuration->get('keycloak.enable')); | |
| 45 | ||
| 46 | if ($enabled && ($baseUrl === '' || $realm === '')) { | |
| 47 | $missing = array_filter([ | |
| 48 | $baseUrl === '' ? 'baseUrl' : null, | |
| 49 | $realm === '' ? 'realm' : null, | |
| 50 | ]); | |
| 51 | throw new InvalidArgumentException(sprintf('Keycloak enabled but missing: %s', implode(' and ', $missing))); | |
| 52 | } | |
| 53 | ||
| 54 | if ($redirectUri === '') { | |
| 55 | $redirectUri = rtrim($this->configuration->getDefaultUrl(), characters: '/') . '/auth/keycloak/callback'; | |
| 56 | } | |
| 57 | ||
| 58 | return new OidcProviderConfig( | |
| 59 | provider: 'keycloak', | |
| 60 | enabled: $enabled, | |
| 61 | discoveryUrl: $this->buildDiscoveryUrl($baseUrl, $realm), | |
| 62 | client: new OidcClientConfig( | |
| 63 | clientId: trim((string) $this->configuration->get('keycloak.clientId')), | |
| 64 | clientSecret: (string) $this->configuration->get('keycloak.clientSecret'), | |
| 65 | redirectUri: $redirectUri, | |
| 66 | scopes: array_values(array_filter($scopes, static fn(string $scope): bool => $scope !== '')), | |
| 67 | ), | |
| 68 | autoProvision: $this->toBool($this->configuration->get('keycloak.autoProvision')), | |
| 69 | logoutRedirectUrl: trim((string) $this->configuration->get('keycloak.logoutRedirectUrl')), | |
| 70 | ); | |
| 71 | } | |
| 72 | ||
| 73 | private function buildDiscoveryUrl(string $baseUrl, string $realm): string | |
| 74 | { | |
| 75 | if ($baseUrl === '' || $realm === '') { | |
| 76 | return ''; | |
| 77 | } | |
| 78 | ||
| 79 | return $baseUrl . '/realms/' . rawurlencode($realm) . '/.well-known/openid-configuration'; | |
| 80 | } | |
| 81 | ||
| 82 | private function toBool(mixed $value): bool | |
| 83 | { | |
| 84 | return $value === true || $value === 1 || $value === '1' || $value === 'true'; | |
| 85 | } | |
| 86 | } |