* @copyright 2005 Janrain, Inc.
* @license http://www.gnu.org/copyleft/lesser.html LGPL
*/
require_once 'Auth/OpenID/CryptUtil.php';
require_once 'Auth/OpenID/DiffieHellman.php';
require_once 'Auth/OpenID/FileStore.php';
require_once 'Auth/OpenID/KVForm.php';
require_once 'Auth/OpenID/Consumer.php';
require_once 'Auth/OpenID/HTTPFetcher.php';
require_once 'PHPUnit.php';
class Auth_OpenID_TestConsumer extends Auth_OpenID_Consumer {
/**
* Use a small (insecure) modulus for this test so that it runs quickly
*/
function _createDiffieHellman()
{
return new Auth_OpenID_DiffieHellman('1235514290909');
}
}
$_Auth_OpenID_assocs = array(
array('another 20-byte key.', 'Snarky'),
array(str_repeat("\x00", 20), 'Zeros'),
);
$_Auth_OpenID_filestore_base_dir = "/tmp";
function Auth_OpenID_parse($qs)
{
$result = array();
$parts = explode("&", $qs);
foreach ($parts as $pair) {
list($key, $value) = explode("=", $pair, 2);
assert(!array_key_exists($key, $result));
$result[$key] = urldecode($value);
}
return $result;
}
function Auth_OpenID_associate($qs, $assoc_secret, $assoc_handle)
{
$query_data = Auth_OpenID_parse($qs);
assert((count($query_data) == 6) || (count($query_data) == 4));
assert($query_data['openid.mode'] == 'associate');
assert($query_data['openid.assoc_type'] == 'HMAC-SHA1');
assert($query_data['openid.session_type'] == 'DH-SHA1');
$reply_dict = array(
'assoc_type' => 'HMAC-SHA1',
'assoc_handle' => $assoc_handle,
'expires_in' => '600',
);
$dh_args = Auth_OpenID_DiffieHellman::
serverAssociate($query_data, $assoc_secret);
$reply_dict = array_merge($reply_dict, $dh_args);
return Auth_OpenID_KVForm::fromArray($reply_dict);
}
class Auth_OpenID_TestFetcher extends Auth_OpenID_HTTPFetcher {
function Auth_OpenID_TestFetcher($user_url, $user_page,
$assoc_secret, $assoc_handle)
{
$this->get_responses = array($user_url => array(200,
$user_url,
$user_page));
$this->assoc_secret = $assoc_secret;
$this->assoc_handle = $assoc_handle;
$this->num_assocs = 0;
}
function response($url, $body)
{
if ($body === null) {
return array(404, $url, 'Not found');
} else {
return array(200, $url, $body);
}
}
function get($url)
{
if (array_key_exists($url, $this->get_responses)) {
return $this->get_responses[$url];
} else {
return $this->response($url, null);
}
}
function _checkAuth($url, $body)
{
$query_data = Auth_OpenID_parse($body);
$expected = array(
'openid.mode' => 'check_authentication',
'openid.signed' => 'assoc_handle,sig,signed',
'openid.sig' => 'fake',
'openid.assoc_handle' => $this->assoc_handle,
);
if ($query_data == $expected) {
return array(200, $url, "is_valid:true\n");
} else {
return array(400, $url, "error:bad check_authentication query\n");
}
}
function post($url, $body)
{
if (strpos($body, 'openid.mode=associate') !== false) {
$response = Auth_OpenID_associate($body, $this->assoc_secret,
$this->assoc_handle);
$this->num_assocs++;
return $this->response($url, $response);
} elseif (strpos($body, 'openid.mode=check_authentication') !== false) {
return $this->_checkAuth($url, $body);
} else {
return $this->response($url, null);
}
}
}
$_Auth_OpenID_user_page_pat = "
A user page
%s
blah blah
";
$_Auth_OpenID_server_url = "http://server.example.com/";
$_Auth_OpenID_consumer_url = "http://consumer.example.com/";
class Tests_Auth_OpenID_Consumer extends PHPUnit_TestCase {
function _run(&$consumer, $user_url, $mode, $delegate_url,
&$fetcher, &$store, $immediate)
{
global $_Auth_OpenID_consumer_url,
$_Auth_OpenID_server_url;
list($status, $info) = $consumer->beginAuth($user_url);
$this->assertEquals(Auth_OpenID_SUCCESS, $status);
$return_to = $_Auth_OpenID_consumer_url;
$trust_root = $_Auth_OpenID_consumer_url;
$redirect_url = $consumer->constructRedirect($info, $return_to,
$trust_root, $immediate);
$parsed = parse_url($redirect_url);
$qs = $parsed['query'];
$q = Auth_OpenID_parse($qs);
$expected = array(
'openid.mode' => $mode,
'openid.identity' => $delegate_url,
'openid.trust_root' => $trust_root,
'openid.return_to' => $return_to
);
if ($consumer->_use_assocs) {
$expected['openid.assoc_handle'] = $fetcher->assoc_handle;
}
$this->assertEquals($expected, $q);
$this->assertEquals(0, strpos($redirect_url, $_Auth_OpenID_server_url));
$query = array(
'openid.mode'=> 'id_res',
'openid.return_to'=> $return_to,
'openid.identity'=> $delegate_url,
'openid.assoc_handle'=> $fetcher->assoc_handle,
);
if ($consumer->_use_assocs) {
$assoc = $store->getAssociation($_Auth_OpenID_server_url,
$fetcher->assoc_handle);
$assoc->addSignature(array('mode', 'return_to', 'identity'),
$query);
} else {
$query['openid.signed'] =
'assoc_handle,sig,signed';
$query['openid.assoc_handle'] = $fetcher->assoc_handle;
$query['openid.sig'] = 'fake';
}
$result = $consumer->completeAuth($info->token, $query);
$this->assertEquals(array(Auth_OpenID_SUCCESS, $user_url), $result);
}
function _test_success($user_url, $delegate_url, $links, $immediate = false)
{
global $_Auth_OpenID_filestore_base_dir,
$_Auth_OpenID_server_url,
$_Auth_OpenID_user_page_pat,
$_Auth_OpenID_assocs;
$store = new Auth_OpenID_FileStore(
Auth_OpenID_FileStore::_mkdtemp($_Auth_OpenID_filestore_base_dir));
if ($immediate) {
$mode = 'checkid_immediate';
} else {
$mode = 'checkid_setup';
}
$user_page = sprintf($_Auth_OpenID_user_page_pat, $links);
$fetcher = new Auth_OpenID_TestFetcher($user_url, $user_page,
$_Auth_OpenID_assocs[0][0],
$_Auth_OpenID_assocs[0][1]);
$consumer = new Auth_OpenID_TestConsumer($store, &$fetcher);
$expected_num_assocs = 0;
$this->assertEquals($expected_num_assocs, $fetcher->num_assocs);
$this->_run($consumer, $user_url, $mode, $delegate_url,
$fetcher, $store, $immediate);
if ($consumer->_use_assocs) {
$expected_num_assocs += 1;
}
$this->assertEquals($expected_num_assocs, $fetcher->num_assocs);
// Test that doing it again uses the existing association
$this->_run($consumer, $user_url, $mode, $delegate_url,
$fetcher, $store, $immediate);
$this->assertEquals($expected_num_assocs, $fetcher->num_assocs);
// Another association is created if we remove the existing one
$store->removeAssociation($_Auth_OpenID_server_url,
$fetcher->assoc_handle);
$this->_run($consumer, $user_url, $mode, $delegate_url,
$fetcher, $store, $immediate);
if ($consumer->_use_assocs) {
$expected_num_assocs += 1;
}
$this->assertEquals($expected_num_assocs, $fetcher->num_assocs);
// Test that doing it again uses the existing association
$this->_run($consumer, $user_url, $mode, $delegate_url,
$fetcher, $store, $immediate);
$this->assertEquals($expected_num_assocs, $fetcher->num_assocs);
$store->destroy();
}
function test_success()
{
global $_Auth_OpenID_server_url;
$user_url = 'http://www.example.com/user.html';
$links = sprintf('',
$_Auth_OpenID_server_url);
$delegate_url = 'http://consumer.example.com/user';
$delegate_links = sprintf(''.
'',
$_Auth_OpenID_server_url, $delegate_url);
$this->_test_success($user_url, $user_url, $links);
$this->_test_success($user_url, $user_url, $links, true);
$this->_test_success($user_url, $delegate_url, $delegate_links);
$this->_test_success($user_url, $delegate_url, $delegate_links, true);
}
function test_bad_fetch()
{
global $_Auth_OpenID_filestore_base_dir;
$store = new Auth_OpenID_FileStore(
Auth_OpenID_FileStore::_mkdtemp($_Auth_OpenID_filestore_base_dir));
$fetcher = new Auth_OpenID_TestFetcher(null, null, null, null);
$consumer = new Auth_OpenID_TestConsumer($store, &$fetcher);
$cases = array(
array(null, 'http://network.error/'),
array(404, 'http://not.found/'),
array(400, 'http://bad.request/'),
array(500, 'http://server.error/')
);
foreach ($cases as $case) {
list($error_code, $url) = $case;
$fetcher->get_responses[$url] = array($error_code, $url, null);
list($status, $info) = $consumer->beginAuth($url);
$this->assertEquals($status, Auth_OpenID_HTTP_FAILURE);
$this->assertEquals($info, $error_code);
}
$store->destroy();
}
function test_bad_parse()
{
global $_Auth_OpenID_filestore_base_dir;
$store = new Auth_OpenID_FileStore(
Auth_OpenID_FileStore::_mkdtemp($_Auth_OpenID_filestore_base_dir));
$user_url = 'http://user.example.com/';
$cases = array(
'',
"http://not.in.a.link.tag/",
''
);
foreach ($cases as $user_page) {
$fetcher = new Auth_OpenID_TestFetcher($user_url, $user_page,
null, null);
$consumer = new Auth_OpenID_TestConsumer($store, $fetcher);
list($status, $info) = $consumer->beginAuth($user_url);
$this->assertEquals($status, Auth_OpenID_PARSE_ERROR);
$this->assertNull($info);
}
$store->destroy();
}
}
?>