]> BookStack Code Mirror - bookstack/blob - app/Auth/Access/Oidc/OidcOAuthProvider.php
Fixes padding issues of the sidebar's items
[bookstack] / app / Auth / Access / Oidc / OidcOAuthProvider.php
1 <?php
2
3 namespace BookStack\Auth\Access\Oidc;
4
5 use League\OAuth2\Client\Grant\AbstractGrant;
6 use League\OAuth2\Client\Provider\AbstractProvider;
7 use League\OAuth2\Client\Provider\Exception\IdentityProviderException;
8 use League\OAuth2\Client\Provider\GenericResourceOwner;
9 use League\OAuth2\Client\Provider\ResourceOwnerInterface;
10 use League\OAuth2\Client\Token\AccessToken;
11 use League\OAuth2\Client\Tool\BearerAuthorizationTrait;
12 use Psr\Http\Message\ResponseInterface;
13
14 /**
15  * Extended OAuth2Provider for using with OIDC.
16  * Credit to the https://github.com/steverhoades/oauth2-openid-connect-client
17  * project for the idea of extending a League\OAuth2 client for this use-case.
18  */
19 class OidcOAuthProvider extends AbstractProvider
20 {
21     use BearerAuthorizationTrait;
22
23     /**
24      * @var string
25      */
26     protected $authorizationEndpoint;
27
28     /**
29      * @var string
30      */
31     protected $tokenEndpoint;
32
33     /**
34      * Returns the base URL for authorizing a client.
35      */
36     public function getBaseAuthorizationUrl(): string
37     {
38         return $this->authorizationEndpoint;
39     }
40
41     /**
42      * Returns the base URL for requesting an access token.
43      */
44     public function getBaseAccessTokenUrl(array $params): string
45     {
46         return $this->tokenEndpoint;
47     }
48
49     /**
50      * Returns the URL for requesting the resource owner's details.
51      */
52     public function getResourceOwnerDetailsUrl(AccessToken $token): string
53     {
54         return '';
55     }
56
57     /**
58      * Returns the default scopes used by this provider.
59      *
60      * This should only be the scopes that are required to request the details
61      * of the resource owner, rather than all the available scopes.
62      */
63     protected function getDefaultScopes(): array
64     {
65         return ['openid', 'profile', 'email'];
66     }
67
68     /**
69      * Returns the string that should be used to separate scopes when building
70      * the URL for requesting an access token.
71      */
72     protected function getScopeSeparator(): string
73     {
74         return ' ';
75     }
76
77     /**
78      * Checks a provider response for errors.
79      *
80      * @param ResponseInterface $response
81      * @param array|string      $data     Parsed response data
82      *
83      * @throws IdentityProviderException
84      *
85      * @return void
86      */
87     protected function checkResponse(ResponseInterface $response, $data)
88     {
89         if ($response->getStatusCode() >= 400 || isset($data['error'])) {
90             throw new IdentityProviderException(
91                 $data['error'] ?? $response->getReasonPhrase(),
92                 $response->getStatusCode(),
93                 (string) $response->getBody()
94             );
95         }
96     }
97
98     /**
99      * Generates a resource owner object from a successful resource owner
100      * details request.
101      *
102      * @param array       $response
103      * @param AccessToken $token
104      *
105      * @return ResourceOwnerInterface
106      */
107     protected function createResourceOwner(array $response, AccessToken $token)
108     {
109         return new GenericResourceOwner($response, '');
110     }
111
112     /**
113      * Creates an access token from a response.
114      *
115      * The grant that was used to fetch the response can be used to provide
116      * additional context.
117      *
118      * @param array         $response
119      * @param AbstractGrant $grant
120      *
121      * @return OidcAccessToken
122      */
123     protected function createAccessToken(array $response, AbstractGrant $grant)
124     {
125         return new OidcAccessToken($response);
126     }
127 }