Completed
Push — master ( e8e573...d0b5f0 )
by Yassine
11s
created

AccessTokenMetadata::getProperty()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
<?php
2
/**
3
 * Copyright 2017 Facebook, Inc.
4
 *
5
 * You are hereby granted a non-exclusive, worldwide, royalty-free license to
6
 * use, copy, modify, and distribute this software in source code or binary
7
 * form for use in connection with the web services and APIs provided by
8
 * Facebook.
9
 *
10
 * As with any software that integrates with the Facebook platform, your use
11
 * of this software is subject to the Facebook Developer Principles and
12
 * Policies [http://developers.facebook.com/policy/]. This copyright notice
13
 * shall be included in all copies or substantial portions of the software.
14
 *
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21
 * DEALINGS IN THE SOFTWARE.
22
 */
23
namespace Facebook\Authentication;
24
25
use Facebook\Exception\SDKException;
26
27
/**
28
 * Represents metadata from an access token.
29
 *
30
 * @package Facebook
31
 *
32
 * @see     https://developers.facebook.com/docs/graph-api/reference/debug_token
33
 */
34
class AccessTokenMetadata
35
{
36
    /**
37
     * The access token metadata.
38
     *
39
     * @var array
40
     */
41
    protected $metadata = [];
42
43
    /**
44
     * Properties that should be cast as DateTime objects.
45
     *
46
     * @var array
47
     */
48
    protected static $dateProperties = ['expires_at', 'issued_at'];
49
50
    /**
51
     * @param array $metadata
52
     *
53
     * @throws SDKException
54
     */
55
    public function __construct(array $metadata)
56
    {
57
        if (!isset($metadata['data'])) {
58
            throw new SDKException('Unexpected debug token response data.', 401);
59
        }
60
61
        $this->metadata = $metadata['data'];
62
63
        $this->castTimestampsToDateTime();
64
    }
65
66
    /**
67
     * Returns a value from the metadata.
68
     *
69
     * @param string $field   the property to retrieve
70
     * @param mixed  $default the default to return if the property doesn't exist
71
     *
72
     * @return mixed
73
     */
74
    public function getField($field, $default = null)
75
    {
76
        if (isset($this->metadata[$field])) {
77
            return $this->metadata[$field];
78
        }
79
80
        return $default;
81
    }
82
83
    /**
84
     * Returns a value from a child property in the metadata.
85
     *
86
     * @param string $parentField the parent property
87
     * @param string $field       the property to retrieve
88
     * @param mixed  $default     the default to return if the property doesn't exist
89
     *
90
     * @return mixed
91
     */
92
    public function getChildProperty($parentField, $field, $default = null)
93
    {
94
        if (!isset($this->metadata[$parentField])) {
95
            return $default;
96
        }
97
98
        if (!isset($this->metadata[$parentField][$field])) {
99
            return $default;
100
        }
101
102
        return $this->metadata[$parentField][$field];
103
    }
104
105
    /**
106
     * Returns a value from the error metadata.
107
     *
108
     * @param string $field   the property to retrieve
109
     * @param mixed  $default the default to return if the property doesn't exist
110
     *
111
     * @return mixed
112
     */
113
    public function getErrorProperty($field, $default = null)
114
    {
115
        return $this->getChildProperty('error', $field, $default);
116
    }
117
118
    /**
119
     * Returns a value from the "metadata" metadata. *Brain explodes*.
120
     *
121
     * @param string $field   the property to retrieve
122
     * @param mixed  $default the default to return if the property doesn't exist
123
     *
124
     * @return mixed
125
     */
126
    public function getMetadataProperty($field, $default = null)
127
    {
128
        return $this->getChildProperty('metadata', $field, $default);
129
    }
130
131
    /**
132
     * The ID of the application this access token is for.
133
     *
134
     * @return null|string
135
     */
136
    public function getAppId()
137
    {
138
        return $this->getField('app_id');
139
    }
140
141
    /**
142
     * Name of the application this access token is for.
143
     *
144
     * @return null|string
145
     */
146
    public function getApplication()
147
    {
148
        return $this->getField('application');
149
    }
150
151
    /**
152
     * Any error that a request to the graph api
153
     * would return due to the access token.
154
     *
155
     * @return null|bool
156
     */
157
    public function isError()
158
    {
159
        return $this->getField('error') !== null;
160
    }
161
162
    /**
163
     * The error code for the error.
164
     *
165
     * @return null|int
166
     */
167
    public function getErrorCode()
168
    {
169
        return $this->getErrorProperty('code');
170
    }
171
172
    /**
173
     * The error message for the error.
174
     *
175
     * @return null|string
176
     */
177
    public function getErrorMessage()
178
    {
179
        return $this->getErrorProperty('message');
180
    }
181
182
    /**
183
     * The error subcode for the error.
184
     *
185
     * @return null|int
186
     */
187
    public function getErrorSubcode()
188
    {
189
        return $this->getErrorProperty('subcode');
190
    }
191
192
    /**
193
     * DateTime when this access token expires.
194
     *
195
     * @return null|\DateTime
196
     */
197
    public function getExpiresAt()
198
    {
199
        return $this->getField('expires_at');
200
    }
201
202
    /**
203
     * Whether the access token is still valid or not.
204
     *
205
     * @return null|bool
206
     */
207
    public function getIsValid()
208
    {
209
        return $this->getField('is_valid');
210
    }
211
212
    /**
213
     * DateTime when this access token was issued.
214
     *
215
     * Note that the issued_at field is not returned
216
     * for short-lived access tokens.
217
     *
218
     * @see https://developers.facebook.com/docs/facebook-login/access-tokens#debug
219
     *
220
     * @return null|\DateTime
221
     */
222
    public function getIssuedAt()
223
    {
224
        return $this->getField('issued_at');
225
    }
226
227
    /**
228
     * General metadata associated with the access token.
229
     * Can contain data like 'sso', 'auth_type', 'auth_nonce'.
230
     *
231
     * @return null|array
232
     */
233
    public function getMetadata()
234
    {
235
        return $this->getField('metadata');
236
    }
237
238
    /**
239
     * The 'sso' child property from the 'metadata' parent property.
240
     *
241
     * @return null|string
242
     */
243
    public function getSso()
244
    {
245
        return $this->getMetadataProperty('sso');
246
    }
247
248
    /**
249
     * The 'auth_type' child property from the 'metadata' parent property.
250
     *
251
     * @return null|string
252
     */
253
    public function getAuthType()
254
    {
255
        return $this->getMetadataProperty('auth_type');
256
    }
257
258
    /**
259
     * The 'auth_nonce' child property from the 'metadata' parent property.
260
     *
261
     * @return null|string
262
     */
263
    public function getAuthNonce()
264
    {
265
        return $this->getMetadataProperty('auth_nonce');
266
    }
267
268
    /**
269
     * For impersonated access tokens, the ID of
270
     * the page this token contains.
271
     *
272
     * @return null|string
273
     */
274
    public function getProfileId()
275
    {
276
        return $this->getField('profile_id');
277
    }
278
279
    /**
280
     * List of permissions that the user has granted for
281
     * the app in this access token.
282
     *
283
     * @return array
284
     */
285
    public function getScopes()
286
    {
287
        return $this->getField('scopes');
288
    }
289
290
    /**
291
     * The ID of the user this access token is for.
292
     *
293
     * @return null|string
294
     */
295
    public function getUserId()
296
    {
297
        return $this->getField('user_id');
298
    }
299
300
    /**
301
     * Ensures the app ID from the access token
302
     * metadata is what we expect.
303
     *
304
     * @param string $appId
305
     *
306
     * @throws SDKException
307
     */
308
    public function validateAppId($appId)
309
    {
310
        if ($this->getAppId() !== $appId) {
311
            throw new SDKException('Access token metadata contains unexpected app ID.', 401);
312
        }
313
    }
314
315
    /**
316
     * Ensures the user ID from the access token
317
     * metadata is what we expect.
318
     *
319
     * @param string $userId
320
     *
321
     * @throws SDKException
322
     */
323
    public function validateUserId($userId)
324
    {
325
        if ($this->getUserId() !== $userId) {
326
            throw new SDKException('Access token metadata contains unexpected user ID.', 401);
327
        }
328
    }
329
330
    /**
331
     * Ensures the access token has not expired yet.
332
     *
333
     * @throws SDKException
334
     */
335
    public function validateExpiration()
336
    {
337
        if (!$this->getExpiresAt() instanceof \DateTime) {
338
            return;
339
        }
340
341
        if ($this->getExpiresAt()->getTimestamp() < time()) {
342
            throw new SDKException('Inspection of access token metadata shows that the access token has expired.', 401);
343
        }
344
    }
345
346
    /**
347
     * Converts a unix timestamp into a DateTime entity.
348
     *
349
     * @param int $timestamp
350
     *
351
     * @return \DateTime
352
     */
353
    private function convertTimestampToDateTime($timestamp)
354
    {
355
        $dt = new \DateTime();
356
        $dt->setTimestamp($timestamp);
357
358
        return $dt;
359
    }
360
361
    /**
362
     * Casts the unix timestamps as DateTime entities.
363
     */
364
    private function castTimestampsToDateTime()
365
    {
366
        foreach (static::$dateProperties as $key) {
367
            if (isset($this->metadata[$key]) && $this->metadata[$key] !== 0) {
368
                $this->metadata[$key] = $this->convertTimestampToDateTime($this->metadata[$key]);
369
            }
370
        }
371
    }
372
}
373