Skip to content

Commit

Permalink
Starting Oauth1 implementation.
Browse files Browse the repository at this point in the history
Starting with PLAINTEXT mode as its the simplest.
  • Loading branch information
markstory committed Dec 30, 2012
1 parent 226eb61 commit fa7a42d
Show file tree
Hide file tree
Showing 2 changed files with 202 additions and 0 deletions.
125 changes: 125 additions & 0 deletions lib/Cake/Network/Http/Auth/Oauth.php
@@ -0,0 +1,125 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Network\Http\Auth;

use Cake\Error;
use Cake\Network\Http\Client;
use Cake\Network\Http\Request;

/**
* Oauth 1 authentication strategy for Cake\Network\Http\Client
*
* This object does not handle getting Oauth access tokens from the service
* provider. It only handles make client requests *after* you have obtained the Oauth
* tokens.
*
* Generally not directly constructed, but instead used by Cake\Network\Http\Client
* when $options['auth']['type'] is 'oauth'
*/
class Oauth {

/**
* Add headers for Oauth authorization.
*
* @param Request $request
* @param array $options
* @return void
*/
public function authentication(Request $request, $credentials) {
$hasKeys = isset(
$credentials['consumerSecret'],
$credentials['consumerKey'],
$credentials['token'],
$credentials['tokenSecret']
);
if (!$hasKeys) {
return;
}
if (empty($credentials['method'])) {
$credentials['method'] = 'hmac-sha1';
}
$credentials['method'] = strtoupper($credentials['method']);
switch ($credentials['method']) {
case 'HMAC-SHA1':
$value = $this->_hmacSha1($request, $credentials);
break;

case 'RSA-SHA1':
$value = $this->_rsaSha1($request, $credentials);
break;

case 'PLAINTEXT':
$value = $this->_plaintext($request, $credentials);
break;

default:
throw new Error\Exception(__d('cake_dev', 'Unknown Oauth signature method %s', $credentials['method']));

}
$request->header('Authorization', $value);
}

/**
* Plaintext signing
*
* @param Request $request
* @param array $credentials
* @return string Authorization header.
*/
protected function _plaintext($request, $credentials) {
$values = [
'oauth_version' => '1.0',
'oauth_nonce' => uniqid(),
'oauth_timestamp' => time(),
'oauth_signature_method' => 'PLAINTEXT',
'oauth_token' => $credentials['token'],
'oauth_consumer_key' => $credentials['consumerKey'],
'oauth_signature' => $credentials['consumerSecret'] . '&' . $credentials['tokenSecret']
];
return $this->_buildAuth($values);
}

protected function _hmacSha1($request, $credentials) {

}

protected function _rsaSha1($request, $credentials) {

}

protected function _buildAuth($data) {
$out = 'Oauth ';
$params = [];
foreach ($data as $key => $value) {
$params[] = $key . '="' . $this->_encode($value) . '"';
}
$out .= implode(',', $params);
return $out;
}

/**
* URL Encodes a value based on rules of rfc3986
*
* @param string $value
* @return string
*/
protected function _encode($value) {
return str_replace(
'+',
' ',
str_replace('%7E', '~', rawurlencode($value))
);
}

}
77 changes: 77 additions & 0 deletions lib/Cake/Test/TestCase/Network/Http/Auth/OauthTest.php
@@ -0,0 +1,77 @@
<?php
/**
* CakePHP(tm) : Rapid Development Framework (http://cakephp.org)
* Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
*
* Licensed under The MIT License
* Redistributions of files must retain the above copyright notice.
*
* @copyright Copyright 2005-2012, Cake Software Foundation, Inc. (http://cakefoundation.org)
* @link http://cakephp.org CakePHP(tm) Project
* @since CakePHP(tm) v 3.0.0
* @license MIT License (http://www.opensource.org/licenses/mit-license.php)
*/
namespace Cake\Test\TestCase\Network\Http\Auth;

use Cake\Network\Http\Auth\Oauth;
use Cake\Network\Http\Request;
use Cake\TestSuite\TestCase;

/**
* Oauth test.
*/
class OauthTest extends TestCase {

/**
* @expectedException Cake\Error\Exception
*/
public function testExceptionUnknownSigningMethod() {
$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();
$auth->authentication($request, $creds);

$result = $request->header('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);
}

public function testHmacSigning() {
$this->markTestIncomplete();
}

public function testRsaSha1Signing() {
$this->markTestIncomplete();
}

}

0 comments on commit fa7a42d

Please sign in to comment.