Commit: 9f12bf9a1838cfd97d3b24d9ffa4bfd5fc2681ff
Author: gwoo | Date: 2009-11-30 10:57:15 -0800
diff --git a/config/routes.php b/config/routes.php
new file mode 100644
index 0000000..4a2117d
--- /dev/null
+++ b/config/routes.php
@@ -0,0 +1,10 @@
+<?php
+
+use \lithium\http\Router;
+
+
+Router::connect('/oauth/{:action}/{:args}', array(
+ 'plugin' => 'li3_oauth', 'controller' => 'server', 'action' => 'index'
+));
+
+?>
\ No newline at end of file
diff --git a/controllers/ServerController.php b/controllers/ServerController.php
new file mode 100644
index 0000000..9ae0bd6
--- /dev/null
+++ b/controllers/ServerController.php
@@ -0,0 +1,69 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_oauth\controllers;
+
+use \li3_oauth\models\Provider;
+use \lithium\storage\Session;
+
+class ServerController extends \lithium\action\Controller {
+
+ protected function _init() {
+ parent::_init();
+ Provider::config(array(
+ 'host' => 'localhost',
+ 'request_token' => 'union-of-rad/rad-dev/plugins/oauth/request_token',
+ 'access_token' => 'union-of-rad/rad-dev/plugins/oauth/access_token',
+ 'port' => 30500
+ ));
+ }
+
+ public function request_token() {
+ if (empty($this->request->data)) {
+ return 'Invalid Request';
+ }
+ $consumer = Provider::fetch($this->request->data['oauth_consumer_key']);
+ $request = array(
+ 'params' => $this->request->data, 'url' => 'request_token',
+ ) + (array) $consumer;
+ if (Provider::verify($request)) {
+ $token = Provider::create('token');
+ $data = (array) $consumer + (array) $token;
+ Provider::store($consumer->oauth_consumer_key, $data);
+ Provider::store($token->oauth_token, $data);
+ return http_build_query((array) $token);
+ }
+ }
+
+ public function authorize() {
+ if (!empty($this->request->query['oauth_token'])) {
+ $token = $this->request->query['oauth_token'];
+ $data = Provider::fetch($token);
+ }
+
+ if (!empty($this->request->data['allow'])) {
+
+ }
+ if (!empty($this->request->data['deny'])) {
+
+ }
+ return compact('token');
+ }
+
+ public function access_token() {
+
+ }
+
+ public function account() {
+ $token = Provider::create('consumer');
+ Provider::store($token->oauth_consumer_key, $token);
+ return compact('token');
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/extensions/service/Oauth.php b/extensions/service/Oauth.php
index 3002d6c..09508cf 100644
--- a/extensions/service/Oauth.php
+++ b/extensions/service/Oauth.php
@@ -61,7 +61,7 @@ class Oauth extends \lithium\core\Object {
public function _init() {
parent::_init();
$this->service = new $this->_classes['service']($this->_config);
- $this->store = new $this->_classes['storage']($this->_config);
+ $this->storage = new $this->_classes['storage']($this->_config);
}
/**
@@ -80,7 +80,7 @@ class Oauth extends \lithium\core\Object {
}
return $this->_config;
}
-
+
/**
* Send request
*
@@ -95,7 +95,7 @@ class Oauth extends \lithium\core\Object {
$method = !empty($options['method']) ? $options['method'] : 'post';
$data = $this->sign($data + compact('url'));
$response = $this->service->send($method, $url, $data, $options);
- if (strpos($response, 'oauth') !== false) {
+ if (in_array($path, array('request_token', 'access_token'))) {
return $this->_decode($response);
}
return $response;
@@ -126,22 +126,25 @@ class Oauth extends \lithium\core\Object {
*/
public function sign($options = array()) {
$defaults = array(
- 'hash' => 'HMAC-SHA1', 'secret' => $this->_config['oauth_consumer_secret'],
- 'params' => array(), 'method' => 'POST', 'url' => '/', 'data' => array(),
+ 'url' => '', 'method' => 'POST', 'hash' => 'HMAC-SHA1',
+ 'oauth_consumer_secret' => $this->_config['oauth_consumer_secret'],
+ 'params' => array(), 'data' => array(),
'token' => array('oauth_token' => null, 'oauth_token_secret' => null),
);
$options += $defaults;
$params = $this->_build($options['params'] + (array)$options['token']) + $options['data'];
- $base = $this->_base($options['type'], $options['url'], $params);
+ $base = $this->_base($options['method'], $options['url'], $params);
$key = join("&", array(
- rawurlencode($options['secret']), rawurlencode($options['token']['oauth_token_secret'])
+ rawurlencode($options['oauth_consumer_secret']),
+ rawurlencode($options['token']['oauth_token_secret'])
));
+
switch ($options['hash']) {
case 'HMAC-SHA1':
$signature = base64_encode(hash_hmac('sha1', $base, $key, true));
break;
default:
- return $options['secret'];
+ return $options['token']['oauth_token'];
break;
}
$params['oauth_signature'] = $signature;
diff --git a/extensions/storage/File.php b/extensions/storage/File.php
index 077b641..1afe919 100644
--- a/extensions/storage/File.php
+++ b/extensions/storage/File.php
@@ -10,26 +10,70 @@ namespace li3_oauth\extensions\storage;
class File extends \lithium\core\Object {
- public $file = null;
+ protected $_file = null;
+ protected $_autoConfig = array('file');
+
+ /**
+ * undocumented function
+ *
+ * @return void
+ */
protected function _init() {
parent::_init();
- $this->file = LITHIUM_APP_PATH . '/tmp/storage/oauth.ini';
+ if (empty($this->_file)) {
+ $this->_file = LITHIUM_APP_PATH . '/tmp/storage/oauth.json';
+ return;
+ }
+ if ($this->_file[0] !== '/') {
+ $this->_file = LITHIUM_APP_PATH . '/tmp/'. $this->_file;
+ }
}
+ /**
+ * undocumented function
+ *
+ * @param string $key
+ * @param string $value
+ * @return void
+ */
public function write($key, $value) {
- $value = json_encode($value);
- $data = "{$key}=\"{$value}\"";
- return file_put_contents($this->file, $data, FILE_APPEND);
+ $data = (array) $this->read();
+ $data[$key] = $value;
+ $data = json_encode($data);
+ return file_put_contents($this->_file, $data);
}
- public function read($key) {
- $data = parse_ini_file($this->file);
+ /**
+ * undocumented function
+ *
+ * @param string $key
+ * @return void
+ */
+ public function read($key = null) {
+ if (!file_exists($this->_file)) {
+ return null;
+ }
+ $data = json_decode(file_get_contents($this->_file));
+ if (isset($data->{$key})) {
+ return $data->{$key};
+ }
+ return $data;
+ }
+
+ /**
+ * undocumented function
+ *
+ * @param string $key
+ * @return void
+ */
+ public function remove($key) {
+ $data = (array) $this->read();
if (isset($data[$key])) {
- return json_decode($data[$key]);
+ unset($data[$key]);
}
- return null;
+ $data = json_encode($data);
+ return file_put_contents($this->_file, $data);
}
-
}
?>
\ No newline at end of file
diff --git a/models/Provider.php b/models/Provider.php
new file mode 100644
index 0000000..3b7f7c0
--- /dev/null
+++ b/models/Provider.php
@@ -0,0 +1,118 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+
+namespace li3_oauth\models;
+
+use \li3_oauth\extensions\service\Oauth;
+
+class Provider extends \lithium\core\StaticObject {
+
+ /**
+ * Holds an instance of the oauth service class
+ *
+ * @see \li3_oauth\extensions\services\Oauth
+ */
+ protected static $_service = null;
+
+ /**
+ * Configure the Consumer to access the Oauth service layer
+ * {{{
+ * Provider::config(array(
+ * 'host' => 'localhost',
+ * 'oauth_consumer_key' => 'key',
+ * 'oauth_consumer_secret' => 'secret',
+ * 'request_token' => 'libraries/oauth_php/example/request_token.php',
+ * 'access_token' => 'libraries/oauth_php/example/access_token.php',
+ * ));
+ * }}}
+ *
+ * @param array $config
+ * - host: the oauth domain
+ * - oauth_consumer_key: key from oauth service provider
+ * - oauth_consumer_secret: secret from oauth service provider
+ * - oauth_consumer_key: key from oauth service provider
+ * - authorize: path to authorize url
+ * - request_token: path to request token url
+ * - access_token: path to access token url
+ *
+ * @return void
+ */
+ public static function config($config) {
+ static::$_service = new Oauth($config);
+ }
+
+ /**
+ * generate a consumer or token
+ *
+ * @param string $type
+ * - consumer: creates object with oauth_consumer_key and oauth_consumer_secret
+ * - token: creates query string with aoauth_token and oauth_token_secret
+ * @param string $key
+ * @param string $secret
+ * @return void
+ */
+ public static function create($type, $key = null, $secret = null) {
+ $key = $key ?: sha1(mt_rand());
+ $secret = $secret ?: sha1(mt_rand());
+ switch($type) {
+ case 'token':
+ return (object) array(
+ 'oauth_token' => $key, 'oauth_token_secret' => $secret
+ );
+ break;
+ default:
+ case 'consumer':
+ return (object) array(
+ 'oauth_consumer_key' => $key, 'oauth_consumer_secret' => $secret
+ );
+ break;
+ }
+ }
+
+ /**
+ * undocumented function
+ *
+ * @param string $query
+ * @return void
+ */
+ public static function verify($request) {
+ if (!empty($request['params']['oauth_signature'])) {
+ $sig = $request['params']['oauth_signature'];
+ unset($request['params']['oauth_signature']);
+ $test = static::$_service->sign($request);
+
+ if ($sig == $test['oauth_signature']) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * undocumented function
+ *
+ * @param string $key
+ * @param string $value
+ * @return void
+ */
+ public static function store($key, $value) {
+ return static::$_service->storage->write($key, $value);
+ }
+
+ /**
+ * undocumented function
+ *
+ * @param string $key
+ * @return void
+ */
+ public static function fetch($key) {
+ return static::$_service->storage->read($key);
+ }
+}
+
+?>
\ No newline at end of file
diff --git a/tests/cases/extensions/storage/FileTest.php b/tests/cases/extensions/storage/FileTest.php
index b723c65..7058dbe 100644
--- a/tests/cases/extensions/storage/FileTest.php
+++ b/tests/cases/extensions/storage/FileTest.php
@@ -6,12 +6,67 @@
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
-namespace li3_oauth\test\cases\extensions\storage;
+namespace li3_oauth\tests\cases\extensions\storage;
use \li3_oauth\extensions\storage\File;
class FileTest extends \lithium\test\Unit {
+ public $path = null;
+
+ public $file = null;
+
+ public function setUp() {
+ $this->path = LITHIUM_APP_PATH . '/tmp/test_oauth.json';
+ $this->file = new File(array('file' => $this->path));
+ }
+
+ public function tearDown() {
+ unlink($this->path);
+ }
+
+ public function testReadWrite() {
+ $expected = '';
+ $result = $this->file->read();
+ $this->assertEqual($expected, $result);
+
+ $expected = true;
+ $result = $this->file->write('some_key', array(
+ 'oauth_consumer_key' => 'some_key',
+ 'oauth_consumer_secret' => 'some_secret'
+ ));
+ $this->assertEqual($expected, $result);
+
+ $expected = (object) array('some_key' => (object) array(
+ 'oauth_consumer_key' => 'some_key','oauth_consumer_secret' => 'some_secret'
+ ));
+ $result = $this->file->read();
+ $this->assertEqual($expected, $result);
+
+ }
+
+ public function testWriteReadRemove() {
+ $expected = true;
+ $result = $this->file->write('some_key', array(
+ 'oauth_consumer_key' => 'some_key',
+ 'oauth_consumer_secret' => 'some_secret'
+ ));
+ $this->assertEqual($expected, $result);
+
+ $expected = (object) array('some_key' => (object) array(
+ 'oauth_consumer_key' => 'some_key','oauth_consumer_secret' => 'some_secret'
+ ));
+ $result = $this->file->read();
+ $this->assertEqual($expected, $result);
+
+ $expected = true;
+ $result = $this->file->remove('some_key');
+ $this->assertEqual($expected, $result);
+
+ $expected = array();
+ $result = $this->file->read();
+ $this->assertEqual($expected, $result);
+ }
}
diff --git a/tests/cases/models/ProviderTest.php b/tests/cases/models/ProviderTest.php
index 8ff768d..ebdf37b 100644
--- a/tests/cases/models/ProviderTest.php
+++ b/tests/cases/models/ProviderTest.php
@@ -6,13 +6,87 @@
* @license http://opensource.org/licenses/bsd-license.php The BSD License
*/
-namespace li3_oauth\test\cases\models;
+namespace li3_oauth\tests\cases\models;
use \li3_oauth\models\Provider;
class ProviderTest extends \lithium\test\Unit {
+ public function setUp() {
+ Provider::config(array(
+ 'host' => 'localhost',
+ 'oauth_consumer_key' => 'key',
+ 'oauth_consumer_secret' => 'secret',
+ 'port' => 30500
+ ));
+ }
+ public function testCreateConsumer() {
+ $expected = (object) array(
+ 'oauth_consumer_key' => 'key', 'oauth_consumer_secret' => 'secret'
+ );
+ $result = Provider::create('consumer', 'key', 'secret');
+ $this->assertEqual($expected, $result);
+
+ $consumer = Provider::create('consumer');
+
+ $expected = '/[a-z0-9]{40}/';
+ $result = $consumer->oauth_consumer_key;
+ $this->assertPattern($expected, $result);
+
+ $expected = '/[a-z0-9]{40}/';
+ $result = $consumer->oauth_consumer_secret;
+ $this->assertPattern($expected, $result);
+ }
+
+ public function testCreateToken() {
+ $expected = (object) array(
+ 'oauth_token' => 'request_token', 'oauth_token_secret' => 'request_secret'
+ );
+ $result = Provider::create('token', 'request_token', 'request_secret');
+ $this->assertEqual($expected, $result);
+
+ $token = Provider::create('token');
+
+ $expected = '/[a-z0-9]{40}/';
+ $result = $token->oauth_token;
+ $this->assertPattern($expected, $result);
+
+ $expected = '/[a-z0-9]{40}/';
+ $result = $token->oauth_token_secret;
+ $this->assertPattern($expected, $result);
+ }
+
+ public function testVerify() {
+ $request = array(
+ 'params' => array(
+ 'oauth_consumer_key' => 'key',
+ 'oauth_nonce' => '4d31073c8ce205ecd3145d6cc0a3a4f6',
+ 'oauth_signature' => 'fKMyRb/Pysuu0XqRoxANOkyiL8I=',
+ 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => '1259606608',
+ 'oauth_version' => '1.0',
+ )
+ );
+ $result = Provider::verify($request);
+ $this->assertTrue($result);
+ }
+
+ public function testVerifyWithToken() {
+ $request = array(
+ 'params' => array(
+ 'oauth_consumer_key' => 'key',
+ 'oauth_nonce' => '4d31073c8ce205ecd3145d6cc0a3a4f6',
+ 'oauth_signature' => 'G/ZDnJOVbvVasoHH/XbDVzdwJ+U=',
+ 'oauth_signature_method' => 'HMAC-SHA1', 'oauth_timestamp' => '1259606608',
+ 'oauth_version' => '1.0',
+ ),
+ 'token' => array(
+ 'oauth_token' => 'request_token', 'oauth_token_secret' => 'request_secret'
+ )
+ );
+ $result = Provider::verify($request);
+ $this->assertTrue($result);
+ }
}
?>
\ No newline at end of file
diff --git a/views/layouts/default.html.php b/views/layouts/default.html.php
new file mode 100644
index 0000000..6c293f7
--- /dev/null
+++ b/views/layouts/default.html.php
@@ -0,0 +1,27 @@
+<?php
+/**
+ * Lithium: the most rad php framework
+ *
+ * @copyright Copyright 2009, Union of RAD (http://union-of-rad.org)
+ * @license http://opensource.org/licenses/bsd-license.php The BSD License
+ */
+?>
+<!doctype html>
+<html>
+<head>
+ <?php echo $this->html->charset(); ?>
+ <title><?=$this->title(); ?></title>
+ <?php echo $this->html->style('base'); ?>
+ <?php echo $this->scripts(); ?>
+ <?php echo $this->html->link('Icon', null, array('type' => 'icon')); ?>
+</head>
+<body>
+ <div id="container">
+ <div id="header"></div>
+ <div id="content">
+ <?php echo $this->content; ?>
+ </div>
+ <div id="footer"></div>
+ </div>
+</body>
+</html>
diff --git a/views/server/account.html.php b/views/server/account.html.php
new file mode 100644
index 0000000..e313e97
--- /dev/null
+++ b/views/server/account.html.php
@@ -0,0 +1,6 @@
+<div class="account">
+ <ul>
+ <li>Key: <?=$token->oauth_consumer_key;?></li>
+ <li>Secret: <?=$token->oauth_consumer_secret;?></li>
+ </ul>
+</div>
\ No newline at end of file
diff --git a/views/server/authorize.html.php b/views/server/authorize.html.php
new file mode 100644
index 0000000..1c25527
--- /dev/null
+++ b/views/server/authorize.html.php
@@ -0,0 +1,6 @@
+<div class="authorize">
+ <form method="POST">
+ <input type="submit" name="deny" value="deny">
+ <input type="submit" name="allow" value="allow">
+ </form>
+</div>
\ No newline at end of file