Skip to content

Instantly share code, notes, and snippets.

@teemow
Created October 14, 2009 14:36
Show Gist options
  • Save teemow/210122 to your computer and use it in GitHub Desktop.
Save teemow/210122 to your computer and use it in GitHub Desktop.
<?php
/**
* Adcloud <https://adcloud.net/>
* Copyright (c) 2009, Adcloud GmbH
* Eupener Str. 150
* 50933 Köln - Deutschland
*
* @copyright Copyright (c) 2009, Adcloud GmbH
* @link https://adcloud.net/
* @package app
* @subpackage tests
*/
App::import('Vendor','OAuthRequest', array('file' => 'oauth' . DS . 'library' . DS . 'OAuthRequest.php'));
class OauthServiceProviderTestCase extends CakeWebTestCase {
/**
* Consumer key is the id of the apps
*
* @var int
*/
private $consumer_key;
/**
* Consumer secret is the request token
*
* @var string
*/
private $consumer_secret;
/**
* OAuth token
*
* @var string
*/
private $token;
/**
* OAuth secret token
*
* @var string
*/
private $token_secret;
/**
* Is calculated
*
* @var string
*/
private $nonce;
/**
* timespamp of request
*
* @var int
*/
private $timestamp;
/**
* Default HMAC-SHA1
*
* @var string
*/
private $sig_method;
/**
* OAuth Version is 1.0
*
* @var int
*/
private $version;
/**
* Is generated
*
* @var string
*/
private $sig;
/**
* ApiApplication Object
*
* @var object
*/
public $ApiApplication = null;
/**
* Complete api request url with a duplicate nonce for fail test
*
* @var string
*/
public $same_nonce_url;
/**
* Referer URL to check if we are correct redirected to the referer
*
* @var string
*/
public $Referer_Url;
public $original_source;
/**
* Constructer of test, to save some data in testsuite and set private attributes
* to OAuth values
*
* @return void
*/
public function __construct() {
$this->ApiApplication = ClassRegistry::init('ApiApplication');
$this->original_source = $this->ApiApplication->useDbConfig;
$this->ApiApplication->useDbConfig = 'default';
$this->ApiApplication->ApiApplicationsUser->useDbConfig = 'default';
$this->ApiApplication->User->useDbConfig = 'default';
$this->ApiApplication->ApiAccessToken->useDbConfig = 'default';
$app_data = $this->ApiApplication->find('first', array(
'conditions' => array(
'name' => 'havvgs test app',
'active' => 1
),
'recursive' => -1
));
if(!isset($app_data['ApiApplication'])) {
# save some data in the ApiApplication table
$data = array(
'ApiApplication' => array(
'name' => 'havvgs test app',
'active' => 1
)
);
$this->ApiApplication->create();
$this->ApiApplication->save($data, false);
$app_data = $this->ApiApplication->find('first', array(
'conditions' => array(
'name' => 'havvgs test app',
'active' => 1
),
'recursive' => -1
));
}
$this->ApiApplication->id = $app_data['ApiApplication']['id'];
$this->sig_method = 'HMAC-SHA1';
$this->timestamp = time();
$this->version = '1.0';
$this->nonce = $this->getNonce();
$this->consumer_key = $app_data['ApiApplication']['id'];
$this->customer_secret = $app_data['ApiApplication']['consumer_secret'];
$this->Referer_Url = 'http://www.google.de';
}
/**
* Create a unique nonce for each OAuth request
*
* @return string hash
*/
public function getNonce() {
return md5(microtime() . mt_rand());
}
/**
* Build url to OAuth with get params
*
* @return string url
*/
public function buildUrl($method, $params = array(), $target = 'oauth', $type = 'request') {
$basic_url = Configure::read('App.url') . '/' . $target . '/';
$i = 0;
$get_params = '';
foreach($params as $key => $value) {
if($i == 0) {
$delimiter = '?';
} else {
$delimiter = '&';
}
$get_params .= $delimiter . $key . '=' . $value;
$i++;
}
$url_without_sig = $basic_url . $method . $get_params;
$OAuthRequest = new OAuthRequest($url_without_sig);
$OAuthRequest->setParam('oauth_consumer_key', $params['oauth_consumer_key']);
$OAuthRequest->setParam('oauth_signature_method', $params['oauth_signature_method']);
$OAuthRequest->setParam('oauth_timestamp', $params['oauth_timestamp']);
$OAuthRequest->setParam('oauth_nonce', $params['oauth_nonce']);
if($type == 'request') {
$signature = $OAuthRequest->calculateSignature($this->customer_secret, null, false);
} elseif($type == 'access') {
$signature = $OAuthRequest->calculateSignature($this->customer_secret, $this->token_secret);
}
$url_with_sig = $url_without_sig . '&oauth_signature=' . $signature;
return $url_with_sig;
}
/**
* Test if we get a correct request token
*
* @return void
*/
public function testCorrectOAuthRequestToken() {
# send get request to oauth interface to become a request token
$params['oauth_consumer_key'] = $this->consumer_key;
$params['oauth_nonce'] = $this->nonce;
$params['oauth_signature_method'] = $this->sig_method;
$params['oauth_timestamp'] = $this->timestamp;
$url = $this->buildUrl('request_token', $params);
$this->getBrowser()->addHeader('Referer: ' . $this->Referer_Url);
$result = $this->getBrowser()->get($url);
$this->assertResponse(200);
$token = array();
parse_str($result, $token);
$this->assertTrue(!empty($token['oauth_token']));
$this->assertTrue(!empty($token['oauth_token_secret']));
# check for indexes in order to avoid E_NOTICE
if (empty($token['oauth_token']) || empty($token['oauth_token_secret'])) {
# skip if none given
$this->fail('no token given in response');
return;
}
$this->token = $token['oauth_token'];
$this->token_secret = $token['oauth_token_secret'];
$data = $this->ApiApplication->ApiAccessToken->find('first', array(
'recursive' => -1,
'order' => 'ApiAccessToken.id DESC',
));
# generated token must be the same in the database
$this->assertEqual($data['ApiAccessToken']['token'], $this->token);
}
/**
* Test if we get a correct access token
*
* @return void
*/
public function testCorrectOAuthAccessToken() {
# send get request to oauth interface to become a access token
$params['oauth_consumer_key'] = $this->consumer_key;
$this->nonce = $this->getNonce();
$params['oauth_nonce'] = $this->nonce;
$params['oauth_signature_method'] = $this->sig_method;
$params['oauth_timestamp'] = $this->timestamp;
$params['oauth_token'] = $this->token;
$url = $this->buildUrl('access_token', $params, 'oauth', 'access');
$result = $this->getBrowser()->get($url);
$this->assertResponse(200, 'access_token response');
$token = array();
parse_str($result, $token);
$this->assertTrue(!empty($token['oauth_token']));
# set access token as oauth token
$this->token = $token['oauth_token'];
}
/**
* Test if we can authorize
*
* @return void
*/
public function testAuthorize() {
$params['oauth_consumer_key'] = $this->consumer_key;
$this->nonce = $this->getNonce();
$params['oauth_nonce'] = $this->nonce;
$params['oauth_signature_method'] = $this->sig_method;
$params['oauth_timestamp'] = $this->timestamp;
$params['oauth_token'] = $this->token;
$url = $this->buildUrl('authorize', $params, 'oauth', 'access');
$this->getBrowser()->get($url);
$this->assertResponse(200, 'authorize response');
# check if test user exisits already in database
$test_user = $this->ApiApplication->User->find('first', array(
'conditions' => array(
'email' => 'test@test.de',
'firstname' => 'test',
'lastname' => 'tester'
),
'recursive' => -1
));
# if test user not exists, we will the create test user
if(!isset($test_user['User'])) {
$this->assertTrue($this->ApiApplication->User->create());
$this->assertTrue($this->ApiApplication->User->save(array(
'email' => 'test@test.de',
'password' => '9643c4ca0c90a0f5cdf17204fede6ff0dc3ac924', # pw: 123456
'role_id' => 1,
'firstname' => 'test',
'lastname' => 'tester',
'gender' => 1,
'terms' => 1,
'privacy' => 1
)));
}
$this->getBrowser()->setField('data[User][email]', 'test@test.de');
$this->getBrowser()->setField('data[User][password]', '123456');
$this->getBrowser()->submitFormById('UserLoginForm');
# User successful logged in, now allow the app
$this->getBrowser()->setField('data[allowed]', 'allow');
$this->getBrowser()->setMaximumRedirects(0); # do not follow the redirect
$result = $this->getBrowser()->submitFormById('AddForm');
# vallid redirect codes
$this->assertResponse(array(301, 302, 303, 307));
# location header for redirect
$this->assertHeader('Location', $this->Referer_Url . '?oauth_token=' . $this->token);
# check if api_application_users has correct entries
$test_user_id = $this->ApiApplication->User->find('first', array(
'conditions' => array(
'email' => 'test@test.de',
'firstname' => 'test',
'lastname' => 'tester'
),
'recursive' => -1,
'fields' => array('id')
));
$data = $this->ApiApplication->ApiApplicationsUser->find('first', array(
'conditions' => array(
'ApiApplicationsUser.user_id' => $test_user_id['User']['id'],
'ApiApplicationsUser.api_application_id' => $this->ApiApplication->id,
'ApiApplicationsUser.allowed' => '1'
),
'recursive' => -1
));
$this->assertTrue(isset($data['ApiApplicationsUser']));
}
/**
* Test if we can request data with access token
*
* @return void
*/
public function testRequestAPI() {
$params['oauth_consumer_key'] = $this->consumer_key;
$this->nonce = $this->getNonce();
$params['oauth_nonce'] = $this->nonce;
$params['oauth_signature_method'] = $this->sig_method;
$params['oauth_timestamp'] = $this->timestamp;
$params['oauth_token'] = $this->token;
$url = $this->buildUrl('api_applications/index', $params, 'api/rest/json', 'access');
$this->same_nonce_url = $url;
$result = $this->getBrowser()->get($url);
$this->assertResponse(200, 'api response');
$result = json_decode($result);
$this->assertEqual($result->return_code, '1');
$this->assertEqual($result->return_message, 'OK');
}
/**
* Test if we get failed tests when some token etc. are wrong
*
* @return void
*/
public function testWrongOAuthRequests() {
# send api request with a duplicate nonce
$this->getBrowser()->restart(); # restart browser to make sure, that session is killed
$this->getBrowser()->get($this->same_nonce_url);
$this->assertResponse(200, 'same nonce request');
# if we use a already used nonce, we will not become any data without a login
$this->assertEqual($this->getBrowser()->getUrl(), Configure::read('App.url') . '/users/login');
# send oauth request with wrong params
$this->consumer_key = 'test';
$this->nonce = 'test';
$this->sig_method = 'HMAC-SHA1';
$this->timestamp = 123;
$this->sig = 'test123';
$params['oauth_consumer_key'] = $this->consumer_key;
$params['oauth_nonce'] = $this->nonce;
$params['oauth_signature_method'] = $this->sig_method;
$params['oauth_timestamp'] = $this->timestamp;
$params['oauth_signature'] = $this->sig;
$url = $this->buildUrl('request_token', $params);
#$result = $this->getBrowser()->get($url);
#pr($result);
# todo: error handling
$this->ApiApplication->useDbConfig = $this->original_source;
$this->ApiApplication->ApiApplicationsUser->useDbConfig = $this->original_source;
$this->ApiApplication->User->useDbConfig = $this->original_source;
$this->ApiApplication->ApiAccessToken->useDbConfig = $this->original_source;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment