• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

janu-software / facebook-php-sdk / 13285164661

12 Feb 2025 12:17PM UTC coverage: 93.359%. Remained the same
13285164661

push

github

stanislav-janu
php 8.1 lock file

956 of 1024 relevant lines covered (93.36%)

11.45 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.24
/src/Authentication/OAuth2Client.php
1
<?php
2

3
declare(strict_types=1);
4
/**
5
 * Copyright 2017 Facebook, Inc.
6
 *
7
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
8
 * use, copy, modify, and distribute this software in source code or binary
9
 * form for use in connection with the web services and APIs provided by
10
 * Facebook.
11
 *
12
 * As with any software that integrates with the Facebook platform, your use
13
 * of this software is subject to the Facebook Developer Principles and
14
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
15
 * shall be included in all copies or substantial portions of the software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
22
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23
 * DEALINGS IN THE SOFTWARE.
24
 */
25

26
namespace JanuSoftware\Facebook\Authentication;
27

28
use JanuSoftware\Facebook\Application;
29
use JanuSoftware\Facebook\Client;
30
use JanuSoftware\Facebook\Exception\SDKException;
31
use JanuSoftware\Facebook\Facebook;
32
use JanuSoftware\Facebook\Request;
33
use JanuSoftware\Facebook\Response;
34

