| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  | <?php | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-13 06:04:28 +08:00
										 |  |  | namespace BookStack\Auth\Access\Oidc; | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-10-12 02:05:16 +08:00
										 |  |  | use League\OAuth2\Client\Grant\AbstractGrant; | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  | use League\OAuth2\Client\Provider\AbstractProvider; | 
					
						
							|  |  |  | use League\OAuth2\Client\Provider\Exception\IdentityProviderException; | 
					
						
							|  |  |  | use League\OAuth2\Client\Provider\GenericResourceOwner; | 
					
						
							|  |  |  | use League\OAuth2\Client\Provider\ResourceOwnerInterface; | 
					
						
							|  |  |  | use League\OAuth2\Client\Token\AccessToken; | 
					
						
							|  |  |  | use League\OAuth2\Client\Tool\BearerAuthorizationTrait; | 
					
						
							|  |  |  | use Psr\Http\Message\ResponseInterface; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | /** | 
					
						
							|  |  |  |  * Extended OAuth2Provider for using with OIDC. | 
					
						
							|  |  |  |  * Credit to the https://github.com/steverhoades/oauth2-openid-connect-client | 
					
						
							|  |  |  |  * project for the idea of extending a League\OAuth2 client for this use-case. | 
					
						
							|  |  |  |  */ | 
					
						
							| 
									
										
										
										
											2021-10-13 06:04:28 +08:00
										 |  |  | class OidcOAuthProvider extends AbstractProvider | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  | { | 
					
						
							|  |  |  |     use BearerAuthorizationTrait; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected $authorizationEndpoint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * @var string | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected $tokenEndpoint; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the base URL for authorizing a client. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getBaseAuthorizationUrl(): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->authorizationEndpoint; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the base URL for requesting an access token. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getBaseAccessTokenUrl(array $params): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return $this->tokenEndpoint; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the URL for requesting the resource owner's details. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     public function getResourceOwnerDetailsUrl(AccessToken $token): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ''; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the default scopes used by this provider. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * This should only be the scopes that are required to request the details | 
					
						
							|  |  |  |      * of the resource owner, rather than all the available scopes. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getDefaultScopes(): array | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ['openid', 'profile', 'email']; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Returns the string that should be used to separate scopes when building | 
					
						
							|  |  |  |      * the URL for requesting an access token. | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function getScopeSeparator(): string | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return ' '; | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Checks a provider response for errors. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * @param ResponseInterface $response | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * @param array|string      $data     Parsed response data | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  |      * @throws IdentityProviderException | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * | 
					
						
							|  |  |  |      * @return void | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected function checkResponse(ResponseInterface $response, $data) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         if ($response->getStatusCode() >= 400 || isset($data['error'])) { | 
					
						
							|  |  |  |             throw new IdentityProviderException( | 
					
						
							|  |  |  |                 $data['error'] ?? $response->getReasonPhrase(), | 
					
						
							|  |  |  |                 $response->getStatusCode(), | 
					
						
							|  |  |  |                 (string) $response->getBody() | 
					
						
							|  |  |  |             ); | 
					
						
							|  |  |  |         } | 
					
						
							|  |  |  |     } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Generates a resource owner object from a successful resource owner | 
					
						
							|  |  |  |      * details request. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * @param array       $response | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  |      * @param AccessToken $token | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-11 02:14:08 +08:00
										 |  |  |      * @return ResourceOwnerInterface | 
					
						
							|  |  |  |      */ | 
					
						
							|  |  |  |     protected function createResourceOwner(array $response, AccessToken $token) | 
					
						
							|  |  |  |     { | 
					
						
							|  |  |  |         return new GenericResourceOwner($response, ''); | 
					
						
							|  |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-12 02:05:16 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     /** | 
					
						
							|  |  |  |      * Creates an access token from a response. | 
					
						
							|  |  |  |      * | 
					
						
							|  |  |  |      * The grant that was used to fetch the response can be used to provide | 
					
						
							|  |  |  |      * additional context. | 
					
						
							|  |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * @param array         $response | 
					
						
							| 
									
										
										
										
											2021-10-12 02:05:16 +08:00
										 |  |  |      * @param AbstractGrant $grant | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  |      * | 
					
						
							| 
									
										
										
										
											2021-10-13 06:04:28 +08:00
										 |  |  |      * @return OidcAccessToken | 
					
						
							| 
									
										
										
										
											2021-10-12 02:05:16 +08:00
										 |  |  |      */ | 
					
						
							|  |  |  |     protected function createAccessToken(array $response, AbstractGrant $grant) | 
					
						
							|  |  |  |     { | 
					
						
							| 
									
										
										
										
											2021-10-13 06:04:28 +08:00
										 |  |  |         return new OidcAccessToken($response); | 
					
						
							| 
									
										
										
										
											2021-10-12 02:05:16 +08:00
										 |  |  |     } | 
					
						
							| 
									
										
										
										
											2021-10-16 23:01:59 +08:00
										 |  |  | } |