1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* Copyright 2011 Facebook, Inc. |
4
|
|
|
* |
5
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may |
6
|
|
|
* not use this file except in compliance with the License. You may obtain |
7
|
|
|
* a copy of the License at |
8
|
|
|
* |
9
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0 |
10
|
|
|
* |
11
|
|
|
* Unless required by applicable law or agreed to in writing, software |
12
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT |
13
|
|
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the |
14
|
|
|
* License for the specific language governing permissions and limitations |
15
|
|
|
* under the License. |
16
|
|
|
*/ |
17
|
|
|
|
18
|
|
|
class PHPSDKTestCase extends PHPUnit_Framework_TestCase { |
19
|
|
|
const APP_ID = '117743971608120'; |
20
|
|
|
const SECRET = '9c8ea2071859659bea1246d33a9207cf'; |
21
|
|
|
|
22
|
|
|
const MIGRATED_APP_ID = '174236045938435'; |
23
|
|
|
const MIGRATED_SECRET = '0073dce2d95c4a5c2922d1827ea0cca6'; |
24
|
|
|
|
25
|
|
|
const TEST_USER = 499834690; |
26
|
|
|
const TEST_USER_2 = 499835484; |
27
|
|
|
|
28
|
|
|
private static $kExpiredAccessToken = 'AAABrFmeaJjgBAIshbq5ZBqZBICsmveZCZBi6O4w9HSTkFI73VMtmkL9jLuWsZBZC9QMHvJFtSulZAqonZBRIByzGooCZC8DWr0t1M4BL9FARdQwPWPnIqCiFQ'; |
29
|
|
|
|
30
|
|
|
private static function kValidSignedRequest($id = self::TEST_USER, $oauth_token = null) { |
31
|
|
|
$facebook = new FBPublic(array( |
32
|
|
|
'appId' => self::APP_ID, |
33
|
|
|
'secret' => self::SECRET, |
34
|
|
|
)); |
35
|
|
|
return $facebook->publicMakeSignedRequest( |
36
|
|
|
array( |
37
|
|
|
'user_id' => $id, |
38
|
|
|
'oauth_token' => $oauth_token |
39
|
|
|
) |
40
|
|
|
); |
41
|
|
|
} |
42
|
|
|
|
43
|
|
|
private static function kNonTosedSignedRequest() { |
44
|
|
|
$facebook = new FBPublic(array( |
45
|
|
|
'appId' => self::APP_ID, |
46
|
|
|
'secret' => self::SECRET, |
47
|
|
|
)); |
48
|
|
|
return $facebook->publicMakeSignedRequest(array()); |
49
|
|
|
} |
50
|
|
|
|
51
|
|
|
private static function kSignedRequestWithEmptyValue() { |
52
|
|
|
return ''; |
53
|
|
|
} |
54
|
|
|
|
55
|
|
|
private static function kSignedRequestWithBogusSignature() { |
56
|
|
|
$facebook = new FBPublic(array( |
57
|
|
|
'appId' => self::APP_ID, |
58
|
|
|
'secret' => 'bogus', |
59
|
|
|
)); |
60
|
|
|
return $facebook->publicMakeSignedRequest( |
61
|
|
|
array( |
62
|
|
|
'algorithm' => 'HMAC-SHA256', |
63
|
|
|
) |
64
|
|
|
); |
65
|
|
|
} |
66
|
|
|
|
67
|
|
|
private static function kSignedRequestWithWrongAlgo() { |
68
|
|
|
$facebook = new FBPublic(array( |
69
|
|
|
'appId' => self::APP_ID, |
70
|
|
|
'secret' => self::SECRET, |
71
|
|
|
)); |
72
|
|
|
$data['algorithm'] = 'foo'; |
73
|
|
|
$json = json_encode($data); |
74
|
|
|
$b64 = $facebook->publicBase64UrlEncode($json); |
75
|
|
|
$raw_sig = hash_hmac('sha256', $b64, self::SECRET, $raw = true); |
76
|
|
|
$sig = $facebook->publicBase64UrlEncode($raw_sig); |
77
|
|
|
return $sig.'.'.$b64; |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
public function testConstructor() { |
81
|
|
|
$facebook = new TransientFacebook(array( |
82
|
|
|
'appId' => self::APP_ID, |
83
|
|
|
'secret' => self::SECRET, |
84
|
|
|
)); |
85
|
|
|
$this->assertEquals($facebook->getAppId(), self::APP_ID, |
86
|
|
|
'Expect the App ID to be set.'); |
87
|
|
|
$this->assertEquals($facebook->getAppSecret(), self::SECRET, |
88
|
|
|
'Expect the API secret to be set.'); |
89
|
|
|
} |
90
|
|
|
|
91
|
|
|
public function testConstructorWithFileUpload() { |
92
|
|
|
$facebook = new TransientFacebook(array( |
93
|
|
|
'appId' => self::APP_ID, |
94
|
|
|
'secret' => self::SECRET, |
95
|
|
|
'fileUpload' => true, |
96
|
|
|
)); |
97
|
|
|
$this->assertEquals($facebook->getAppId(), self::APP_ID, |
98
|
|
|
'Expect the App ID to be set.'); |
99
|
|
|
$this->assertEquals($facebook->getAppSecret(), self::SECRET, |
100
|
|
|
'Expect the API secret to be set.'); |
101
|
|
|
$this->assertTrue($facebook->getFileUploadSupport(), |
102
|
|
|
'Expect file upload support to be on.'); |
103
|
|
|
// alias (depricated) for getFileUploadSupport -- test until removed |
104
|
|
|
$this->assertTrue($facebook->useFileUploadSupport(), |
|
|
|
|
105
|
|
|
'Expect file upload support to be on.'); |
106
|
|
|
} |
107
|
|
|
|
108
|
|
|
public function testSetAppId() { |
109
|
|
|
$facebook = new TransientFacebook(array( |
110
|
|
|
'appId' => self::APP_ID, |
111
|
|
|
'secret' => self::SECRET, |
112
|
|
|
)); |
113
|
|
|
$facebook->setAppId('dummy'); |
114
|
|
|
$this->assertEquals($facebook->getAppId(), 'dummy', |
115
|
|
|
'Expect the App ID to be dummy.'); |
116
|
|
|
} |
117
|
|
|
|
118
|
|
|
public function testSetAPISecret() { |
119
|
|
|
$facebook = new TransientFacebook(array( |
120
|
|
|
'appId' => self::APP_ID, |
121
|
|
|
'secret' => self::SECRET, |
122
|
|
|
)); |
123
|
|
|
$facebook->setApiSecret('dummy'); |
|
|
|
|
124
|
|
|
$this->assertEquals($facebook->getApiSecret(), 'dummy', |
|
|
|
|
125
|
|
|
'Expect the API secret to be dummy.'); |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
public function testSetAPPSecret() { |
129
|
|
|
$facebook = new TransientFacebook(array( |
130
|
|
|
'appId' => self::APP_ID, |
131
|
|
|
'secret' => self::SECRET, |
132
|
|
|
)); |
133
|
|
|
$facebook->setAppSecret('dummy'); |
134
|
|
|
$this->assertEquals($facebook->getAppSecret(), 'dummy', |
135
|
|
|
'Expect the API secret to be dummy.'); |
136
|
|
|
} |
137
|
|
|
|
138
|
|
|
public function testSetAccessToken() { |
139
|
|
|
$facebook = new TransientFacebook(array( |
140
|
|
|
'appId' => self::APP_ID, |
141
|
|
|
'secret' => self::SECRET, |
142
|
|
|
)); |
143
|
|
|
|
144
|
|
|
$facebook->setAccessToken('saltydog'); |
145
|
|
|
$this->assertEquals($facebook->getAccessToken(), 'saltydog', |
146
|
|
|
'Expect installed access token to remain \'saltydog\''); |
147
|
|
|
} |
148
|
|
|
|
149
|
|
|
public function testSetFileUploadSupport() { |
150
|
|
|
$facebook = new TransientFacebook(array( |
151
|
|
|
'appId' => self::APP_ID, |
152
|
|
|
'secret' => self::SECRET, |
153
|
|
|
)); |
154
|
|
|
$this->assertFalse($facebook->getFileUploadSupport(), |
155
|
|
|
'Expect file upload support to be off.'); |
156
|
|
|
// alias for getFileUploadSupport (depricated), testing until removed |
157
|
|
|
$this->assertFalse($facebook->useFileUploadSupport(), |
|
|
|
|
158
|
|
|
'Expect file upload support to be off.'); |
159
|
|
|
$facebook->setFileUploadSupport(true); |
160
|
|
|
$this->assertTrue($facebook->getFileUploadSupport(), |
161
|
|
|
'Expect file upload support to be on.'); |
162
|
|
|
// alias for getFileUploadSupport (depricated), testing until removed |
163
|
|
|
$this->assertTrue($facebook->useFileUploadSupport(), |
|
|
|
|
164
|
|
|
'Expect file upload support to be on.'); |
165
|
|
|
} |
166
|
|
|
|
167
|
|
|
public function testGetCurrentURL() { |
168
|
|
|
$facebook = new FBGetCurrentURLFacebook(array( |
169
|
|
|
'appId' => self::APP_ID, |
170
|
|
|
'secret' => self::SECRET, |
171
|
|
|
)); |
172
|
|
|
|
173
|
|
|
// fake the HPHP $_SERVER globals |
174
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
175
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php?one=one&two=two&three=three'; |
176
|
|
|
$current_url = $facebook->publicGetCurrentUrl(); |
177
|
|
|
$this->assertEquals( |
178
|
|
|
'http://www.test.com/unit-tests.php?one=one&two=two&three=three', |
179
|
|
|
$current_url, |
180
|
|
|
'getCurrentUrl function is changing the current URL'); |
181
|
|
|
|
182
|
|
|
// ensure structure of valueless GET params is retained (sometimes |
183
|
|
|
// an = sign was present, and sometimes it was not) |
184
|
|
|
// first test when equal signs are present |
185
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
186
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php?one=&two=&three='; |
187
|
|
|
$current_url = $facebook->publicGetCurrentUrl(); |
188
|
|
|
$this->assertEquals( |
189
|
|
|
'http://www.test.com/unit-tests.php?one=&two=&three=', |
190
|
|
|
$current_url, |
191
|
|
|
'getCurrentUrl function is changing the current URL'); |
192
|
|
|
|
193
|
|
|
// now confirm that |
194
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
195
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php?one&two&three'; |
196
|
|
|
$current_url = $facebook->publicGetCurrentUrl(); |
197
|
|
|
$this->assertEquals( |
198
|
|
|
'http://www.test.com/unit-tests.php?one&two&three', |
199
|
|
|
$current_url, |
200
|
|
|
'getCurrentUrl function is changing the current URL'); |
201
|
|
|
} |
202
|
|
|
|
203
|
|
|
public function testGetLoginURL() { |
204
|
|
|
$facebook = new Facebook(array( |
205
|
|
|
'appId' => self::APP_ID, |
206
|
|
|
'secret' => self::SECRET, |
207
|
|
|
)); |
208
|
|
|
|
209
|
|
|
// fake the HPHP $_SERVER globals |
210
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
211
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php'; |
212
|
|
|
$login_url = parse_url($facebook->getLoginUrl()); |
213
|
|
|
$this->assertEquals($login_url['scheme'], 'https'); |
214
|
|
|
$this->assertEquals($login_url['host'], 'www.facebook.com'); |
215
|
|
|
$this->assertEquals($login_url['path'], '/dialog/oauth'); |
216
|
|
|
$expected_login_params = |
217
|
|
|
array('client_id' => self::APP_ID, |
218
|
|
|
'redirect_uri' => 'http://www.test.com/unit-tests.php'); |
219
|
|
|
|
220
|
|
|
$query_map = array(); |
221
|
|
|
parse_str($login_url['query'], $query_map); |
222
|
|
|
$this->assertIsSubset($expected_login_params, $query_map); |
223
|
|
|
// we don't know what the state is, but we know it's an md5 and should |
224
|
|
|
// be 32 characters long. |
225
|
|
|
$this->assertEquals(strlen($query_map['state']), $num_characters = 32); |
226
|
|
|
} |
227
|
|
|
|
228
|
|
|
public function testGetLoginURLWithExtraParams() { |
229
|
|
|
$facebook = new Facebook(array( |
230
|
|
|
'appId' => self::APP_ID, |
231
|
|
|
'secret' => self::SECRET, |
232
|
|
|
)); |
233
|
|
|
|
234
|
|
|
// fake the HPHP $_SERVER globals |
235
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
236
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php'; |
237
|
|
|
$extra_params = array('scope' => 'email, sms', |
238
|
|
|
'nonsense' => 'nonsense'); |
239
|
|
|
$login_url = parse_url($facebook->getLoginUrl($extra_params)); |
240
|
|
|
$this->assertEquals($login_url['scheme'], 'https'); |
241
|
|
|
$this->assertEquals($login_url['host'], 'www.facebook.com'); |
242
|
|
|
$this->assertEquals($login_url['path'], '/dialog/oauth'); |
243
|
|
|
$expected_login_params = |
244
|
|
|
array_merge( |
245
|
|
|
array('client_id' => self::APP_ID, |
246
|
|
|
'redirect_uri' => 'http://www.test.com/unit-tests.php'), |
247
|
|
|
$extra_params); |
248
|
|
|
$query_map = array(); |
249
|
|
|
parse_str($login_url['query'], $query_map); |
250
|
|
|
$this->assertIsSubset($expected_login_params, $query_map); |
251
|
|
|
// we don't know what the state is, but we know it's an md5 and should |
252
|
|
|
// be 32 characters long. |
253
|
|
|
$this->assertEquals(strlen($query_map['state']), $num_characters = 32); |
254
|
|
|
} |
255
|
|
|
|
256
|
|
|
public function testGetLoginURLWithScopeParamsAsArray() { |
257
|
|
|
$facebook = new Facebook(array( |
258
|
|
|
'appId' => self::APP_ID, |
259
|
|
|
'secret' => self::SECRET, |
260
|
|
|
)); |
261
|
|
|
|
262
|
|
|
// fake the HPHP $_SERVER globals |
263
|
|
|
$_SERVER['HTTP_HOST'] = 'www.test.com'; |
264
|
|
|
$_SERVER['REQUEST_URI'] = '/unit-tests.php'; |
265
|
|
|
$scope_params_as_array = array('email','sms','read_stream'); |
266
|
|
|
$extra_params = array('scope' => $scope_params_as_array, |
267
|
|
|
'nonsense' => 'nonsense'); |
268
|
|
|
$login_url = parse_url($facebook->getLoginUrl($extra_params)); |
269
|
|
|
$this->assertEquals($login_url['scheme'], 'https'); |
270
|
|
|
$this->assertEquals($login_url['host'], 'www.facebook.com'); |
271
|
|
|
$this->assertEquals($login_url['path'], '/dialog/oauth'); |
272
|
|
|
// expect api to flatten array params to comma separated list |
273
|
|
|
// should do the same here before asserting to make sure API is behaving |
274
|
|
|
// correctly; |
275
|
|
|
$extra_params['scope'] = implode(',', $scope_params_as_array); |
276
|
|
|
$expected_login_params = |
277
|
|
|
array_merge( |
278
|
|
|
array('client_id' => self::APP_ID, |
279
|
|
|
'redirect_uri' => 'http://www.test.com/unit-tests.php'), |
280
|
|
|
$extra_params); |
281
|
|
|
$query_map = array(); |
282
|
|
|
parse_str($login_url['query'], $query_map); |
283
|
|
|
$this->assertIsSubset($expected_login_params, $query_map); |
284
|
|
|
// we don't know what the state is, but we know it's an md5 and should |
285
|
|
|
// be 32 characters long. |
286
|
|
|
$this->assertEquals(strlen($query_map['state']), $num_characters = 32); |
287
|
|
|
} |
288
|
|
|
|
289
|
|
|
public function testGetCodeWithValidCSRFState() { |
290
|
|
|
$facebook = new FBCode(array( |
291
|
|
|
'appId' => self::APP_ID, |
292
|
|
|
'secret' => self::SECRET, |
293
|
|
|
)); |
294
|
|
|
|
295
|
|
|
$facebook->setCSRFStateToken(); |
296
|
|
|
$code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); |
297
|
|
|
$_REQUEST['state'] = $facebook->getCSRFStateToken(); |
298
|
|
|
$this->assertEquals($code, |
299
|
|
|
$facebook->publicGetCode(), |
300
|
|
|
'Expect code to be pulled from $_REQUEST[\'code\']'); |
301
|
|
|
} |
302
|
|
|
|
303
|
|
|
public function testGetCodeWithInvalidCSRFState() { |
304
|
|
|
$facebook = new FBCode(array( |
305
|
|
|
'appId' => self::APP_ID, |
306
|
|
|
'secret' => self::SECRET, |
307
|
|
|
)); |
308
|
|
|
|
309
|
|
|
$facebook->setCSRFStateToken(); |
310
|
|
|
$code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); |
311
|
|
|
$_REQUEST['state'] = $facebook->getCSRFStateToken().'forgery!!!'; |
312
|
|
|
$this->assertFalse($facebook->publicGetCode(), |
313
|
|
|
'Expect getCode to fail, CSRF state should not match.'); |
314
|
|
|
} |
315
|
|
|
|
316
|
|
|
public function testGetCodeWithMissingCSRFState() { |
317
|
|
|
$facebook = new FBCode(array( |
318
|
|
|
'appId' => self::APP_ID, |
319
|
|
|
'secret' => self::SECRET, |
320
|
|
|
)); |
321
|
|
|
|
322
|
|
|
$code = $_REQUEST['code'] = $this->generateMD5HashOfRandomValue(); |
323
|
|
|
// intentionally don't set CSRF token at all |
324
|
|
|
$this->assertFalse($facebook->publicGetCode(), |
325
|
|
|
'Expect getCode to fail, CSRF state not sent back.'); |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
public function testPersistentCSRFState() |
329
|
|
|
{ |
330
|
|
|
$facebook = new FBCode(array( |
331
|
|
|
'appId' => self::APP_ID, |
332
|
|
|
'secret' => self::SECRET, |
333
|
|
|
)); |
334
|
|
|
$facebook->setCSRFStateToken(); |
335
|
|
|
$code = $facebook->getCSRFStateToken(); |
336
|
|
|
|
337
|
|
|
$facebook = new FBCode(array( |
338
|
|
|
'appId' => self::APP_ID, |
339
|
|
|
'secret' => self::SECRET, |
340
|
|
|
)); |
341
|
|
|
|
342
|
|
|
$this->assertEquals($code, $facebook->publicGetState(), |
343
|
|
|
'Persisted CSRF state token not loaded correctly'); |
344
|
|
|
} |
345
|
|
|
|
346
|
|
|
public function testPersistentCSRFStateWithSharedSession() |
347
|
|
|
{ |
348
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
349
|
|
|
$facebook = new FBCode(array( |
350
|
|
|
'appId' => self::APP_ID, |
351
|
|
|
'secret' => self::SECRET, |
352
|
|
|
'sharedSession' => true, |
353
|
|
|
)); |
354
|
|
|
$facebook->setCSRFStateToken(); |
355
|
|
|
$code = $facebook->getCSRFStateToken(); |
356
|
|
|
|
357
|
|
|
$facebook = new FBCode(array( |
358
|
|
|
'appId' => self::APP_ID, |
359
|
|
|
'secret' => self::SECRET, |
360
|
|
|
'sharedSession' => true, |
361
|
|
|
)); |
362
|
|
|
|
363
|
|
|
$this->assertEquals($code, $facebook->publicGetState(), |
364
|
|
|
'Persisted CSRF state token not loaded correctly with shared session'); |
365
|
|
|
} |
366
|
|
|
|
367
|
|
|
public function testGetUserFromSignedRequest() { |
368
|
|
|
$facebook = new TransientFacebook(array( |
369
|
|
|
'appId' => self::APP_ID, |
370
|
|
|
'secret' => self::SECRET, |
371
|
|
|
)); |
372
|
|
|
|
373
|
|
|
$_REQUEST['signed_request'] = self::kValidSignedRequest(); |
374
|
|
|
$this->assertEquals('499834690', $facebook->getUser(), |
375
|
|
|
'Failed to get user ID from a valid signed request.'); |
376
|
|
|
} |
377
|
|
|
|
378
|
|
|
public function testDisallowSignedRequest() { |
379
|
|
|
$facebook = new TransientFacebook(array( |
380
|
|
|
'appId' => self::APP_ID, |
381
|
|
|
'secret' => self::SECRET, |
382
|
|
|
'allowSignedRequest' => false |
383
|
|
|
)); |
384
|
|
|
|
385
|
|
|
$_REQUEST['signed_request'] = self::kValidSignedRequest(); |
386
|
|
|
$this->assertEquals(0, $facebook->getUser(), |
387
|
|
|
'Should not have received valid user from signed_request.'); |
388
|
|
|
} |
389
|
|
|
|
390
|
|
|
|
391
|
|
|
public function testSignedRequestRewrite(){ |
392
|
|
|
$facebook = new FBRewrite(array( |
393
|
|
|
'appId' => self::APP_ID, |
394
|
|
|
'secret' => self::SECRET, |
395
|
|
|
)); |
396
|
|
|
|
397
|
|
|
$_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER, 'Hello sweetie'); |
398
|
|
|
|
399
|
|
|
$this->assertEquals(self::TEST_USER, $facebook->getUser(), |
400
|
|
|
'Failed to get user ID from a valid signed request.'); |
401
|
|
|
|
402
|
|
|
$this->assertEquals('Hello sweetie', $facebook->getAccessToken(), |
403
|
|
|
'Failed to get access token from signed request'); |
404
|
|
|
|
405
|
|
|
$facebook->uncache(); |
406
|
|
|
|
407
|
|
|
$_REQUEST['signed_request'] = self::kValidSignedRequest(self::TEST_USER_2, 'spoilers'); |
408
|
|
|
|
409
|
|
|
$this->assertEquals(self::TEST_USER_2, $facebook->getUser(), |
410
|
|
|
'Failed to get user ID from a valid signed request.'); |
411
|
|
|
|
412
|
|
|
$_REQUEST['signed_request'] = null; |
413
|
|
|
$facebook ->uncacheSignedRequest(); |
414
|
|
|
|
415
|
|
|
$this->assertNotEquals('Hello sweetie', $facebook->getAccessToken(), |
416
|
|
|
'Failed to clear access token'); |
417
|
|
|
} |
418
|
|
|
|
419
|
|
|
public function testGetSignedRequestFromCookie() { |
420
|
|
|
$facebook = new FBPublicCookie(array( |
421
|
|
|
'appId' => self::APP_ID, |
422
|
|
|
'secret' => self::SECRET, |
423
|
|
|
)); |
424
|
|
|
|
425
|
|
|
$_COOKIE[$facebook->publicGetSignedRequestCookieName()] = |
426
|
|
|
self::kValidSignedRequest(); |
427
|
|
|
$this->assertNotNull($facebook->publicGetSignedRequest()); |
428
|
|
|
$this->assertEquals('499834690', $facebook->getUser(), |
429
|
|
|
'Failed to get user ID from a valid signed request.'); |
430
|
|
|
} |
431
|
|
|
|
432
|
|
|
public function testGetSignedRequestWithIncorrectSignature() { |
433
|
|
|
$facebook = new FBPublicCookie(array( |
434
|
|
|
'appId' => self::APP_ID, |
435
|
|
|
'secret' => self::SECRET, |
436
|
|
|
)); |
437
|
|
|
|
438
|
|
|
$_COOKIE[$facebook->publicGetSignedRequestCookieName()] = |
439
|
|
|
self::kSignedRequestWithBogusSignature(); |
440
|
|
|
$this->assertNull($facebook->publicGetSignedRequest()); |
441
|
|
|
} |
442
|
|
|
|
443
|
|
|
public function testNonUserAccessToken() { |
444
|
|
|
$facebook = new FBAccessToken(array( |
445
|
|
|
'appId' => self::APP_ID, |
446
|
|
|
'secret' => self::SECRET, |
447
|
|
|
)); |
448
|
|
|
|
449
|
|
|
// no cookies, and no request params, so no user or code, |
450
|
|
|
// so no user access token (even with cookie support) |
451
|
|
|
$this->assertEquals($facebook->publicGetApplicationAccessToken(), |
452
|
|
|
$facebook->getAccessToken(), |
453
|
|
|
'Access token should be that for logged out users.'); |
454
|
|
|
} |
455
|
|
|
|
456
|
|
|
public function testMissingMetadataCookie() { |
457
|
|
|
$fb = new FBPublicCookie(array( |
458
|
|
|
'appId' => self::APP_ID, |
459
|
|
|
'secret' => self::SECRET, |
460
|
|
|
)); |
461
|
|
|
$this->assertEmpty($fb->publicGetMetadataCookie()); |
462
|
|
|
} |
463
|
|
|
|
464
|
|
|
public function testEmptyMetadataCookie() { |
465
|
|
|
$fb = new FBPublicCookie(array( |
466
|
|
|
'appId' => self::APP_ID, |
467
|
|
|
'secret' => self::SECRET, |
468
|
|
|
)); |
469
|
|
|
$_COOKIE[$fb->publicGetMetadataCookieName()] = ''; |
470
|
|
|
$this->assertEmpty($fb->publicGetMetadataCookie()); |
471
|
|
|
} |
472
|
|
|
|
473
|
|
|
public function testMetadataCookie() { |
474
|
|
|
$fb = new FBPublicCookie(array( |
475
|
|
|
'appId' => self::APP_ID, |
476
|
|
|
'secret' => self::SECRET, |
477
|
|
|
)); |
478
|
|
|
$key = 'foo'; |
479
|
|
|
$val = '42'; |
480
|
|
|
$_COOKIE[$fb->publicGetMetadataCookieName()] = "$key=$val"; |
481
|
|
|
$this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie()); |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
public function testQuotedMetadataCookie() { |
485
|
|
|
$fb = new FBPublicCookie(array( |
486
|
|
|
'appId' => self::APP_ID, |
487
|
|
|
'secret' => self::SECRET, |
488
|
|
|
)); |
489
|
|
|
$key = 'foo'; |
490
|
|
|
$val = '42'; |
491
|
|
|
$_COOKIE[$fb->publicGetMetadataCookieName()] = "\"$key=$val\""; |
492
|
|
|
$this->assertEquals(array($key => $val), $fb->publicGetMetadataCookie()); |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
public function testAPIForLoggedOutUsers() { |
496
|
|
|
$facebook = new TransientFacebook(array( |
497
|
|
|
'appId' => self::APP_ID, |
498
|
|
|
'secret' => self::SECRET, |
499
|
|
|
)); |
500
|
|
|
$response = $facebook->api(array( |
501
|
|
|
'method' => 'fql.query', |
502
|
|
|
'query' => 'SELECT name FROM user WHERE uid=4', |
503
|
|
|
)); |
504
|
|
|
$this->assertEquals(count($response), 1, |
505
|
|
|
'Expect one row back.'); |
506
|
|
|
$this->assertEquals($response[0]['name'], 'Mark Zuckerberg', |
507
|
|
|
'Expect the name back.'); |
508
|
|
|
} |
509
|
|
|
|
510
|
|
|
public function testAPIWithBogusAccessToken() { |
511
|
|
|
$facebook = new TransientFacebook(array( |
512
|
|
|
'appId' => self::APP_ID, |
513
|
|
|
'secret' => self::SECRET, |
514
|
|
|
)); |
515
|
|
|
|
516
|
|
|
$facebook->setAccessToken('this-is-not-really-an-access-token'); |
517
|
|
|
// if we don't set an access token and there's no way to |
518
|
|
|
// get one, then the FQL query below works beautifully, handing |
519
|
|
|
// over Zuck's public data. But if you specify a bogus access |
520
|
|
|
// token as I have right here, then the FQL query should fail. |
521
|
|
|
// We could return just Zuck's public data, but that wouldn't |
522
|
|
|
// advertise the issue that the access token is at worst broken |
523
|
|
|
// and at best expired. |
524
|
|
|
try { |
525
|
|
|
$response = $facebook->api(array( |
526
|
|
|
'method' => 'fql.query', |
527
|
|
|
'query' => 'SELECT name FROM profile WHERE id=4', |
528
|
|
|
)); |
529
|
|
|
$this->fail('Should not get here.'); |
530
|
|
|
} catch(FacebookApiException $e) { |
531
|
|
|
$result = $e->getResult(); |
532
|
|
|
$this->assertTrue(is_array($result), 'expect a result object'); |
533
|
|
|
$this->assertEquals('190', $result['error_code'], 'expect code'); |
534
|
|
|
} |
535
|
|
|
} |
536
|
|
|
|
537
|
|
|
public function testAPIGraphPublicData() { |
538
|
|
|
$facebook = new TransientFacebook(array( |
539
|
|
|
'appId' => self::APP_ID, |
540
|
|
|
'secret' => self::SECRET, |
541
|
|
|
)); |
542
|
|
|
|
543
|
|
|
$response = $facebook->api('/jerry'); |
544
|
|
|
$this->assertEquals( |
545
|
|
|
$response['id'], '214707', 'should get expected id.'); |
546
|
|
|
} |
547
|
|
|
|
548
|
|
|
public function testGraphAPIWithBogusAccessToken() { |
549
|
|
|
$facebook = new TransientFacebook(array( |
550
|
|
|
'appId' => self::APP_ID, |
551
|
|
|
'secret' => self::SECRET, |
552
|
|
|
)); |
553
|
|
|
|
554
|
|
|
$facebook->setAccessToken('this-is-not-really-an-access-token'); |
555
|
|
|
try { |
556
|
|
|
$response = $facebook->api('/me'); |
557
|
|
|
$this->fail('Should not get here.'); |
558
|
|
|
} catch(FacebookApiException $e) { |
559
|
|
|
// means the server got the access token and didn't like it |
560
|
|
|
$msg = 'OAuthException: Invalid OAuth access token.'; |
561
|
|
|
$this->assertEquals($msg, (string) $e, |
562
|
|
|
'Expect the invalid OAuth token message.'); |
563
|
|
|
} |
564
|
|
|
} |
565
|
|
|
|
566
|
|
|
public function testGraphAPIWithExpiredAccessToken() { |
567
|
|
|
$facebook = new TransientFacebook(array( |
568
|
|
|
'appId' => self::APP_ID, |
569
|
|
|
'secret' => self::SECRET, |
570
|
|
|
)); |
571
|
|
|
|
572
|
|
|
$facebook->setAccessToken(self::$kExpiredAccessToken); |
573
|
|
|
try { |
574
|
|
|
$response = $facebook->api('/me'); |
575
|
|
|
$this->fail('Should not get here.'); |
576
|
|
|
} catch(FacebookApiException $e) { |
577
|
|
|
// means the server got the access token and didn't like it |
578
|
|
|
$error_msg_start = 'OAuthException: Error validating access token:'; |
579
|
|
|
$this->assertTrue(strpos((string) $e, $error_msg_start) === 0, |
580
|
|
|
'Expect the token validation error message.'); |
581
|
|
|
} |
582
|
|
|
} |
583
|
|
|
|
584
|
|
|
public function testGraphAPIOAuthSpecError() { |
585
|
|
|
$facebook = new TransientFacebook(array( |
586
|
|
|
'appId' => self::MIGRATED_APP_ID, |
587
|
|
|
'secret' => self::MIGRATED_SECRET, |
588
|
|
|
)); |
589
|
|
|
|
590
|
|
|
try { |
591
|
|
|
$response = $facebook->api('/me', array( |
592
|
|
|
'client_id' => self::MIGRATED_APP_ID)); |
593
|
|
|
|
594
|
|
|
$this->fail('Should not get here.'); |
595
|
|
|
} catch(FacebookApiException $e) { |
596
|
|
|
// means the server got the access token |
597
|
|
|
$msg = 'invalid_request: An active access token must be used '. |
598
|
|
|
'to query information about the current user.'; |
599
|
|
|
$this->assertEquals($msg, (string) $e, |
600
|
|
|
'Expect the invalid session message.'); |
601
|
|
|
} |
602
|
|
|
} |
603
|
|
|
|
604
|
|
|
public function testGraphAPIMethodOAuthSpecError() { |
605
|
|
|
$facebook = new TransientFacebook(array( |
606
|
|
|
'appId' => self::MIGRATED_APP_ID, |
607
|
|
|
'secret' => self::MIGRATED_SECRET, |
608
|
|
|
)); |
609
|
|
|
|
610
|
|
|
try { |
611
|
|
|
$response = $facebook->api('/daaku.shah', 'DELETE', array( |
612
|
|
|
'client_id' => self::MIGRATED_APP_ID)); |
613
|
|
|
$this->fail('Should not get here.'); |
614
|
|
|
} catch(FacebookApiException $e) { |
615
|
|
|
$this->assertEquals(strpos($e, 'invalid_request'), 0); |
616
|
|
|
} |
617
|
|
|
} |
618
|
|
|
|
619
|
|
|
public function testCurlFailure() { |
620
|
|
|
$facebook = new TransientFacebook(array( |
621
|
|
|
'appId' => self::APP_ID, |
622
|
|
|
'secret' => self::SECRET, |
623
|
|
|
)); |
624
|
|
|
|
625
|
|
|
if (!defined('CURLOPT_TIMEOUT_MS')) { |
626
|
|
|
// can't test it if we don't have millisecond timeouts |
627
|
|
|
return; |
628
|
|
|
} |
629
|
|
|
|
630
|
|
|
$exception = null; |
631
|
|
|
try { |
632
|
|
|
// we dont expect facebook will ever return in 1ms |
633
|
|
|
Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS] = 50; |
634
|
|
|
$facebook->api('/naitik'); |
635
|
|
|
} catch(FacebookApiException $e) { |
636
|
|
|
$exception = $e; |
637
|
|
|
} |
638
|
|
|
unset(Facebook::$CURL_OPTS[CURLOPT_TIMEOUT_MS]); |
639
|
|
|
if (!$exception) { |
640
|
|
|
$this->fail('no exception was thrown on timeout.'); |
641
|
|
|
} |
642
|
|
|
|
643
|
|
|
$code = $exception->getCode(); |
644
|
|
|
if ($code != CURLE_OPERATION_TIMEOUTED && $code != CURLE_COULDNT_CONNECT) { |
645
|
|
|
$this->fail("Expected curl error code 7 or 28 but got: $code"); |
646
|
|
|
} |
647
|
|
|
$this->assertEquals('CurlException', $exception->getType(), 'expect type'); |
648
|
|
|
} |
649
|
|
|
|
650
|
|
|
public function testGraphAPIWithOnlyParams() { |
651
|
|
|
$facebook = new TransientFacebook(array( |
652
|
|
|
'appId' => self::APP_ID, |
653
|
|
|
'secret' => self::SECRET, |
654
|
|
|
)); |
655
|
|
|
|
656
|
|
|
$response = $facebook->api('/jerry'); |
657
|
|
|
$this->assertTrue(isset($response['id']), |
658
|
|
|
'User ID should be public.'); |
659
|
|
|
$this->assertTrue(isset($response['name']), |
660
|
|
|
'User\'s name should be public.'); |
661
|
|
|
$this->assertTrue(isset($response['first_name']), |
662
|
|
|
'User\'s first name should be public.'); |
663
|
|
|
$this->assertTrue(isset($response['last_name']), |
664
|
|
|
'User\'s last name should be public.'); |
665
|
|
|
$this->assertFalse(isset($response['work']), |
666
|
|
|
'User\'s work history should only be available with '. |
667
|
|
|
'a valid access token.'); |
668
|
|
|
$this->assertFalse(isset($response['education']), |
669
|
|
|
'User\'s education history should only be '. |
670
|
|
|
'available with a valid access token.'); |
671
|
|
|
$this->assertFalse(isset($response['verified']), |
672
|
|
|
'User\'s verification status should only be '. |
673
|
|
|
'available with a valid access token.'); |
674
|
|
|
} |
675
|
|
|
|
676
|
|
|
public function testLoginURLDefaults() { |
677
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
678
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
679
|
|
|
$facebook = new TransientFacebook(array( |
680
|
|
|
'appId' => self::APP_ID, |
681
|
|
|
'secret' => self::SECRET, |
682
|
|
|
)); |
683
|
|
|
$encodedUrl = rawurlencode('http://fbrell.com/examples'); |
684
|
|
|
$this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), |
685
|
|
|
'Expect the current url to exist.'); |
686
|
|
|
} |
687
|
|
|
|
688
|
|
|
public function testLoginURLDefaultsDropStateQueryParam() { |
689
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
690
|
|
|
$_SERVER['REQUEST_URI'] = '/examples?state=xx42xx'; |
691
|
|
|
$facebook = new TransientFacebook(array( |
692
|
|
|
'appId' => self::APP_ID, |
693
|
|
|
'secret' => self::SECRET, |
694
|
|
|
)); |
695
|
|
|
$expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); |
696
|
|
|
$this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1, |
697
|
|
|
'Expect the current url to exist.'); |
698
|
|
|
$this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), |
699
|
|
|
'Expect the session param to be dropped.'); |
700
|
|
|
} |
701
|
|
|
|
702
|
|
|
public function testLoginURLDefaultsDropCodeQueryParam() { |
703
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
704
|
|
|
$_SERVER['REQUEST_URI'] = '/examples?code=xx42xx'; |
705
|
|
|
$facebook = new TransientFacebook(array( |
706
|
|
|
'appId' => self::APP_ID, |
707
|
|
|
'secret' => self::SECRET, |
708
|
|
|
)); |
709
|
|
|
$expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); |
710
|
|
|
$this->assertTrue(strpos($facebook->getLoginUrl(), $expectEncodedUrl) > -1, |
711
|
|
|
'Expect the current url to exist.'); |
712
|
|
|
$this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), |
713
|
|
|
'Expect the session param to be dropped.'); |
714
|
|
|
} |
715
|
|
|
|
716
|
|
|
public function testLoginURLDefaultsDropSignedRequestParamButNotOthers() { |
717
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
718
|
|
|
$_SERVER['REQUEST_URI'] = |
719
|
|
|
'/examples?signed_request=xx42xx&do_not_drop=xx43xx'; |
720
|
|
|
$facebook = new TransientFacebook(array( |
721
|
|
|
'appId' => self::APP_ID, |
722
|
|
|
'secret' => self::SECRET, |
723
|
|
|
)); |
724
|
|
|
$expectEncodedUrl = rawurlencode('http://fbrell.com/examples'); |
725
|
|
|
$this->assertFalse(strpos($facebook->getLoginUrl(), 'xx42xx'), |
726
|
|
|
'Expect the session param to be dropped.'); |
727
|
|
|
$this->assertTrue(strpos($facebook->getLoginUrl(), 'xx43xx') > -1, |
728
|
|
|
'Expect the do_not_drop param to exist.'); |
729
|
|
|
} |
730
|
|
|
|
731
|
|
|
public function testLoginURLCustomNext() { |
732
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
733
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
734
|
|
|
$facebook = new TransientFacebook(array( |
735
|
|
|
'appId' => self::APP_ID, |
736
|
|
|
'secret' => self::SECRET, |
737
|
|
|
)); |
738
|
|
|
$next = 'http://fbrell.com/custom'; |
739
|
|
|
$loginUrl = $facebook->getLoginUrl(array( |
740
|
|
|
'redirect_uri' => $next, |
741
|
|
|
'cancel_url' => $next |
742
|
|
|
)); |
743
|
|
|
$currentEncodedUrl = rawurlencode('http://fbrell.com/examples'); |
744
|
|
|
$expectedEncodedUrl = rawurlencode($next); |
745
|
|
|
$this->assertNotNull(strpos($loginUrl, $expectedEncodedUrl), |
746
|
|
|
'Expect the custom url to exist.'); |
747
|
|
|
$this->assertFalse(strpos($loginUrl, $currentEncodedUrl), |
748
|
|
|
'Expect the current url to not exist.'); |
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
public function testLogoutURLDefaults() { |
752
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
753
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
754
|
|
|
$facebook = new TransientFacebook(array( |
755
|
|
|
'appId' => self::APP_ID, |
756
|
|
|
'secret' => self::SECRET, |
757
|
|
|
)); |
758
|
|
|
$encodedUrl = rawurlencode('http://fbrell.com/examples'); |
759
|
|
|
$this->assertNotNull(strpos($facebook->getLogoutUrl(), $encodedUrl), |
760
|
|
|
'Expect the current url to exist.'); |
761
|
|
|
$this->assertFalse(strpos($facebook->getLogoutUrl(), self::SECRET)); |
762
|
|
|
} |
763
|
|
|
|
764
|
|
|
public function testLoginStatusURLDefaults() { |
765
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
766
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
767
|
|
|
$facebook = new TransientFacebook(array( |
768
|
|
|
'appId' => self::APP_ID, |
769
|
|
|
'secret' => self::SECRET, |
770
|
|
|
)); |
771
|
|
|
$encodedUrl = rawurlencode('http://fbrell.com/examples'); |
772
|
|
|
$this->assertNotNull(strpos($facebook->getLoginStatusUrl(), $encodedUrl), |
773
|
|
|
'Expect the current url to exist.'); |
774
|
|
|
} |
775
|
|
|
|
776
|
|
|
public function testLoginStatusURLCustom() { |
777
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
778
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
779
|
|
|
$facebook = new TransientFacebook(array( |
780
|
|
|
'appId' => self::APP_ID, |
781
|
|
|
'secret' => self::SECRET, |
782
|
|
|
)); |
783
|
|
|
$encodedUrl1 = rawurlencode('http://fbrell.com/examples'); |
784
|
|
|
$okUrl = 'http://fbrell.com/here1'; |
785
|
|
|
$encodedUrl2 = rawurlencode($okUrl); |
786
|
|
|
$loginStatusUrl = $facebook->getLoginStatusUrl(array( |
787
|
|
|
'ok_session' => $okUrl, |
788
|
|
|
)); |
789
|
|
|
$this->assertNotNull(strpos($loginStatusUrl, $encodedUrl1), |
790
|
|
|
'Expect the current url to exist.'); |
791
|
|
|
$this->assertNotNull(strpos($loginStatusUrl, $encodedUrl2), |
792
|
|
|
'Expect the custom url to exist.'); |
793
|
|
|
} |
794
|
|
|
|
795
|
|
|
public function testNonDefaultPort() { |
796
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com:8080'; |
797
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
798
|
|
|
$facebook = new TransientFacebook(array( |
799
|
|
|
'appId' => self::APP_ID, |
800
|
|
|
'secret' => self::SECRET, |
801
|
|
|
)); |
802
|
|
|
$encodedUrl = rawurlencode('http://fbrell.com:8080/examples'); |
803
|
|
|
$this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), |
804
|
|
|
'Expect the current url to exist.'); |
805
|
|
|
} |
806
|
|
|
|
807
|
|
|
public function testSecureCurrentUrl() { |
808
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
809
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
810
|
|
|
$_SERVER['HTTPS'] = 'on'; |
811
|
|
|
$facebook = new TransientFacebook(array( |
812
|
|
|
'appId' => self::APP_ID, |
813
|
|
|
'secret' => self::SECRET, |
814
|
|
|
)); |
815
|
|
|
$encodedUrl = rawurlencode('https://fbrell.com/examples'); |
816
|
|
|
$this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), |
817
|
|
|
'Expect the current url to exist.'); |
818
|
|
|
} |
819
|
|
|
|
820
|
|
|
public function testSecureCurrentUrlWithNonDefaultPort() { |
821
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com:8080'; |
822
|
|
|
$_SERVER['REQUEST_URI'] = '/examples'; |
823
|
|
|
$_SERVER['HTTPS'] = 'on'; |
824
|
|
|
$facebook = new TransientFacebook(array( |
825
|
|
|
'appId' => self::APP_ID, |
826
|
|
|
'secret' => self::SECRET, |
827
|
|
|
)); |
828
|
|
|
$encodedUrl = rawurlencode('https://fbrell.com:8080/examples'); |
829
|
|
|
$this->assertNotNull(strpos($facebook->getLoginUrl(), $encodedUrl), |
830
|
|
|
'Expect the current url to exist.'); |
831
|
|
|
} |
832
|
|
|
|
833
|
|
|
public function testBase64UrlEncode() { |
834
|
|
|
$input = 'Facebook rocks'; |
835
|
|
|
$output = 'RmFjZWJvb2sgcm9ja3M'; |
836
|
|
|
|
837
|
|
|
$this->assertEquals(FBPublic::publicBase64UrlDecode($output), $input); |
838
|
|
|
} |
839
|
|
|
|
840
|
|
|
public function testSignedToken() { |
841
|
|
|
$facebook = new FBPublic(array( |
842
|
|
|
'appId' => self::APP_ID, |
843
|
|
|
'secret' => self::SECRET |
844
|
|
|
)); |
845
|
|
|
$sr = self::kValidSignedRequest(); |
846
|
|
|
$payload = $facebook->publicParseSignedRequest($sr); |
847
|
|
|
$this->assertNotNull($payload, 'Expected token to parse'); |
848
|
|
|
$this->assertEquals($facebook->getSignedRequest(), null); |
849
|
|
|
$_REQUEST['signed_request'] = $sr; |
850
|
|
|
$this->assertEquals($facebook->getSignedRequest(), $payload); |
851
|
|
|
} |
852
|
|
|
|
853
|
|
|
public function testNonTossedSignedtoken() { |
854
|
|
|
$facebook = new FBPublic(array( |
855
|
|
|
'appId' => self::APP_ID, |
856
|
|
|
'secret' => self::SECRET |
857
|
|
|
)); |
858
|
|
|
$payload = $facebook->publicParseSignedRequest( |
859
|
|
|
self::kNonTosedSignedRequest()); |
860
|
|
|
$this->assertNotNull($payload, 'Expected token to parse'); |
861
|
|
|
$this->assertNull($facebook->getSignedRequest()); |
862
|
|
|
$_REQUEST['signed_request'] = self::kNonTosedSignedRequest(); |
863
|
|
|
$sr = $facebook->getSignedRequest(); |
864
|
|
|
$this->assertTrue(isset($sr['algorithm'])); |
865
|
|
|
} |
866
|
|
|
|
867
|
|
|
public function testSignedRequestWithEmptyValue() { |
868
|
|
|
$fb = new FBPublicCookie(array( |
869
|
|
|
'appId' => self::APP_ID, |
870
|
|
|
'secret' => self::SECRET |
871
|
|
|
)); |
872
|
|
|
$_REQUEST['signed_request'] = self::kSignedRequestWithEmptyValue(); |
873
|
|
|
$this->assertNull($fb->getSignedRequest()); |
874
|
|
|
$_COOKIE[$fb->publicGetSignedRequestCookieName()] = |
875
|
|
|
self::kSignedRequestWithEmptyValue(); |
876
|
|
|
$this->assertNull($fb->getSignedRequest()); |
877
|
|
|
} |
878
|
|
|
|
879
|
|
|
public function testSignedRequestWithWrongAlgo() { |
880
|
|
|
$fb = new FBPublic(array( |
881
|
|
|
'appId' => self::APP_ID, |
882
|
|
|
'secret' => self::SECRET |
883
|
|
|
)); |
884
|
|
|
$payload = $fb->publicParseSignedRequest( |
885
|
|
|
self::kSignedRequestWithWrongAlgo()); |
886
|
|
|
$this->assertNull($payload, 'Expected nothing back.'); |
887
|
|
|
} |
888
|
|
|
|
889
|
|
|
public function testMakeAndParse() { |
890
|
|
|
$fb = new FBPublic(array( |
891
|
|
|
'appId' => self::APP_ID, |
892
|
|
|
'secret' => self::SECRET |
893
|
|
|
)); |
894
|
|
|
$data = array('foo' => 42); |
895
|
|
|
$sr = $fb->publicMakeSignedRequest($data); |
896
|
|
|
$decoded = $fb->publicParseSignedRequest($sr); |
897
|
|
|
$this->assertEquals($data['foo'], $decoded['foo']); |
898
|
|
|
} |
899
|
|
|
|
900
|
|
|
/** |
901
|
|
|
* @expectedException InvalidArgumentException |
902
|
|
|
*/ |
903
|
|
|
public function testMakeSignedRequestExpectsArray() { |
904
|
|
|
$fb = new FBPublic(array( |
905
|
|
|
'appId' => self::APP_ID, |
906
|
|
|
'secret' => self::SECRET |
907
|
|
|
)); |
908
|
|
|
$sr = $fb->publicMakeSignedRequest(''); |
909
|
|
|
} |
910
|
|
|
|
911
|
|
|
public function testBundledCACert() { |
912
|
|
|
$facebook = new TransientFacebook(array( |
913
|
|
|
'appId' => self::APP_ID, |
914
|
|
|
'secret' => self::SECRET |
915
|
|
|
)); |
916
|
|
|
|
917
|
|
|
// use the bundled cert from the start |
918
|
|
|
Facebook::$CURL_OPTS[CURLOPT_CAINFO] = |
919
|
|
|
dirname(__FILE__) . '/../src/fb_ca_chain_bundle.crt'; |
920
|
|
|
$response = $facebook->api('/naitik'); |
921
|
|
|
|
922
|
|
|
unset(Facebook::$CURL_OPTS[CURLOPT_CAINFO]); |
923
|
|
|
$this->assertEquals( |
924
|
|
|
$response['id'], '5526183', 'should get expected id.'); |
925
|
|
|
} |
926
|
|
|
|
927
|
|
|
public function testVideoUpload() { |
928
|
|
|
$facebook = new FBRecordURL(array( |
929
|
|
|
'appId' => self::APP_ID, |
930
|
|
|
'secret' => self::SECRET |
931
|
|
|
)); |
932
|
|
|
|
933
|
|
|
$facebook->api(array('method' => 'video.upload')); |
934
|
|
|
$this->assertContains('//api-video.', $facebook->getRequestedURL(), |
935
|
|
|
'video.upload should go against api-video'); |
936
|
|
|
} |
937
|
|
|
|
938
|
|
|
public function testVideoUploadGraph() { |
939
|
|
|
$facebook = new FBRecordURL(array( |
940
|
|
|
'appId' => self::APP_ID, |
941
|
|
|
'secret' => self::SECRET |
942
|
|
|
)); |
943
|
|
|
|
944
|
|
|
$facebook->api('/me/videos', 'POST'); |
945
|
|
|
$this->assertContains('//graph-video.', $facebook->getRequestedURL(), |
946
|
|
|
'/me/videos should go against graph-video'); |
947
|
|
|
} |
948
|
|
|
|
949
|
|
|
public function testGetUserAndAccessTokenFromSession() { |
950
|
|
|
$facebook = new PersistentFBPublic(array( |
951
|
|
|
'appId' => self::APP_ID, |
952
|
|
|
'secret' => self::SECRET |
953
|
|
|
)); |
954
|
|
|
|
955
|
|
|
$facebook->publicSetPersistentData('access_token', |
956
|
|
|
self::$kExpiredAccessToken); |
957
|
|
|
$facebook->publicSetPersistentData('user_id', 12345); |
958
|
|
|
$this->assertEquals(self::$kExpiredAccessToken, |
959
|
|
|
$facebook->getAccessToken(), |
960
|
|
|
'Get access token from persistent store.'); |
961
|
|
|
$this->assertEquals('12345', |
962
|
|
|
$facebook->getUser(), |
963
|
|
|
'Get user id from persistent store.'); |
964
|
|
|
} |
965
|
|
|
|
966
|
|
|
public function testGetUserAndAccessTokenFromSignedRequestNotSession() { |
967
|
|
|
$facebook = new PersistentFBPublic(array( |
968
|
|
|
'appId' => self::APP_ID, |
969
|
|
|
'secret' => self::SECRET |
970
|
|
|
)); |
971
|
|
|
|
972
|
|
|
$_REQUEST['signed_request'] = self::kValidSignedRequest(); |
973
|
|
|
$facebook->publicSetPersistentData('user_id', 41572); |
974
|
|
|
$facebook->publicSetPersistentData('access_token', |
975
|
|
|
self::$kExpiredAccessToken); |
976
|
|
|
$this->assertNotEquals('41572', $facebook->getUser(), |
977
|
|
|
'Got user from session instead of signed request.'); |
978
|
|
|
$this->assertEquals('499834690', $facebook->getUser(), |
979
|
|
|
'Failed to get correct user ID from signed request.'); |
980
|
|
|
$this->assertNotEquals( |
981
|
|
|
self::$kExpiredAccessToken, |
982
|
|
|
$facebook->getAccessToken(), |
983
|
|
|
'Got access token from session instead of signed request.'); |
984
|
|
|
$this->assertNotEmpty( |
985
|
|
|
$facebook->getAccessToken(), |
986
|
|
|
'Failed to extract an access token from the signed request.'); |
987
|
|
|
} |
988
|
|
|
|
989
|
|
|
public function testGetUserWithoutCodeOrSignedRequestOrSession() { |
990
|
|
|
$facebook = new PersistentFBPublic(array( |
991
|
|
|
'appId' => self::APP_ID, |
992
|
|
|
'secret' => self::SECRET |
993
|
|
|
)); |
994
|
|
|
|
995
|
|
|
// deliberately leave $_REQUEST and _$SESSION empty |
996
|
|
|
$this->assertEmpty($_REQUEST, |
997
|
|
|
'GET, POST, and COOKIE params exist even though '. |
998
|
|
|
'they should. Test cannot succeed unless all of '. |
999
|
|
|
'$_REQUEST is empty.'); |
1000
|
|
|
$this->assertEmpty($_SESSION, |
1001
|
|
|
'Session is carrying state and should not be.'); |
1002
|
|
|
$this->assertEmpty($facebook->getUser(), |
1003
|
|
|
'Got a user id, even without a signed request, '. |
1004
|
|
|
'access token, or session variable.'); |
1005
|
|
|
$this->assertEmpty($_SESSION, |
1006
|
|
|
'Session superglobal incorrectly populated by getUser.'); |
1007
|
|
|
} |
1008
|
|
|
|
1009
|
|
|
public function testGetAccessTokenUsingCodeInJsSdkCookie() { |
1010
|
|
|
$code = 'code1'; |
1011
|
|
|
$access_token = 'at1'; |
1012
|
|
|
$methods_to_stub = array('getSignedRequest', 'getAccessTokenFromCode'); |
1013
|
|
|
$constructor_args = array(array( |
1014
|
|
|
'appId' => self::APP_ID, |
1015
|
|
|
'secret' => self::SECRET |
1016
|
|
|
)); |
1017
|
|
|
$stub = $this->getMock( |
1018
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1019
|
|
|
$stub |
1020
|
|
|
->expects($this->once()) |
1021
|
|
|
->method('getSignedRequest') |
1022
|
|
|
->will($this->returnValue(array('code' => $code))); |
1023
|
|
|
$stub |
1024
|
|
|
->expects($this->once()) |
1025
|
|
|
->method('getAccessTokenFromCode') |
1026
|
|
|
->will($this->returnValueMap(array(array($code, '', $access_token)))); |
1027
|
|
|
$this->assertEquals($stub->getAccessToken(), $access_token); |
1028
|
|
|
} |
1029
|
|
|
|
1030
|
|
|
public function testSignedRequestWithoutAuthClearsData() { |
1031
|
|
|
$methods_to_stub = array('getSignedRequest', 'clearAllPersistentData'); |
1032
|
|
|
$constructor_args = array(array( |
1033
|
|
|
'appId' => self::APP_ID, |
1034
|
|
|
'secret' => self::SECRET |
1035
|
|
|
)); |
1036
|
|
|
$stub = $this->getMock( |
1037
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1038
|
|
|
$stub |
1039
|
|
|
->expects($this->once()) |
1040
|
|
|
->method('getSignedRequest') |
1041
|
|
|
->will($this->returnValue(array('foo' => 1))); |
1042
|
|
|
$stub |
1043
|
|
|
->expects($this->once()) |
1044
|
|
|
->method('clearAllPersistentData'); |
1045
|
|
|
$this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); |
1046
|
|
|
} |
1047
|
|
|
|
1048
|
|
|
public function testInvalidCodeInSignedRequestWillClearData() { |
1049
|
|
|
$code = 'code1'; |
1050
|
|
|
$methods_to_stub = array( |
1051
|
|
|
'getSignedRequest', |
1052
|
|
|
'getAccessTokenFromCode', |
1053
|
|
|
'clearAllPersistentData', |
1054
|
|
|
); |
1055
|
|
|
$constructor_args = array(array( |
1056
|
|
|
'appId' => self::APP_ID, |
1057
|
|
|
'secret' => self::SECRET |
1058
|
|
|
)); |
1059
|
|
|
$stub = $this->getMock( |
1060
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1061
|
|
|
$stub |
1062
|
|
|
->expects($this->once()) |
1063
|
|
|
->method('getSignedRequest') |
1064
|
|
|
->will($this->returnValue(array('code' => $code))); |
1065
|
|
|
$stub |
1066
|
|
|
->expects($this->once()) |
1067
|
|
|
->method('getAccessTokenFromCode') |
1068
|
|
|
->will($this->returnValue(null)); |
1069
|
|
|
$stub |
1070
|
|
|
->expects($this->once()) |
1071
|
|
|
->method('clearAllPersistentData'); |
1072
|
|
|
$this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); |
1073
|
|
|
} |
1074
|
|
|
|
1075
|
|
|
public function testInvalidCodeWillClearData() { |
1076
|
|
|
$code = 'code1'; |
1077
|
|
|
$methods_to_stub = array( |
1078
|
|
|
'getCode', |
1079
|
|
|
'getAccessTokenFromCode', |
1080
|
|
|
'clearAllPersistentData', |
1081
|
|
|
); |
1082
|
|
|
$constructor_args = array(array( |
1083
|
|
|
'appId' => self::APP_ID, |
1084
|
|
|
'secret' => self::SECRET |
1085
|
|
|
)); |
1086
|
|
|
$stub = $this->getMock( |
1087
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1088
|
|
|
$stub |
1089
|
|
|
->expects($this->once()) |
1090
|
|
|
->method('getCode') |
1091
|
|
|
->will($this->returnValue($code)); |
1092
|
|
|
$stub |
1093
|
|
|
->expects($this->once()) |
1094
|
|
|
->method('getAccessTokenFromCode') |
1095
|
|
|
->will($this->returnValue(null)); |
1096
|
|
|
$stub |
1097
|
|
|
->expects($this->once()) |
1098
|
|
|
->method('clearAllPersistentData'); |
1099
|
|
|
$this->assertEquals(self::APP_ID.'|'.self::SECRET, $stub->getAccessToken()); |
1100
|
|
|
} |
1101
|
|
|
|
1102
|
|
|
public function testValidCodeToToken() { |
1103
|
|
|
$code = 'code1'; |
1104
|
|
|
$access_token = 'at1'; |
1105
|
|
|
$methods_to_stub = array( |
1106
|
|
|
'getSignedRequest', |
1107
|
|
|
'getCode', |
1108
|
|
|
'getAccessTokenFromCode', |
1109
|
|
|
); |
1110
|
|
|
$constructor_args = array(array( |
1111
|
|
|
'appId' => self::APP_ID, |
1112
|
|
|
'secret' => self::SECRET |
1113
|
|
|
)); |
1114
|
|
|
$stub = $this->getMock( |
1115
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1116
|
|
|
$stub |
1117
|
|
|
->expects($this->once()) |
1118
|
|
|
->method('getCode') |
1119
|
|
|
->will($this->returnValue($code)); |
1120
|
|
|
$stub |
1121
|
|
|
->expects($this->once()) |
1122
|
|
|
->method('getAccessTokenFromCode') |
1123
|
|
|
->will($this->returnValueMap(array(array($code, null, $access_token)))); |
1124
|
|
|
$this->assertEquals($stub->getAccessToken(), $access_token); |
1125
|
|
|
} |
1126
|
|
|
|
1127
|
|
|
public function testSignedRequestWithoutAuthClearsDataInAvailData() { |
1128
|
|
|
$methods_to_stub = array('getSignedRequest', 'clearAllPersistentData'); |
1129
|
|
|
$constructor_args = array(array( |
1130
|
|
|
'appId' => self::APP_ID, |
1131
|
|
|
'secret' => self::SECRET |
1132
|
|
|
)); |
1133
|
|
|
$stub = $this->getMock( |
1134
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1135
|
|
|
$stub |
1136
|
|
|
->expects($this->once()) |
1137
|
|
|
->method('getSignedRequest') |
1138
|
|
|
->will($this->returnValue(array('foo' => 1))); |
1139
|
|
|
$stub |
1140
|
|
|
->expects($this->once()) |
1141
|
|
|
->method('clearAllPersistentData'); |
1142
|
|
|
$this->assertEquals(0, $stub->getUser()); |
1143
|
|
|
} |
1144
|
|
|
|
1145
|
|
|
public function testFailedToGetUserFromAccessTokenClearsData() { |
1146
|
|
|
$methods_to_stub = array( |
1147
|
|
|
'getAccessToken', |
1148
|
|
|
'getUserFromAccessToken', |
1149
|
|
|
'clearAllPersistentData', |
1150
|
|
|
); |
1151
|
|
|
$constructor_args = array(array( |
1152
|
|
|
'appId' => self::APP_ID, |
1153
|
|
|
'secret' => self::SECRET |
1154
|
|
|
)); |
1155
|
|
|
$stub = $this->getMock( |
1156
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1157
|
|
|
$stub |
1158
|
|
|
->expects($this->once()) |
1159
|
|
|
->method('getAccessToken') |
1160
|
|
|
->will($this->returnValue('at1')); |
1161
|
|
|
$stub |
1162
|
|
|
->expects($this->once()) |
1163
|
|
|
->method('getUserFromAccessToken'); |
1164
|
|
|
$stub |
1165
|
|
|
->expects($this->once()) |
1166
|
|
|
->method('clearAllPersistentData'); |
1167
|
|
|
$this->assertEquals(0, $stub->getUser()); |
1168
|
|
|
} |
1169
|
|
|
|
1170
|
|
|
public function testUserFromAccessTokenIsStored() { |
1171
|
|
|
$methods_to_stub = array( |
1172
|
|
|
'getAccessToken', |
1173
|
|
|
'getUserFromAccessToken', |
1174
|
|
|
'setPersistentData', |
1175
|
|
|
); |
1176
|
|
|
$constructor_args = array(array( |
1177
|
|
|
'appId' => self::APP_ID, |
1178
|
|
|
'secret' => self::SECRET |
1179
|
|
|
)); |
1180
|
|
|
$user = 42; |
1181
|
|
|
$stub = $this->getMock( |
1182
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1183
|
|
|
$stub |
1184
|
|
|
->expects($this->once()) |
1185
|
|
|
->method('getAccessToken') |
1186
|
|
|
->will($this->returnValue('at1')); |
1187
|
|
|
$stub |
1188
|
|
|
->expects($this->once()) |
1189
|
|
|
->method('getUserFromAccessToken') |
1190
|
|
|
->will($this->returnValue($user)); |
1191
|
|
|
$stub |
1192
|
|
|
->expects($this->once()) |
1193
|
|
|
->method('setPersistentData'); |
1194
|
|
|
$this->assertEquals($user, $stub->getUser()); |
1195
|
|
|
} |
1196
|
|
|
|
1197
|
|
|
public function testUserFromAccessTokenPullsID() { |
1198
|
|
|
$methods_to_stub = array( |
1199
|
|
|
'getAccessToken', |
1200
|
|
|
'api', |
1201
|
|
|
); |
1202
|
|
|
$constructor_args = array(array( |
1203
|
|
|
'appId' => self::APP_ID, |
1204
|
|
|
'secret' => self::SECRET |
1205
|
|
|
)); |
1206
|
|
|
$user = 42; |
1207
|
|
|
$stub = $this->getMock( |
1208
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1209
|
|
|
$stub |
1210
|
|
|
->expects($this->once()) |
1211
|
|
|
->method('getAccessToken') |
1212
|
|
|
->will($this->returnValue('at1')); |
1213
|
|
|
$stub |
1214
|
|
|
->expects($this->once()) |
1215
|
|
|
->method('api') |
1216
|
|
|
->will($this->returnValue(array('id' => $user))); |
1217
|
|
|
$this->assertEquals($user, $stub->getUser()); |
1218
|
|
|
} |
1219
|
|
|
|
1220
|
|
|
public function testUserFromAccessTokenResetsOnApiException() { |
1221
|
|
|
$methods_to_stub = array( |
1222
|
|
|
'getAccessToken', |
1223
|
|
|
'clearAllPersistentData', |
1224
|
|
|
'api', |
1225
|
|
|
); |
1226
|
|
|
$constructor_args = array(array( |
1227
|
|
|
'appId' => self::APP_ID, |
1228
|
|
|
'secret' => self::SECRET |
1229
|
|
|
)); |
1230
|
|
|
$stub = $this->getMock( |
1231
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1232
|
|
|
$stub |
1233
|
|
|
->expects($this->once()) |
1234
|
|
|
->method('getAccessToken') |
1235
|
|
|
->will($this->returnValue('at1')); |
1236
|
|
|
$stub |
1237
|
|
|
->expects($this->once()) |
1238
|
|
|
->method('api') |
1239
|
|
|
->will($this->throwException(new FacebookApiException(false))); |
1240
|
|
|
$stub |
1241
|
|
|
->expects($this->once()) |
1242
|
|
|
->method('clearAllPersistentData'); |
1243
|
|
|
$this->assertEquals(0, $stub->getUser()); |
1244
|
|
|
} |
1245
|
|
|
|
1246
|
|
|
public function testEmptyCodeReturnsFalse() { |
1247
|
|
|
$fb = new FBPublicGetAccessTokenFromCode(array( |
1248
|
|
|
'appId' => self::APP_ID, |
1249
|
|
|
'secret' => self::SECRET |
1250
|
|
|
)); |
1251
|
|
|
$this->assertFalse($fb->publicGetAccessTokenFromCode('')); |
1252
|
|
|
$this->assertFalse($fb->publicGetAccessTokenFromCode(null)); |
1253
|
|
|
$this->assertFalse($fb->publicGetAccessTokenFromCode(false)); |
1254
|
|
|
} |
1255
|
|
|
|
1256
|
|
|
public function testNullRedirectURIUsesCurrentURL() { |
1257
|
|
|
$methods_to_stub = array( |
1258
|
|
|
'_oauthRequest', |
1259
|
|
|
'getCurrentUrl', |
1260
|
|
|
); |
1261
|
|
|
$constructor_args = array(array( |
1262
|
|
|
'appId' => self::APP_ID, |
1263
|
|
|
'secret' => self::SECRET |
1264
|
|
|
)); |
1265
|
|
|
$access_token = 'at1'; |
1266
|
|
|
$stub = $this->getMock( |
1267
|
|
|
'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); |
1268
|
|
|
$stub |
1269
|
|
|
->expects($this->once()) |
1270
|
|
|
->method('_oauthRequest') |
1271
|
|
|
->will($this->returnValue("access_token=$access_token")); |
1272
|
|
|
$stub |
1273
|
|
|
->expects($this->once()) |
1274
|
|
|
->method('getCurrentUrl'); |
1275
|
|
|
$this->assertEquals( |
1276
|
|
|
$access_token, $stub->publicGetAccessTokenFromCode('c')); |
1277
|
|
|
} |
1278
|
|
|
|
1279
|
|
|
public function testNullRedirectURIAllowsEmptyStringForCookie() { |
1280
|
|
|
$methods_to_stub = array( |
1281
|
|
|
'_oauthRequest', |
1282
|
|
|
'getCurrentUrl', |
1283
|
|
|
); |
1284
|
|
|
$constructor_args = array(array( |
1285
|
|
|
'appId' => self::APP_ID, |
1286
|
|
|
'secret' => self::SECRET |
1287
|
|
|
)); |
1288
|
|
|
$access_token = 'at1'; |
1289
|
|
|
$stub = $this->getMock( |
1290
|
|
|
'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); |
1291
|
|
|
$stub |
1292
|
|
|
->expects($this->once()) |
1293
|
|
|
->method('_oauthRequest') |
1294
|
|
|
->will($this->returnValue("access_token=$access_token")); |
1295
|
|
|
$stub |
1296
|
|
|
->expects($this->never()) |
1297
|
|
|
->method('getCurrentUrl'); |
1298
|
|
|
$this->assertEquals( |
1299
|
|
|
$access_token, $stub->publicGetAccessTokenFromCode('c', '')); |
1300
|
|
|
} |
1301
|
|
|
|
1302
|
|
|
public function testAPIExceptionDuringCodeExchangeIsIgnored() { |
1303
|
|
|
$methods_to_stub = array( |
1304
|
|
|
'_oauthRequest', |
1305
|
|
|
); |
1306
|
|
|
$constructor_args = array(array( |
1307
|
|
|
'appId' => self::APP_ID, |
1308
|
|
|
'secret' => self::SECRET |
1309
|
|
|
)); |
1310
|
|
|
$stub = $this->getMock( |
1311
|
|
|
'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); |
1312
|
|
|
$stub |
1313
|
|
|
->expects($this->once()) |
1314
|
|
|
->method('_oauthRequest') |
1315
|
|
|
->will($this->throwException(new FacebookApiException(false))); |
1316
|
|
|
$this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); |
1317
|
|
|
} |
1318
|
|
|
|
1319
|
|
|
public function testEmptyResponseInCodeExchangeIsIgnored() { |
1320
|
|
|
$methods_to_stub = array( |
1321
|
|
|
'_oauthRequest', |
1322
|
|
|
); |
1323
|
|
|
$constructor_args = array(array( |
1324
|
|
|
'appId' => self::APP_ID, |
1325
|
|
|
'secret' => self::SECRET |
1326
|
|
|
)); |
1327
|
|
|
$stub = $this->getMock( |
1328
|
|
|
'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); |
1329
|
|
|
$stub |
1330
|
|
|
->expects($this->once()) |
1331
|
|
|
->method('_oauthRequest') |
1332
|
|
|
->will($this->returnValue('')); |
1333
|
|
|
$this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); |
1334
|
|
|
} |
1335
|
|
|
|
1336
|
|
|
public function testExistingStateRestoredInConstructor() { |
1337
|
|
|
$fb = new FBPublicState(array( |
1338
|
|
|
'appId' => self::APP_ID, |
1339
|
|
|
'secret' => self::SECRET |
1340
|
|
|
)); |
1341
|
|
|
$this->assertEquals(FBPublicState::STATE, $fb->publicGetState()); |
1342
|
|
|
} |
1343
|
|
|
|
1344
|
|
|
public function testMissingAccessTokenInCodeExchangeIsIgnored() { |
1345
|
|
|
$methods_to_stub = array( |
1346
|
|
|
'_oauthRequest', |
1347
|
|
|
); |
1348
|
|
|
$constructor_args = array(array( |
1349
|
|
|
'appId' => self::APP_ID, |
1350
|
|
|
'secret' => self::SECRET |
1351
|
|
|
)); |
1352
|
|
|
$stub = $this->getMock( |
1353
|
|
|
'FBPublicGetAccessTokenFromCode', $methods_to_stub, $constructor_args); |
1354
|
|
|
$stub |
1355
|
|
|
->expects($this->once()) |
1356
|
|
|
->method('_oauthRequest') |
1357
|
|
|
->will($this->returnValue('foo=1')); |
1358
|
|
|
$this->assertFalse($stub->publicGetAccessTokenFromCode('c', '')); |
1359
|
|
|
} |
1360
|
|
|
|
1361
|
|
|
public function testAppsecretProofNoParams() { |
1362
|
|
|
$fb = new FBRecordMakeRequest(array( |
1363
|
|
|
'appId' => self::APP_ID, |
1364
|
|
|
'secret' => self::SECRET, |
1365
|
|
|
)); |
1366
|
|
|
$token = $fb->getAccessToken(); |
1367
|
|
|
$proof = $fb->publicGetAppSecretProof($token); |
1368
|
|
|
$params = array(); |
1369
|
|
|
$fb->api('/mattynoce', $params); |
1370
|
|
|
$requests = $fb->publicGetRequests(); |
1371
|
|
|
$this->assertEquals($proof, $requests[0]['params']['appsecret_proof']); |
1372
|
|
|
} |
1373
|
|
|
|
1374
|
|
|
public function testAppsecretProofWithParams() { |
1375
|
|
|
$fb = new FBRecordMakeRequest(array( |
1376
|
|
|
'appId' => self::APP_ID, |
1377
|
|
|
'secret' => self::SECRET, |
1378
|
|
|
)); |
1379
|
|
|
$proof = 'foo'; |
1380
|
|
|
$params = array('appsecret_proof' => $proof); |
1381
|
|
|
$fb->api('/mattynoce', $params); |
1382
|
|
|
$requests = $fb->publicGetRequests(); |
1383
|
|
|
$this->assertEquals($proof, $requests[0]['params']['appsecret_proof']); |
1384
|
|
|
} |
1385
|
|
|
|
1386
|
|
|
public function testExceptionConstructorWithErrorCode() { |
1387
|
|
|
$code = 404; |
1388
|
|
|
$e = new FacebookApiException(array('error_code' => $code)); |
1389
|
|
|
$this->assertEquals($code, $e->getCode()); |
1390
|
|
|
} |
1391
|
|
|
|
1392
|
|
|
public function testExceptionConstructorWithInvalidErrorCode() { |
1393
|
|
|
$e = new FacebookApiException(array('error_code' => 'not an int')); |
1394
|
|
|
$this->assertEquals(0, $e->getCode()); |
1395
|
|
|
} |
1396
|
|
|
|
1397
|
|
|
// this happens often despite the fact that it is useless |
1398
|
|
|
public function testExceptionTypeFalse() { |
1399
|
|
|
$e = new FacebookApiException(false); |
1400
|
|
|
$this->assertEquals('Exception', $e->getType()); |
1401
|
|
|
} |
1402
|
|
|
|
1403
|
|
|
public function testExceptionTypeMixedDraft00() { |
1404
|
|
|
$e = new FacebookApiException(array('error' => array('message' => 'foo'))); |
1405
|
|
|
$this->assertEquals('Exception', $e->getType()); |
1406
|
|
|
} |
1407
|
|
|
|
1408
|
|
|
public function testExceptionTypeDraft00() { |
1409
|
|
|
$error = 'foo'; |
1410
|
|
|
$e = new FacebookApiException( |
1411
|
|
|
array('error' => array('type' => $error, 'message' => 'hello world'))); |
1412
|
|
|
$this->assertEquals($error, $e->getType()); |
1413
|
|
|
} |
1414
|
|
|
|
1415
|
|
|
public function testExceptionTypeDraft10() { |
1416
|
|
|
$error = 'foo'; |
1417
|
|
|
$e = new FacebookApiException(array('error' => $error)); |
1418
|
|
|
$this->assertEquals($error, $e->getType()); |
1419
|
|
|
} |
1420
|
|
|
|
1421
|
|
|
public function testExceptionTypeDefault() { |
1422
|
|
|
$e = new FacebookApiException(array('error' => false)); |
1423
|
|
|
$this->assertEquals('Exception', $e->getType()); |
1424
|
|
|
} |
1425
|
|
|
|
1426
|
|
|
public function testExceptionToString() { |
1427
|
|
|
$e = new FacebookApiException(array( |
1428
|
|
|
'error_code' => 1, |
1429
|
|
|
'error_description' => 'foo', |
1430
|
|
|
)); |
1431
|
|
|
$this->assertEquals('Exception: 1: foo', (string) $e); |
1432
|
|
|
} |
1433
|
|
|
|
1434
|
|
|
public function testDestroyClearsCookie() { |
1435
|
|
|
$fb = new FBPublicCookie(array( |
1436
|
|
|
'appId' => self::APP_ID, |
1437
|
|
|
'secret' => self::SECRET, |
1438
|
|
|
)); |
1439
|
|
|
$_COOKIE[$fb->publicGetSignedRequestCookieName()] = 'foo'; |
1440
|
|
|
$_COOKIE[$fb->publicGetMetadataCookieName()] = 'base_domain=fbrell.com'; |
1441
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1442
|
|
|
$fb->destroySession(); |
1443
|
|
|
$this->assertFalse( |
1444
|
|
|
array_key_exists($fb->publicGetSignedRequestCookieName(), $_COOKIE)); |
1445
|
|
|
} |
1446
|
|
|
|
1447
|
|
|
public function testAuthExpireSessionDestroysSession() { |
1448
|
|
|
$methods_to_stub = array( |
1449
|
|
|
'_oauthRequest', |
1450
|
|
|
'destroySession', |
1451
|
|
|
); |
1452
|
|
|
$constructor_args = array(array( |
1453
|
|
|
'appId' => self::APP_ID, |
1454
|
|
|
'secret' => self::SECRET |
1455
|
|
|
)); |
1456
|
|
|
$key = 'foo'; |
1457
|
|
|
$val = 42; |
1458
|
|
|
$stub = $this->getMock( |
1459
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1460
|
|
|
$stub |
1461
|
|
|
->expects($this->once()) |
1462
|
|
|
->method('_oauthRequest') |
1463
|
|
|
->will($this->returnValue("{\"$key\":$val}")); |
1464
|
|
|
$stub |
1465
|
|
|
->expects($this->once()) |
1466
|
|
|
->method('destroySession'); |
1467
|
|
|
$this->assertEquals( |
1468
|
|
|
array($key => $val), |
1469
|
|
|
$stub->api(array('method' => 'auth.expireSession')) |
1470
|
|
|
); |
1471
|
|
|
} |
1472
|
|
|
|
1473
|
|
|
public function testLowercaseAuthRevokeAuthDestroysSession() { |
1474
|
|
|
$methods_to_stub = array( |
1475
|
|
|
'_oauthRequest', |
1476
|
|
|
'destroySession', |
1477
|
|
|
); |
1478
|
|
|
$constructor_args = array(array( |
1479
|
|
|
'appId' => self::APP_ID, |
1480
|
|
|
'secret' => self::SECRET |
1481
|
|
|
)); |
1482
|
|
|
$key = 'foo'; |
1483
|
|
|
$val = 42; |
1484
|
|
|
$stub = $this->getMock( |
1485
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1486
|
|
|
$stub |
1487
|
|
|
->expects($this->once()) |
1488
|
|
|
->method('_oauthRequest') |
1489
|
|
|
->will($this->returnValue("{\"$key\":$val}")); |
1490
|
|
|
$stub |
1491
|
|
|
->expects($this->once()) |
1492
|
|
|
->method('destroySession'); |
1493
|
|
|
$this->assertEquals( |
1494
|
|
|
array($key => $val), |
1495
|
|
|
$stub->api(array('method' => 'auth.revokeauthorization')) |
1496
|
|
|
); |
1497
|
|
|
} |
1498
|
|
|
|
1499
|
|
|
/** |
1500
|
|
|
* @expectedException FacebookAPIException |
1501
|
|
|
*/ |
1502
|
|
|
public function testErrorCodeFromRestAPIThrowsException() { |
1503
|
|
|
$methods_to_stub = array( |
1504
|
|
|
'_oauthRequest', |
1505
|
|
|
); |
1506
|
|
|
$constructor_args = array(array( |
1507
|
|
|
'appId' => self::APP_ID, |
1508
|
|
|
'secret' => self::SECRET |
1509
|
|
|
)); |
1510
|
|
|
$stub = $this->getMock( |
1511
|
|
|
'TransientFacebook', $methods_to_stub, $constructor_args); |
1512
|
|
|
$stub |
1513
|
|
|
->expects($this->once()) |
1514
|
|
|
->method('_oauthRequest') |
1515
|
|
|
->will($this->returnValue('{"error_code": 500}')); |
1516
|
|
|
$stub->api(array('method' => 'foo')); |
1517
|
|
|
} |
1518
|
|
|
|
1519
|
|
|
public function testJsonEncodeOfNonStringParams() { |
1520
|
|
|
$foo = array(1, 2); |
1521
|
|
|
$params = array( |
1522
|
|
|
'method' => 'get', |
1523
|
|
|
'foo' => $foo, |
1524
|
|
|
); |
1525
|
|
|
$fb = new FBRecordMakeRequest(array( |
1526
|
|
|
'appId' => self::APP_ID, |
1527
|
|
|
'secret' => self::SECRET, |
1528
|
|
|
)); |
1529
|
|
|
$fb->api('/naitik', $params); |
1530
|
|
|
$requests = $fb->publicGetRequests(); |
1531
|
|
|
$this->assertEquals(json_encode($foo), $requests[0]['params']['foo']); |
1532
|
|
|
} |
1533
|
|
|
|
1534
|
|
|
public function testSessionBackedFacebook() { |
1535
|
|
|
$fb = new PersistentFBPublic(array( |
1536
|
|
|
'appId' => self::APP_ID, |
1537
|
|
|
'secret' => self::SECRET, |
1538
|
|
|
)); |
1539
|
|
|
$key = 'state'; |
1540
|
|
|
$val = 'foo'; |
1541
|
|
|
$fb->publicSetPersistentData($key, $val); |
1542
|
|
|
$this->assertEquals( |
1543
|
|
|
$val, |
1544
|
|
|
$_SESSION[sprintf('fb_%s_%s', self::APP_ID, $key)] |
1545
|
|
|
); |
1546
|
|
|
$this->assertEquals( |
1547
|
|
|
$val, |
1548
|
|
|
$fb->publicGetPersistentData($key) |
1549
|
|
|
); |
1550
|
|
|
} |
1551
|
|
|
|
1552
|
|
|
public function testSessionBackedFacebookIgnoresUnsupportedKey() { |
1553
|
|
|
$fb = new PersistentFBPublic(array( |
1554
|
|
|
'appId' => self::APP_ID, |
1555
|
|
|
'secret' => self::SECRET, |
1556
|
|
|
)); |
1557
|
|
|
$key = '--invalid--'; |
1558
|
|
|
$val = 'foo'; |
1559
|
|
|
$fb->publicSetPersistentData($key, $val); |
1560
|
|
|
$this->assertFalse( |
1561
|
|
|
array_key_exists( |
1562
|
|
|
sprintf('fb_%s_%s', self::APP_ID, $key), |
1563
|
|
|
$_SESSION |
1564
|
|
|
) |
1565
|
|
|
); |
1566
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1567
|
|
|
} |
1568
|
|
|
|
1569
|
|
|
public function testClearSessionBackedFacebook() { |
1570
|
|
|
$fb = new PersistentFBPublic(array( |
1571
|
|
|
'appId' => self::APP_ID, |
1572
|
|
|
'secret' => self::SECRET, |
1573
|
|
|
)); |
1574
|
|
|
$key = 'state'; |
1575
|
|
|
$val = 'foo'; |
1576
|
|
|
$fb->publicSetPersistentData($key, $val); |
1577
|
|
|
$this->assertEquals( |
1578
|
|
|
$val, |
1579
|
|
|
$_SESSION[sprintf('fb_%s_%s', self::APP_ID, $key)] |
1580
|
|
|
); |
1581
|
|
|
$this->assertEquals( |
1582
|
|
|
$val, |
1583
|
|
|
$fb->publicGetPersistentData($key) |
1584
|
|
|
); |
1585
|
|
|
$fb->publicClearPersistentData($key); |
1586
|
|
|
$this->assertFalse( |
1587
|
|
|
array_key_exists( |
1588
|
|
|
sprintf('fb_%s_%s', self::APP_ID, $key), |
1589
|
|
|
$_SESSION |
1590
|
|
|
) |
1591
|
|
|
); |
1592
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1593
|
|
|
} |
1594
|
|
|
|
1595
|
|
|
public function testSessionBackedFacebookIgnoresUnsupportedKeyInClear() { |
1596
|
|
|
$fb = new PersistentFBPublic(array( |
1597
|
|
|
'appId' => self::APP_ID, |
1598
|
|
|
'secret' => self::SECRET, |
1599
|
|
|
)); |
1600
|
|
|
$key = '--invalid--'; |
1601
|
|
|
$val = 'foo'; |
1602
|
|
|
$session_var_name = sprintf('fb_%s_%s', self::APP_ID, $key); |
1603
|
|
|
$_SESSION[$session_var_name] = $val; |
1604
|
|
|
$fb->publicClearPersistentData($key); |
1605
|
|
|
$this->assertTrue(array_key_exists($session_var_name, $_SESSION)); |
1606
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1607
|
|
|
} |
1608
|
|
|
|
1609
|
|
|
public function testClearAllSessionBackedFacebook() { |
1610
|
|
|
$fb = new PersistentFBPublic(array( |
1611
|
|
|
'appId' => self::APP_ID, |
1612
|
|
|
'secret' => self::SECRET, |
1613
|
|
|
)); |
1614
|
|
|
$key = 'state'; |
1615
|
|
|
$val = 'foo'; |
1616
|
|
|
$session_var_name = sprintf('fb_%s_%s', self::APP_ID, $key); |
1617
|
|
|
$fb->publicSetPersistentData($key, $val); |
1618
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1619
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1620
|
|
|
$fb->publicClearAllPersistentData(); |
1621
|
|
|
$this->assertFalse(array_key_exists($session_var_name, $_SESSION)); |
1622
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1623
|
|
|
} |
1624
|
|
|
|
1625
|
|
|
public function testSharedSessionBackedFacebook() { |
1626
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1627
|
|
|
$fb = new PersistentFBPublic(array( |
1628
|
|
|
'appId' => self::APP_ID, |
1629
|
|
|
'secret' => self::SECRET, |
1630
|
|
|
'sharedSession' => true, |
1631
|
|
|
)); |
1632
|
|
|
$key = 'state'; |
1633
|
|
|
$val = 'foo'; |
1634
|
|
|
$session_var_name = sprintf( |
1635
|
|
|
'%s_fb_%s_%s', |
1636
|
|
|
$fb->publicGetSharedSessionID(), |
1637
|
|
|
self::APP_ID, |
1638
|
|
|
$key |
1639
|
|
|
); |
1640
|
|
|
$fb->publicSetPersistentData($key, $val); |
1641
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1642
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1643
|
|
|
} |
1644
|
|
|
|
1645
|
|
|
public function testSharedSessionBackedFacebookIgnoresUnsupportedKey() { |
1646
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1647
|
|
|
$fb = new PersistentFBPublic(array( |
1648
|
|
|
'appId' => self::APP_ID, |
1649
|
|
|
'secret' => self::SECRET, |
1650
|
|
|
'sharedSession' => true, |
1651
|
|
|
)); |
1652
|
|
|
$key = '--invalid--'; |
1653
|
|
|
$val = 'foo'; |
1654
|
|
|
$session_var_name = sprintf( |
1655
|
|
|
'%s_fb_%s_%s', |
1656
|
|
|
$fb->publicGetSharedSessionID(), |
1657
|
|
|
self::APP_ID, |
1658
|
|
|
$key |
1659
|
|
|
); |
1660
|
|
|
$fb->publicSetPersistentData($key, $val); |
1661
|
|
|
$this->assertFalse(array_key_exists($session_var_name, $_SESSION)); |
1662
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1663
|
|
|
} |
1664
|
|
|
|
1665
|
|
|
public function testSharedClearSessionBackedFacebook() { |
1666
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1667
|
|
|
$fb = new PersistentFBPublic(array( |
1668
|
|
|
'appId' => self::APP_ID, |
1669
|
|
|
'secret' => self::SECRET, |
1670
|
|
|
'sharedSession' => true, |
1671
|
|
|
)); |
1672
|
|
|
$key = 'state'; |
1673
|
|
|
$val = 'foo'; |
1674
|
|
|
$session_var_name = sprintf( |
1675
|
|
|
'%s_fb_%s_%s', |
1676
|
|
|
$fb->publicGetSharedSessionID(), |
1677
|
|
|
self::APP_ID, |
1678
|
|
|
$key |
1679
|
|
|
); |
1680
|
|
|
$fb->publicSetPersistentData($key, $val); |
1681
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1682
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1683
|
|
|
$fb->publicClearPersistentData($key); |
1684
|
|
|
$this->assertFalse(array_key_exists($session_var_name, $_SESSION)); |
1685
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1686
|
|
|
} |
1687
|
|
|
|
1688
|
|
|
public function testSharedSessionBackedFacebookIgnoresUnsupportedKeyInClear() { |
1689
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1690
|
|
|
$fb = new PersistentFBPublic(array( |
1691
|
|
|
'appId' => self::APP_ID, |
1692
|
|
|
'secret' => self::SECRET, |
1693
|
|
|
'sharedSession' => true, |
1694
|
|
|
)); |
1695
|
|
|
$key = '--invalid--'; |
1696
|
|
|
$val = 'foo'; |
1697
|
|
|
$session_var_name = sprintf( |
1698
|
|
|
'%s_fb_%s_%s', |
1699
|
|
|
$fb->publicGetSharedSessionID(), |
1700
|
|
|
self::APP_ID, |
1701
|
|
|
$key |
1702
|
|
|
); |
1703
|
|
|
$_SESSION[$session_var_name] = $val; |
1704
|
|
|
$fb->publicClearPersistentData($key); |
1705
|
|
|
$this->assertTrue(array_key_exists($session_var_name, $_SESSION)); |
1706
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1707
|
|
|
} |
1708
|
|
|
|
1709
|
|
|
public function testSharedClearAllSessionBackedFacebook() { |
1710
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1711
|
|
|
$fb = new PersistentFBPublic(array( |
1712
|
|
|
'appId' => self::APP_ID, |
1713
|
|
|
'secret' => self::SECRET, |
1714
|
|
|
'sharedSession' => true, |
1715
|
|
|
)); |
1716
|
|
|
$key = 'state'; |
1717
|
|
|
$val = 'foo'; |
1718
|
|
|
$session_var_name = sprintf( |
1719
|
|
|
'%s_fb_%s_%s', |
1720
|
|
|
$fb->publicGetSharedSessionID(), |
1721
|
|
|
self::APP_ID, |
1722
|
|
|
$key |
1723
|
|
|
); |
1724
|
|
|
$fb->publicSetPersistentData($key, $val); |
1725
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1726
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1727
|
|
|
$fb->publicClearAllPersistentData(); |
1728
|
|
|
$this->assertFalse(array_key_exists($session_var_name, $_SESSION)); |
1729
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1730
|
|
|
} |
1731
|
|
|
|
1732
|
|
|
public function testSharedSessionBackedFacebookIsRestored() { |
1733
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1734
|
|
|
$fb = new PersistentFBPublic(array( |
1735
|
|
|
'appId' => self::APP_ID, |
1736
|
|
|
'secret' => self::SECRET, |
1737
|
|
|
'sharedSession' => true, |
1738
|
|
|
)); |
1739
|
|
|
$key = 'state'; |
1740
|
|
|
$val = 'foo'; |
1741
|
|
|
$shared_session_id = $fb->publicGetSharedSessionID(); |
1742
|
|
|
$session_var_name = sprintf( |
1743
|
|
|
'%s_fb_%s_%s', |
1744
|
|
|
$shared_session_id, |
1745
|
|
|
self::APP_ID, |
1746
|
|
|
$key |
1747
|
|
|
); |
1748
|
|
|
$fb->publicSetPersistentData($key, $val); |
1749
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1750
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1751
|
|
|
|
1752
|
|
|
// check the new instance has the same data |
1753
|
|
|
$fb = new PersistentFBPublic(array( |
1754
|
|
|
'appId' => self::APP_ID, |
1755
|
|
|
'secret' => self::SECRET, |
1756
|
|
|
'sharedSession' => true, |
1757
|
|
|
)); |
1758
|
|
|
$this->assertEquals( |
1759
|
|
|
$shared_session_id, |
1760
|
|
|
$fb->publicGetSharedSessionID() |
1761
|
|
|
); |
1762
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1763
|
|
|
} |
1764
|
|
|
|
1765
|
|
|
public function testSharedSessionBackedFacebookIsNotRestoredWhenCorrupt() { |
1766
|
|
|
$_SERVER['HTTP_HOST'] = 'fbrell.com'; |
1767
|
|
|
$fb = new PersistentFBPublic(array( |
1768
|
|
|
'appId' => self::APP_ID, |
1769
|
|
|
'secret' => self::SECRET, |
1770
|
|
|
'sharedSession' => true, |
1771
|
|
|
)); |
1772
|
|
|
$key = 'state'; |
1773
|
|
|
$val = 'foo'; |
1774
|
|
|
$shared_session_id = $fb->publicGetSharedSessionID(); |
1775
|
|
|
$session_var_name = sprintf( |
1776
|
|
|
'%s_fb_%s_%s', |
1777
|
|
|
$shared_session_id, |
1778
|
|
|
self::APP_ID, |
1779
|
|
|
$key |
1780
|
|
|
); |
1781
|
|
|
$fb->publicSetPersistentData($key, $val); |
1782
|
|
|
$this->assertEquals($val, $_SESSION[$session_var_name]); |
1783
|
|
|
$this->assertEquals($val, $fb->publicGetPersistentData($key)); |
1784
|
|
|
|
1785
|
|
|
// break the cookie |
1786
|
|
|
$cookie_name = $fb->publicGetSharedSessionCookieName(); |
1787
|
|
|
$_COOKIE[$cookie_name] = substr($_COOKIE[$cookie_name], 1); |
1788
|
|
|
|
1789
|
|
|
// check the new instance does not have the data |
1790
|
|
|
$fb = new PersistentFBPublic(array( |
1791
|
|
|
'appId' => self::APP_ID, |
1792
|
|
|
'secret' => self::SECRET, |
1793
|
|
|
'sharedSession' => true, |
1794
|
|
|
)); |
1795
|
|
|
$this->assertFalse($fb->publicGetPersistentData($key)); |
1796
|
|
|
$this->assertNotEquals( |
1797
|
|
|
$shared_session_id, |
1798
|
|
|
$fb->publicGetSharedSessionID() |
1799
|
|
|
); |
1800
|
|
|
} |
1801
|
|
|
|
1802
|
|
|
public function testHttpHost() { |
1803
|
|
|
$real = 'foo.com'; |
1804
|
|
|
$_SERVER['HTTP_HOST'] = $real; |
1805
|
|
|
$_SERVER['HTTP_X_FORWARDED_HOST'] = 'evil.com'; |
1806
|
|
|
$fb = new PersistentFBPublic(array( |
1807
|
|
|
'appId' => self::APP_ID, |
1808
|
|
|
'secret' => self::SECRET, |
1809
|
|
|
)); |
1810
|
|
|
$this->assertEquals($real, $fb->publicGetHttpHost()); |
1811
|
|
|
} |
1812
|
|
|
|
1813
|
|
|
public function testHttpProtocol() { |
1814
|
|
|
$_SERVER['HTTPS'] = 'on'; |
1815
|
|
|
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; |
1816
|
|
|
$fb = new PersistentFBPublic(array( |
1817
|
|
|
'appId' => self::APP_ID, |
1818
|
|
|
'secret' => self::SECRET, |
1819
|
|
|
)); |
1820
|
|
|
$this->assertEquals('https', $fb->publicGetHttpProtocol()); |
1821
|
|
|
} |
1822
|
|
|
|
1823
|
|
|
public function testHttpHostForwarded() { |
1824
|
|
|
$real = 'foo.com'; |
1825
|
|
|
$_SERVER['HTTP_HOST'] = 'localhost'; |
1826
|
|
|
$_SERVER['HTTP_X_FORWARDED_HOST'] = $real; |
1827
|
|
|
$fb = new PersistentFBPublic(array( |
1828
|
|
|
'appId' => self::APP_ID, |
1829
|
|
|
'secret' => self::SECRET, |
1830
|
|
|
'trustForwarded' => true, |
1831
|
|
|
)); |
1832
|
|
|
$this->assertEquals($real, $fb->publicGetHttpHost()); |
1833
|
|
|
} |
1834
|
|
|
|
1835
|
|
|
public function testHttpProtocolForwarded() { |
1836
|
|
|
$_SERVER['HTTPS'] = 'on'; |
1837
|
|
|
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'http'; |
1838
|
|
|
$fb = new PersistentFBPublic(array( |
1839
|
|
|
'appId' => self::APP_ID, |
1840
|
|
|
'secret' => self::SECRET, |
1841
|
|
|
'trustForwarded' => true, |
1842
|
|
|
)); |
1843
|
|
|
$this->assertEquals('http', $fb->publicGetHttpProtocol()); |
1844
|
|
|
} |
1845
|
|
|
|
1846
|
|
|
public function testHttpProtocolForwardedSecure() { |
1847
|
|
|
$_SERVER['HTTPS'] = 'on'; |
1848
|
|
|
$_SERVER['HTTP_X_FORWARDED_PROTO'] = 'https'; |
1849
|
|
|
$fb = new PersistentFBPublic(array( |
1850
|
|
|
'appId' => self::APP_ID, |
1851
|
|
|
'secret' => self::SECRET, |
1852
|
|
|
'trustForwarded' => true, |
1853
|
|
|
)); |
1854
|
|
|
$this->assertEquals('https', $fb->publicGetHttpProtocol()); |
1855
|
|
|
} |
1856
|
|
|
|
1857
|
|
|
/** |
1858
|
|
|
* @dataProvider provideEndsWith |
1859
|
|
|
*/ |
1860
|
|
|
public function testEndsWith($big, $small, $result) { |
1861
|
|
|
$this->assertEquals( |
1862
|
|
|
$result, |
1863
|
|
|
PersistentFBPublic::publicEndsWith($big, $small) |
1864
|
|
|
); |
1865
|
|
|
} |
1866
|
|
|
|
1867
|
|
|
public function provideEndsWith() { |
1868
|
|
|
return array( |
1869
|
|
|
array('', '', true), |
1870
|
|
|
array('', 'a', false), |
1871
|
|
|
array('a', '', true), |
1872
|
|
|
array('a', 'b', false), |
1873
|
|
|
array('a', 'a', true), |
1874
|
|
|
array('aa', 'a', true), |
1875
|
|
|
array('ab', 'a', false), |
1876
|
|
|
array('ba', 'a', true), |
1877
|
|
|
); |
1878
|
|
|
} |
1879
|
|
|
|
1880
|
|
|
/** |
1881
|
|
|
* @dataProvider provideIsAllowedDomain |
1882
|
|
|
*/ |
1883
|
|
|
public function testIsAllowedDomain($big, $small, $result) { |
1884
|
|
|
$this->assertEquals( |
1885
|
|
|
$result, |
1886
|
|
|
PersistentFBPublic::publicIsAllowedDomain($big, $small) |
1887
|
|
|
); |
1888
|
|
|
} |
1889
|
|
|
|
1890
|
|
|
public function provideIsAllowedDomain() { |
1891
|
|
|
return array( |
1892
|
|
|
array('fbrell.com', 'fbrell.com', true), |
1893
|
|
|
array('foo.fbrell.com', 'fbrell.com', true), |
1894
|
|
|
array('foofbrell.com', 'fbrell.com', false), |
1895
|
|
|
array('evil.com', 'fbrell.com', false), |
1896
|
|
|
array('foo.fbrell.com', 'bar.fbrell.com', false), |
1897
|
|
|
); |
1898
|
|
|
} |
1899
|
|
|
|
1900
|
|
|
protected function generateMD5HashOfRandomValue() { |
1901
|
|
|
return md5(uniqid(mt_rand(), true)); |
1902
|
|
|
} |
1903
|
|
|
|
1904
|
|
|
protected function setUp() { |
1905
|
|
|
parent::setUp(); |
1906
|
|
|
} |
1907
|
|
|
|
1908
|
|
|
protected function tearDown() { |
1909
|
|
|
$this->clearSuperGlobals(); |
1910
|
|
|
parent::tearDown(); |
1911
|
|
|
} |
1912
|
|
|
|
1913
|
|
|
protected function clearSuperGlobals() { |
1914
|
|
|
unset($_SERVER['HTTPS']); |
1915
|
|
|
unset($_SERVER['HTTP_HOST']); |
1916
|
|
|
unset($_SERVER['REQUEST_URI']); |
1917
|
|
|
$_SESSION = array(); |
1918
|
|
|
$_COOKIE = array(); |
1919
|
|
|
$_REQUEST = array(); |
1920
|
|
|
$_POST = array(); |
1921
|
|
|
$_GET = array(); |
1922
|
|
|
if (session_id()) { |
1923
|
|
|
session_destroy(); |
1924
|
|
|
} |
1925
|
|
|
} |
1926
|
|
|
|
1927
|
|
|
/** |
1928
|
|
|
* Checks that the correct args are a subset of the returned obj |
1929
|
|
|
* @param array $correct The correct array values |
1930
|
|
|
* @param array $actual The values in practice |
1931
|
|
|
* @param string $message to be shown on failure |
|
|
|
|
1932
|
|
|
*/ |
1933
|
|
|
protected function assertIsSubset($correct, $actual, $msg='') { |
1934
|
|
|
foreach ($correct as $key => $value) { |
1935
|
|
|
$actual_value = $actual[$key]; |
1936
|
|
|
$newMsg = (strlen($msg) ? ($msg.' ') : '').'Key: '.$key; |
1937
|
|
|
$this->assertEquals($value, $actual_value, $newMsg); |
1938
|
|
|
} |
1939
|
|
|
} |
1940
|
|
|
} |
1941
|
|
|
|
1942
|
|
|
class TransientFacebook extends BaseFacebook { |
|
|
|
|
1943
|
|
|
protected function setPersistentData($key, $value) {} |
1944
|
|
|
protected function getPersistentData($key, $default = false) { |
1945
|
|
|
return $default; |
1946
|
|
|
} |
1947
|
|
|
protected function clearPersistentData($key) {} |
1948
|
|
|
protected function clearAllPersistentData() {} |
1949
|
|
|
} |
1950
|
|
|
|
1951
|
|
|
class FBRecordURL extends TransientFacebook { |
|
|
|
|
1952
|
|
|
private $url; |
1953
|
|
|
|
1954
|
|
|
protected function _oauthRequest($url, $params) { |
1955
|
|
|
$this->url = $url; |
1956
|
|
|
} |
1957
|
|
|
|
1958
|
|
|
public function getRequestedURL() { |
1959
|
|
|
return $this->url; |
1960
|
|
|
} |
1961
|
|
|
} |
1962
|
|
|
|
1963
|
|
|
class FBRecordMakeRequest extends TransientFacebook { |
|
|
|
|
1964
|
|
|
private $requests = array(); |
1965
|
|
|
|
1966
|
|
|
protected function makeRequest($url, $params, $ch=null) { |
1967
|
|
|
$this->requests[] = array( |
1968
|
|
|
'url' => $url, |
1969
|
|
|
'params' => $params, |
1970
|
|
|
); |
1971
|
|
|
return parent::makeRequest($url, $params, $ch); |
1972
|
|
|
} |
1973
|
|
|
|
1974
|
|
|
public function publicGetRequests() { |
1975
|
|
|
return $this->requests; |
1976
|
|
|
} |
1977
|
|
|
|
1978
|
|
|
public function publicGetAppSecretProof($access_token) { |
1979
|
|
|
return $this->getAppSecretProof($access_token); |
1980
|
|
|
} |
1981
|
|
|
} |
1982
|
|
|
|
1983
|
|
|
class FBPublic extends TransientFacebook { |
|
|
|
|
1984
|
|
|
public static function publicBase64UrlDecode($input) { |
1985
|
|
|
return self::base64UrlDecode($input); |
1986
|
|
|
} |
1987
|
|
|
public static function publicBase64UrlEncode($input) { |
1988
|
|
|
return self::base64UrlEncode($input); |
1989
|
|
|
} |
1990
|
|
|
public function publicParseSignedRequest($input) { |
1991
|
|
|
return $this->parseSignedRequest($input); |
1992
|
|
|
} |
1993
|
|
|
public function publicMakeSignedRequest($data) { |
1994
|
|
|
return $this->makeSignedRequest($data); |
1995
|
|
|
} |
1996
|
|
|
} |
1997
|
|
|
|
1998
|
|
|
class PersistentFBPublic extends Facebook { |
|
|
|
|
1999
|
|
|
public function publicParseSignedRequest($input) { |
2000
|
|
|
return $this->parseSignedRequest($input); |
2001
|
|
|
} |
2002
|
|
|
|
2003
|
|
|
public function publicSetPersistentData($key, $value) { |
2004
|
|
|
$this->setPersistentData($key, $value); |
2005
|
|
|
} |
2006
|
|
|
|
2007
|
|
|
public function publicGetPersistentData($key, $default = false) { |
2008
|
|
|
return $this->getPersistentData($key, $default); |
2009
|
|
|
} |
2010
|
|
|
|
2011
|
|
|
public function publicClearPersistentData($key) { |
2012
|
|
|
return $this->clearPersistentData($key); |
2013
|
|
|
} |
2014
|
|
|
|
2015
|
|
|
public function publicClearAllPersistentData() { |
2016
|
|
|
return $this->clearAllPersistentData(); |
2017
|
|
|
} |
2018
|
|
|
|
2019
|
|
|
public function publicGetSharedSessionID() { |
2020
|
|
|
return $this->sharedSessionID; |
2021
|
|
|
} |
2022
|
|
|
|
2023
|
|
|
public static function publicIsAllowedDomain($big, $small) { |
2024
|
|
|
return self::isAllowedDomain($big, $small); |
2025
|
|
|
} |
2026
|
|
|
|
2027
|
|
|
public static function publicEndsWith($big, $small) { |
2028
|
|
|
return self::endsWith($big, $small); |
2029
|
|
|
} |
2030
|
|
|
|
2031
|
|
|
public function publicGetSharedSessionCookieName() { |
2032
|
|
|
return $this->getSharedSessionCookieName(); |
2033
|
|
|
} |
2034
|
|
|
|
2035
|
|
|
public function publicGetHttpHost() { |
2036
|
|
|
return $this->getHttpHost(); |
2037
|
|
|
} |
2038
|
|
|
|
2039
|
|
|
public function publicGetHttpProtocol() { |
2040
|
|
|
return $this->getHttpProtocol(); |
2041
|
|
|
} |
2042
|
|
|
} |
2043
|
|
|
|
2044
|
|
|
class FBCode extends Facebook { |
|
|
|
|
2045
|
|
|
public function publicGetCode() { |
2046
|
|
|
return $this->getCode(); |
2047
|
|
|
} |
2048
|
|
|
|
2049
|
|
|
public function publicGetState() { |
2050
|
|
|
return $this->state; |
2051
|
|
|
} |
2052
|
|
|
|
2053
|
|
|
public function setCSRFStateToken() { |
2054
|
|
|
$this->establishCSRFTokenState(); |
2055
|
|
|
} |
2056
|
|
|
|
2057
|
|
|
public function getCSRFStateToken() { |
2058
|
|
|
return $this->getPersistentData('state'); |
2059
|
|
|
} |
2060
|
|
|
} |
2061
|
|
|
|
2062
|
|
|
class FBAccessToken extends TransientFacebook { |
|
|
|
|
2063
|
|
|
public function publicGetApplicationAccessToken() { |
2064
|
|
|
return $this->getApplicationAccessToken(); |
2065
|
|
|
} |
2066
|
|
|
} |
2067
|
|
|
|
2068
|
|
|
class FBGetCurrentURLFacebook extends TransientFacebook { |
|
|
|
|
2069
|
|
|
public function publicGetCurrentUrl() { |
2070
|
|
|
return $this->getCurrentUrl(); |
2071
|
|
|
} |
2072
|
|
|
} |
2073
|
|
|
|
2074
|
|
|
class FBPublicCookie extends TransientFacebook { |
|
|
|
|
2075
|
|
|
public function publicGetSignedRequest() { |
2076
|
|
|
return $this->getSignedRequest(); |
2077
|
|
|
} |
2078
|
|
|
|
2079
|
|
|
public function publicGetSignedRequestCookieName() { |
2080
|
|
|
return $this->getSignedRequestCookieName(); |
2081
|
|
|
} |
2082
|
|
|
|
2083
|
|
|
public function publicGetMetadataCookie() { |
2084
|
|
|
return $this->getMetadataCookie(); |
2085
|
|
|
} |
2086
|
|
|
|
2087
|
|
|
public function publicGetMetadataCookieName() { |
2088
|
|
|
return $this->getMetadataCookieName(); |
2089
|
|
|
} |
2090
|
|
|
} |
2091
|
|
|
|
2092
|
|
|
class FBRewrite extends Facebook{ |
|
|
|
|
2093
|
|
|
|
2094
|
|
|
public function uncacheSignedRequest(){ |
2095
|
|
|
$this->signedRequest = null; |
2096
|
|
|
} |
2097
|
|
|
|
2098
|
|
|
public function uncache() |
2099
|
|
|
{ |
2100
|
|
|
$this->user = null; |
2101
|
|
|
$this->signedRequest = null; |
2102
|
|
|
$this->accessToken = null; |
2103
|
|
|
} |
2104
|
|
|
} |
2105
|
|
|
|
2106
|
|
|
|
2107
|
|
|
class FBPublicGetAccessTokenFromCode extends TransientFacebook { |
|
|
|
|
2108
|
|
|
public function publicGetAccessTokenFromCode($code, $redirect_uri = null) { |
2109
|
|
|
return $this->getAccessTokenFromCode($code, $redirect_uri); |
2110
|
|
|
} |
2111
|
|
|
} |
2112
|
|
|
|
2113
|
|
|
class FBPublicState extends TransientFacebook { |
|
|
|
|
2114
|
|
|
const STATE = 'foo'; |
2115
|
|
|
protected function getPersistentData($key, $default = false) { |
2116
|
|
|
if ($key === 'state') { |
2117
|
|
|
return self::STATE; |
2118
|
|
|
} |
2119
|
|
|
return parent::getPersistentData($key, $default); |
2120
|
|
|
} |
2121
|
|
|
|
2122
|
|
|
public function publicGetState() { |
2123
|
|
|
return $this->state; |
2124
|
|
|
} |
2125
|
|
|
} |
2126
|
|
|
|
This method has been deprecated. The supplier of the class has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.