35
class OAuth2Client
36
{
37
        /**
38
         * @const string The base authorization URL.
39
         */
40
        final public const BaseAuthorizationUrl = 'https://www.facebook.com';
41

42
        /**
43
         * The last request sent to Graph.
44
         */
45
        protected ?Request $lastRequest = null;
46

47

48
        /**
49
         * @param string $graphVersion the version of the Graph API to use
50
         */
51
        public function __construct(
52
                protected Application $application,
53
                protected Client $client,
54
                protected string $graphVersion,
55
        ) {
56
        }
26✔
57

58

59
        /**
60
         * Returns the last Request that was sent.
61
         * Useful for debugging and testing.
62
         */
63
        public function getLastRequest(): ?Request
64
        {
65
                return $this->lastRequest;
4✔
66
        }
67

68

69
        /**
70
         * Get the metadata associated with the access token.
71
         *
72
         * @param AccessToken|string $accessToken the access token to debug
73
         *
74
         * @throws SDKException
75
         */
76
        public function debugToken(AccessToken|string $accessToken): AccessTokenMetadata
77
        {
78
                $accessToken = $accessToken instanceof AccessToken
1✔
79
                        ? $accessToken->getValue()
×
80
                        : $accessToken;
1✔
81
                $params = ['input_token' => $accessToken];
1✔
82

83
                $this->lastRequest = new Request(
1✔
84
                        $this->application,
1✔
85
                        $this->application->getAccessToken(),
1✔
86
                        'GET',
1✔
87
                        '/debug_token',
1✔
88
                        $params,
1✔
89
                        null,
1✔
90
                        $this->graphVersion,
1✔
91
                );
1✔
92
                $response = $this->client->sendRequest($this->lastRequest);
1✔
93
                $metadata = $response->getDecodedBody();
1✔
94

95
                return new AccessTokenMetadata($metadata);
1✔
96
        }
97

98

99
        /**
100
         * Generates an authorization URL to begin the process of authenticating a user.
101
         *
102
         * @param string $redirectUrl the callback URL to redirect to
103
         * @param string $state       the CSPRNG-generated CSRF value
104
         * @param array  $scope       an array of permissions to request
105
         * @param array  $params      an array of parameters to generate URL
106
         * @param string $separator   the separator to use in http_build_query()
107
         */
108
        public function getAuthorizationUrl(
109
                string $redirectUrl,
110
                string $state,
111
                array $scope = [],
112
                array $params = [],
113
                string $separator = '&',
114
        ): string {
115
                $params += [
4✔
116
                        'client_id' => $this->application->getId(),
4✔
117
                        'state' => $state,
4✔
118
                        'response_type' => 'code',
4✔
119
                        'sdk' => 'php-sdk-' . Facebook::Version,
4✔
120
                        'redirect_uri' => $redirectUrl,
4✔
121
                        'scope' => implode(',', $scope),
4✔
122
                ];
4✔
123

124
                return static::BaseAuthorizationUrl . '/' . $this->graphVersion . '/dialog/oauth?' . http_build_query($params, '', $separator);
4✔
125
        }
126

127

128
        /**
129
         * Get a valid access token from a code.
130
         *
131
         * @throws SDKException
132
         */
133
        public function getAccessTokenFromCode(string $code, string $redirectUri = ''): AccessToken
134
        {
135
                $params = [
2✔
136
                        'code' => $code,
2✔
137
                        'redirect_uri' => $redirectUri,
2✔
138
                ];
2✔
139

140
                return $this->requestAnAccessToken($params);
2✔
141
        }
142

143

144
        /**
145
         * Exchanges a short-lived access token with a long-lived access token.
146
         *
147
         * @throws SDKException
148
         */
149
        public function getLongLivedAccessToken(AccessToken|string $accessToken): AccessToken
150
        {
151
                $accessToken = $accessToken instanceof AccessToken
1✔
152
                        ? $accessToken->getValue()
×
153
                        : $accessToken;
1✔
154
                $params = [
1✔
155
                        'grant_type' => 'fb_exchange_token',
1✔
156
                        'fb_exchange_token' => $accessToken,
1✔
157
                ];
1✔
158

159
                return $this->requestAnAccessToken($params);
1✔
160
        }
161

162

163
        /**
164
         * Get a valid code from an access token.
165
         *
166
         * @throws SDKException
167
         */
168
        public function getCodeFromLongLivedAccessToken(AccessToken|string $accessToken, string $redirectUri = ''): string
169
        {
170
                $params = [
1✔
171
                        'redirect_uri' => $redirectUri,
1✔
172
                ];
1✔
173

174
                $response = $this->sendRequestWithClientParams('/oauth/client_code', $params, $accessToken);
1✔
175
                $data = $response->getDecodedBody();
1✔
176

177
                if (!isset($data['code'])) {
1✔
178
                        throw new SDKException('Code was not returned from Graph.', 401);
×
179
                }
180

181
                return $data['code'];
1✔
182
        }
183

184

185
        /**
186
         * Send a request to the OAuth endpoint.
187
         *
188
         * @throws SDKException
189
         */
190
        protected function requestAnAccessToken(array $params): AccessToken
191
        {
192
                $response = $this->sendRequestWithClientParams('/oauth/access_token', $params);
3✔
193
                $data = $response->getDecodedBody();
3✔
194

195
                if (!isset($data['access_token'])) {
3✔
196
                        throw new SDKException('Access token was not returned from Graph.', 401);
×
197
                }
198

199
                // Graph returns two different key names for expiration time
200
                // on the same endpoint. Doh! :/
201
                $expiresAt = 0;
3✔
202
                if (isset($data['expires'])) {
3✔
203
                        // For exchanging a short lived token with a long lived token.
204
                        // The expiration time in seconds will be returned as "expires".
205
                        $expiresAt = time() + $data['expires'];
2✔
206
                } elseif (isset($data['expires_in'])) {
1✔
207
                        // For exchanging a code for a short lived access token.
208
                        // The expiration time in seconds will be returned as "expires_in".
209
                        // See: https://developers.facebook.com/docs/facebook-login/access-tokens#long-via-code
210
                        $expiresAt = time() + $data['expires_in'];
×
211
                }
212

213
                return new AccessToken($data['access_token'], $expiresAt);
3✔
214
        }
215

216

217
        /**
218
         * Send a request to Graph with an app access token.
219
         */
220
        protected function sendRequestWithClientParams(
221
                string $endpoint,
222
                array $params,
223
                AccessToken|string|null $accessToken = null,
224
        ): Response {
225
                $params += $this->getClientParams();
4✔
226

227
                $accessToken ??= $this->application->getAccessToken();
4✔
228

229
                $this->lastRequest = new Request(
4✔
230
                        $this->application,
4✔
231
                        $accessToken,
4✔
232
                        'GET',
4✔
233
                        $endpoint,
4✔
234
                        $params,
4✔
235
                        null,
4✔
236
                        $this->graphVersion,
4✔
237
                );
4✔
238

239
                return $this->client->sendRequest($this->lastRequest);
4✔
240
        }
241

242

243
        /**
244
         * Returns the client_* params for OAuth requests.
245
         * @return array{client_id: string, client_secret: string}
246
         */
247
        protected function getClientParams(): array
248
        {
249
                return [
4✔
250
                        'client_id' => $this->application->getId(),
4✔
251
                        'client_secret' => $this->application->getSecret(),
4✔
252
                ];
4✔
253
        }
254
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc