X-Git-Url: http://source.bookstackapp.com/bookstack/blobdiff_plain/c167f40af32a45f0905c6d2961865fbe8c52d996..refs/pull/3043/head:/app/Auth/Access/Oidc/OidcService.php diff --git a/app/Auth/Access/Oidc/OidcService.php b/app/Auth/Access/Oidc/OidcService.php index be6a5c3c4..b8e017b4b 100644 --- a/app/Auth/Access/Oidc/OidcService.php +++ b/app/Auth/Access/Oidc/OidcService.php @@ -1,5 +1,8 @@ -config = config('oidc'); $this->registrationService = $registrationService; $this->loginService = $loginService; + $this->httpClient = $httpClient; } /** * Initiate an authorization flow. + * * @return array{url: string, state: string} */ public function login(): array { $settings = $this->getProviderSettings(); $provider = $this->getProvider($settings); + return [ - 'url' => $provider->getAuthorizationUrl(), + 'url' => $provider->getAuthorizationUrl(), 'state' => $provider->getState(), ]; } @@ -55,6 +60,7 @@ class OidcService * return the matching, or new if registration active, user matched to * the authorization server. * Returns null if not authenticated. + * * @throws Exception * @throws ClientExceptionInterface */ @@ -77,23 +83,24 @@ class OidcService */ protected function getProviderSettings(): OidcProviderSettings { + $config = $this->config(); $settings = new OidcProviderSettings([ - 'issuer' => $this->config['issuer'], - 'clientId' => $this->config['client_id'], - 'clientSecret' => $this->config['client_secret'], - 'redirectUri' => url('/http/source.bookstackapp.com/oidc/redirect'), - 'authorizationEndpoint' => $this->config['authorization_endpoint'], - 'tokenEndpoint' => $this->config['token_endpoint'], + 'issuer' => $config['issuer'], + 'clientId' => $config['client_id'], + 'clientSecret' => $config['client_secret'], + 'redirectUri' => url('/http/source.bookstackapp.com/oidc/callback'), + 'authorizationEndpoint' => $config['authorization_endpoint'], + 'tokenEndpoint' => $config['token_endpoint'], ]); // Use keys if configured - if (!empty($this->config['jwt_public_key'])) { - $settings->keys = [$this->config['jwt_public_key']]; + if (!empty($config['jwt_public_key'])) { + $settings->keys = [$config['jwt_public_key']]; } // Run discovery - if ($this->config['discover'] ?? false) { - $settings->discoverFromIssuer(new Client(['timeout' => 3]), Cache::store(null), 15); + if ($config['discover'] ?? false) { + $settings->discoverFromIssuer($this->httpClient, Cache::store(null), 15); } $settings->validate(); @@ -106,15 +113,18 @@ class OidcService */ protected function getProvider(OidcProviderSettings $settings): OidcOAuthProvider { - return new OidcOAuthProvider($settings->arrayForProvider()); + return new OidcOAuthProvider($settings->arrayForProvider(), [ + 'httpClient' => $this->httpClient, + 'optionProvider' => new HttpBasicAuthOptionProvider(), + ]); } /** - * Calculate the display name + * Calculate the display name. */ protected function getUserDisplayName(OidcIdToken $token, string $defaultValue): string { - $displayNameAttr = $this->config['display_name_claims']; + $displayNameAttr = $this->config()['display_name_claims']; $displayName = []; foreach ($displayNameAttr as $dnAttr) { @@ -133,21 +143,24 @@ class OidcService /** * Extract the details of a user from an ID token. + * * @return array{name: string, email: string, external_id: string} */ protected function getUserDetails(OidcIdToken $token): array { $id = $token->getClaim('sub'); + return [ 'external_id' => $id, - 'email' => $token->getClaim('email'), - 'name' => $this->getUserDisplayName($token, $id), + 'email' => $token->getClaim('email'), + 'name' => $this->getUserDisplayName($token, $id), ]; } /** * Processes a received access token for a user. Login the user when * they exist, optionally registering them automatically. + * * @throws OpenIdConnectException * @throws JsonDebugException * @throws UserRegistrationException @@ -162,7 +175,7 @@ class OidcService $settings->keys, ); - if ($this->config['dump_user_details']) { + if ($this->config()['dump_user_details']) { throw new JsonDebugException($idToken->getAllClaims()); } @@ -175,7 +188,7 @@ class OidcService $userDetails = $this->getUserDetails($idToken); $isLoggedIn = auth()->check(); - if ($userDetails['email'] === null) { + if (empty($userDetails['email'])) { throw new OpenIdConnectException(trans('errors.oidc_no_email_address')); } @@ -184,7 +197,9 @@ class OidcService } $user = $this->registrationService->findOrRegister( - $userDetails['name'], $userDetails['email'], $userDetails['external_id'] + $userDetails['name'], + $userDetails['email'], + $userDetails['external_id'] ); if ($user === null) { @@ -192,6 +207,15 @@ class OidcService } $this->loginService->login($user, 'oidc'); + return $user; } + + /** + * Get the OIDC config from the application. + */ + protected function config(): array + { + return config('oidc'); + } }