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)); } }