| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572 |
- <?php
- /**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link https://cakephp.org CakePHP(tm) Project
- * @since 3.0.0
- * @license https://opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\Test\TestCase\Http\Client\Auth;
- use Cake\Http\Client\Auth\Oauth;
- use Cake\Http\Client\Request;
- use Cake\TestSuite\TestCase;
- /**
- * Oauth test.
- */
- class OauthTest extends TestCase
- {
- private $privateKeyString = '-----BEGIN RSA PRIVATE KEY-----
- MIICdgIBADANBgkqhkiG9w0BAQEFAASCAmAwggJcAgEAAoGBALRiMLAh9iimur8V
- A7qVvdqxevEuUkW4K+2KdMXmnQbG9Aa7k7eBjK1S+0LYmVjPKlJGNXHDGuy5Fw/d
- 7rjVJ0BLB+ubPK8iA/Tw3hLQgXMRRGRXXCn8ikfuQfjUS1uZSatdLB81mydBETlJ
- hI6GH4twrbDJCR2Bwy/XWXgqgGRzAgMBAAECgYBYWVtleUzavkbrPjy0T5FMou8H
- X9u2AC2ry8vD/l7cqedtwMPp9k7TubgNFo+NGvKsl2ynyprOZR1xjQ7WgrgVB+mm
- uScOM/5HVceFuGRDhYTCObE+y1kxRloNYXnx3ei1zbeYLPCHdhxRYW7T0qcynNmw
- rn05/KO2RLjgQNalsQJBANeA3Q4Nugqy4QBUCEC09SqylT2K9FrrItqL2QKc9v0Z
- zO2uwllCbg0dwpVuYPYXYvikNHHg+aCWF+VXsb9rpPsCQQDWR9TT4ORdzoj+Nccn
- qkMsDmzt0EfNaAOwHOmVJ2RVBspPcxt5iN4HI7HNeG6U5YsFBb+/GZbgfBT3kpNG
- WPTpAkBI+gFhjfJvRw38n3g/+UeAkwMI2TJQS4n8+hid0uus3/zOjDySH3XHCUno
- cn1xOJAyZODBo47E+67R4jV1/gzbAkEAklJaspRPXP877NssM5nAZMU0/O/NGCZ+
- 3jPgDUno6WbJn5cqm8MqWhW1xGkImgRk+fkDBquiq4gPiT898jusgQJAd5Zrr6Q8
- AO/0isr/3aa6O6NLQxISLKcPDk2NOccAfS/xOtfOz4sJYM3+Bs4Io9+dZGSDCA54
- Lw03eHTNQghS0A==
- -----END RSA PRIVATE KEY-----';
- private $privateKeyStringEnc = '-----BEGIN RSA PRIVATE KEY-----
- Proc-Type: 4,ENCRYPTED
- DEK-Info: DES-CBC,E65DB7AE7A05EF23
- QCXAQ/Uj1+7uQp0MyDUPlKvW/28PhbT4GxflBYmU6SxKZ2CVFPk0M8RgB6gkJyVv
- mwjo1Ch2Tlt7/VrNfLWGIh1XPhsC3gatv8Wv+g0keWWifaHlhXulgMGREJ7QeJg0
- 5THvdFuIs2qQnOzPCAwONjM6yMxPb2qxvwq0UKAL5V/CYVFWS6PYdR25f9ogXxBz
- c3QjvvnhQ7ipNjpjVp/XKYMYnZPCYkNYvRX+BcsWlqYtclO3m+xPG+mPAFs9hnBI
- wHI4yC2fl52giRc7XnSl7NNjun6RpHT/Cn7JDH6ql86pgMO0dw6PDzPf0KY9DCrR
- ldQyzQ8WjN3FU55+En+8zmSnxUu7EbdqZwhVEF+UwfJ7IqJUnHll0aDTUA/qq0dk
- DqtMKIXvRnDVZJqKxHyRvARf8Zp8USsq3cVdlA9PhtcKrs4CbTDL0lJ3eWj1bDS1
- kIHXYo19lBqcS1oX+6TqvEs69oW/aG8UZIONN0Xh5TbxuJMedXD1dexV9oOA9lGR
- cS6Ye0wC7fCdnA6jfAmHFJ5t2qk7FOzcFZwap7m+EWn11z+72GVqz3BDSe5qH2m2
- XOHl59rVtJsZFtjyQEV34IFYyb2qBHHqUUdKwIwT1JOZIq+IdTJxaieIb1mnlmDw
- DDf4Kwr0C9tti1R1IsPaAmjF7eH0PGbDGAB3fJSCXbHf7EXTz1AUdknd2MHXQ7wO
- UBABkD2ETB+EotdHTly5FQt0jwbHfF2najBmezxtEjIygCnDb02Rtuei4HTansBu
- shqoyFXJvizZzje7HaTQv/eJTuA6rUOzu/sAv/eBx2YAPkA8oa3qUw==
- -----END RSA PRIVATE KEY-----';
- /**
- * @return void
- */
- public function testExceptionUnknownSigningMethod()
- {
- $this->expectException(\Cake\Core\Exception\Exception::class);
- $auth = new Oauth();
- $creds = [
- 'consumerSecret' => 'it is secret',
- 'consumerKey' => 'a key',
- 'token' => 'a token value',
- 'tokenSecret' => 'also secret',
- 'method' => 'silly goose',
- ];
- $request = new Request();
- $auth->authentication($request, $creds);
- }
- /**
- * Test plain-text signing.
- *
- * @return void
- */
- public function testPlainTextSigning()
- {
- $auth = new Oauth();
- $creds = [
- 'consumerSecret' => 'it is secret',
- 'consumerKey' => 'a key',
- 'token' => 'a token value',
- 'tokenSecret' => 'also secret',
- 'method' => 'plaintext',
- ];
- $request = new Request();
- $request = $auth->authentication($request, $creds);
- $result = $request->getHeaderLine('Authorization');
- $this->assertContains('OAuth', $result);
- $this->assertContains('oauth_version="1.0"', $result);
- $this->assertContains('oauth_token="a%20token%20value"', $result);
- $this->assertContains('oauth_consumer_key="a%20key"', $result);
- $this->assertContains('oauth_signature_method="PLAINTEXT"', $result);
- $this->assertContains('oauth_signature="it%20is%20secret%26also%20secret"', $result);
- $this->assertContains('oauth_timestamp=', $result);
- $this->assertContains('oauth_nonce=', $result);
- }
- /**
- * Test that baseString() normalizes the URL.
- *
- * @return void
- */
- public function testBaseStringNormalizeUrl()
- {
- $request = new Request('HTTP://exAmple.com:80/parts/foo');
- $auth = new Oauth();
- $creds = [];
- $result = $auth->baseString($request, $creds);
- $this->assertContains('GET&', $result, 'method was missing.');
- $this->assertContains('http%3A%2F%2Fexample.com%2Fparts%2Ffoo', $result);
- }
- /**
- * Test that the query string is stripped from the normalized host.
- *
- * @return void
- */
- public function testBaseStringWithQueryString()
- {
- $request = new Request('http://example.com/search?q=pogo&cat=2');
- $auth = new Oauth();
- $values = [
- 'oauth_version' => '1.0',
- 'oauth_nonce' => uniqid(),
- 'oauth_timestamp' => time(),
- 'oauth_signature_method' => 'HMAC-SHA1',
- 'oauth_token' => 'token',
- 'oauth_consumer_key' => 'consumer-key',
- ];
- $result = $auth->baseString($request, $values);
- $this->assertContains('GET&', $result, 'method was missing.');
- $this->assertContains(
- 'http%3A%2F%2Fexample.com%2Fsearch&',
- $result
- );
- $this->assertContains(
- 'cat%3D2%26oauth_consumer_key%3Dconsumer-key' .
- '%26oauth_nonce%3D' . $values['oauth_nonce'] .
- '%26oauth_signature_method%3DHMAC-SHA1' .
- '%26oauth_timestamp%3D' . $values['oauth_timestamp'] .
- '%26oauth_token%3Dtoken' .
- '%26oauth_version%3D1.0' .
- '%26q%3Dpogo',
- $result
- );
- }
- /**
- * Ensure that post data is sorted and encoded.
- *
- * Keys with array values have to be serialized using
- * a more standard HTTP approach. PHP flavoured HTTP
- * is not part of the Oauth spec.
- *
- * See Normalize Request Parameters (section 9.1.1)
- *
- * @return void
- */
- public function testBaseStringWithPostDataNestedArrays()
- {
- $request = new Request(
- 'http://example.com/search?q=pogo',
- Request::METHOD_POST,
- [],
- [
- 'search' => [
- 'filters' => [
- 'field' => 'date',
- 'value' => 'one two',
- ],
- ],
- ]
- );
- $auth = new Oauth();
- $values = [
- 'oauth_version' => '1.0',
- 'oauth_nonce' => uniqid(),
- 'oauth_timestamp' => time(),
- 'oauth_signature_method' => 'HMAC-SHA1',
- 'oauth_token' => 'token',
- 'oauth_consumer_key' => 'consumer-key',
- ];
- $result = $auth->baseString($request, $values);
- $this->assertContains('POST&', $result, 'method was missing.');
- $this->assertContains(
- 'http%3A%2F%2Fexample.com%2Fsearch&',
- $result
- );
- $this->assertContains(
- '&oauth_consumer_key%3Dconsumer-key' .
- '%26oauth_nonce%3D' . $values['oauth_nonce'] .
- '%26oauth_signature_method%3DHMAC-SHA1' .
- '%26oauth_timestamp%3D' . $values['oauth_timestamp'] .
- '%26oauth_token%3Dtoken' .
- '%26oauth_version%3D1.0' .
- '%26q%3Dpogo' .
- '%26search%5Bfilters%5D%5Bfield%5D%3Ddate' .
- '%26search%5Bfilters%5D%5Bvalue%5D%3Done%20two',
- $result
- );
- }
- /**
- * Ensure that post data is sorted and encoded.
- *
- * Keys with array values have to be serialized using
- * a more standard HTTP approach. PHP flavoured HTTP
- * is not part of the Oauth spec.
- *
- * See Normalize Request Parameters (section 9.1.1)
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testBaseStringWithPostData()
- {
- $request = new Request(
- 'http://example.com/search?q=pogo',
- Request::METHOD_POST,
- [],
- [
- 'address' => 'post',
- 'zed' => 'last',
- 'tags' => ['oauth', 'cake'],
- ]
- );
- $auth = new Oauth();
- $values = [
- 'oauth_version' => '1.0',
- 'oauth_nonce' => uniqid(),
- 'oauth_timestamp' => time(),
- 'oauth_signature_method' => 'HMAC-SHA1',
- 'oauth_token' => 'token',
- 'oauth_consumer_key' => 'consumer-key',
- ];
- $result = $auth->baseString($request, $values);
- $this->assertContains('POST&', $result, 'method was missing.');
- $this->assertContains(
- 'http%3A%2F%2Fexample.com%2Fsearch&',
- $result
- );
- $this->assertContains(
- '&address%3Dpost' .
- '%26oauth_consumer_key%3Dconsumer-key' .
- '%26oauth_nonce%3D' . $values['oauth_nonce'] .
- '%26oauth_signature_method%3DHMAC-SHA1' .
- '%26oauth_timestamp%3D' . $values['oauth_timestamp'] .
- '%26oauth_token%3Dtoken' .
- '%26oauth_version%3D1.0' .
- '%26q%3Dpogo' .
- '%26tags%3Dcake' .
- '%26tags%3Doauth' .
- '%26zed%3Dlast',
- $result
- );
- }
- /**
- * Test HMAC-SHA1 signing
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testHmacSigning()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacation.jpg', 'size' => 'original']
- );
- $options = [
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'consumerSecret' => 'kd94hf93k423kf44',
- 'tokenSecret' => 'pfkkdhi9sl3r4s00',
- 'token' => 'nnch734d00sl2jdk',
- 'nonce' => 'kllo9940pd9333jh',
- 'timestamp' => '1191242096',
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'tR3+Ty81lMeYAr/Fid0kMTYa/WM=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test HMAC-SHA1 signing with a base64 consumer key
- *
- * @return void
- */
- public function testHmacBase64Signing()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET'
- );
- $options = [
- 'consumerKey' => 'ZHBmNDNmM3AybDRrM2wwMw==',
- 'consumerSecret' => 'kd94hf93k423kf44',
- 'tokenSecret' => 'pfkkdhi9sl3r4s00',
- 'token' => 'nnch734d00sl2jdk',
- 'nonce' => 'kllo9940pd9333jh',
- 'timestamp' => '1191242096',
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = '2hr/eoFyTSuWc6SfZIvkhpeRHdM=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test RSA-SHA1 signing with a private key string
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningString()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = $this->privateKeyString;
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test RSA-SHA1 signing with a private key file
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningFile()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = fopen(TEST_APP . DS . 'config' . DS . 'key.pem', 'r');
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test RSA-SHA1 signing with a private key file passphrase string
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningWithPassphraseString()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = fopen(TEST_APP . DS . 'config' . DS . 'key_with_passphrase.pem', 'r');
- $passphrase = 'fancy-cakephp-passphrase';
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- 'privateKeyPassphrase' => $passphrase,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test RSA-SHA1 signing with a private key string and passphrase string
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningStringWithPassphraseString()
- {
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = $this->privateKeyStringEnc;
- $passphrase = 'fancy-cakephp-passphrase';
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- 'privateKeyPassphrase' => $passphrase,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- }
- /**
- * Test RSA-SHA1 signing with passphrase file
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningWithPassphraseFile()
- {
- $this->skipIf(PHP_EOL != "\n", 'Just the line ending "\n" is supported. You can run the test again e.g. on a linux system.');
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = fopen(TEST_APP . DS . 'config' . DS . 'key_with_passphrase.pem', 'r');
- $passphrase = fopen(TEST_APP . DS . 'config' . DS . 'key_passphrase_lf', 'r');
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- 'privateKeyPassphrase' => $passphrase,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- $expected = 0;
- $this->assertEquals($expected, ftell($passphrase));
- }
- /**
- * Test RSA-SHA1 signing with a private key string and passphrase file
- *
- * Hash result + parameters taken from
- * http://wiki.oauth.net/w/page/12238556/TestCases
- *
- * @return void
- */
- public function testRsaSigningStringWithPassphraseFile()
- {
- $this->skipIf(PHP_EOL != "\n", 'Just the line ending "\n" is supported. You can run the test again e.g. on a linux system.');
- $request = new Request(
- 'http://photos.example.net/photos',
- 'GET',
- [],
- ['file' => 'vacaction.jpg', 'size' => 'original']
- );
- $privateKey = $this->privateKeyStringEnc;
- $passphrase = fopen(TEST_APP . DS . 'config' . DS . 'key_passphrase_lf', 'r');
- $options = [
- 'method' => 'RSA-SHA1',
- 'consumerKey' => 'dpf43f3p2l4k3l03',
- 'nonce' => '13917289812797014437',
- 'timestamp' => '1196666512',
- 'privateKey' => $privateKey,
- 'privateKeyPassphrase' => $passphrase,
- ];
- $auth = new Oauth();
- $request = $auth->authentication($request, $options);
- $result = $request->getHeaderLine('Authorization');
- $expected = 'jvTp/wX1TYtByB1m+Pbyo0lnCOLIsyGCH7wke8AUs3BpnwZJtAuEJkvQL2/9n4s5wUmUl4aCI4BwpraNx4RtEXMe5qg5T1LVTGliMRpKasKsW//e+RinhejgCuzoH26dyF8iY2ZZ/5D1ilgeijhV/vBka5twt399mXwaYdCwFYE=';
- $this->assertContains(
- 'oauth_signature="' . $expected . '"',
- urldecode($result)
- );
- $expected = 0;
- $this->assertEquals($expected, ftell($passphrase));
- }
- }
|