forked from GNUsocial/gnu-social
		
	
		
			
				
	
	
		
			378 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			378 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
| <?php
 | |
| 
 | |
| require_once "Tests/Auth/OpenID/TestUtil.php";
 | |
| require_once "Tests/Auth/OpenID/MemStore.php";
 | |
| 
 | |
| require_once "Auth/OpenID/Message.php";
 | |
| require_once "Auth/OpenID/Server.php";
 | |
| require_once "Auth/OpenID/Consumer.php";
 | |
| require_once "Auth/OpenID/Association.php";
 | |
| 
 | |
| // Some values we can use for convenience (see mkAssocResponse)
 | |
| global $association_response_values;
 | |
| $association_response_values = array(
 | |
|     'expires_in' => '1000',
 | |
|     'assoc_handle' => 'a handle',
 | |
|     'assoc_type' => 'a type',
 | |
|     'session_type' => 'a session type',
 | |
|     'ns' => Auth_OpenID_OPENID2_NS
 | |
|     );
 | |
| 
 | |
| /**
 | |
|  * Build an association response message that contains the specified
 | |
|  * subset of keys. The values come from association_response_values.
 | |
|  *
 | |
|  * This is useful for testing for missing keys and other times that we
 | |
|  * don't care what the values are.
 | |
|  */
 | |
| function mkAssocResponse($keys)
 | |
| {
 | |
|     global $association_response_values;
 | |
| 
 | |
|     $args = array();
 | |
| 
 | |
|     foreach ($keys as $key) {
 | |
|         $args[$key] = $association_response_values[$key];
 | |
|     }
 | |
| 
 | |
|     return Auth_OpenID_Message::fromOpenIDArgs($args);
 | |
| }
 | |
| 
 | |
| class Tests_Auth_OpenID_AssociationResponse extends PHPUnit_Framework_TestCase {
 | |
|     function setUp()
 | |
|     {
 | |
|         $this->store = new Tests_Auth_OpenID_MemStore();
 | |
|         $this->consumer = new Auth_OpenID_GenericConsumer($this->store);
 | |
|         $this->endpoint = new Auth_OpenID_ServiceEndpoint();
 | |
|     }
 | |
| 
 | |
|     function failUnlessProtocolError($thing)
 | |
|     {
 | |
|         $this->assertTrue(Auth_OpenID::isFailure($thing));
 | |
|     }
 | |
| 
 | |
|     function _run($keys)
 | |
|     {
 | |
|         $msg = mkAssocResponse($keys);
 | |
|         $dumb = null;
 | |
|         $this->assertTrue(Auth_OpenID::isFailure($this->consumer->_extractAssociation($msg, $dumb)));
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Test for returning an error upon missing fields in association
 | |
|  * responses for OpenID 2
 | |
|  */
 | |
| class TestExtractAssociationMissingFieldsOpenID2 extends Tests_Auth_OpenID_AssociationResponse {
 | |
| 
 | |
|     function test_noFields_openid2()
 | |
|     {
 | |
|         $this->_run(array('ns'));
 | |
|     }
 | |
| 
 | |
|     function test_missingExpires_openid2()
 | |
|     {
 | |
|         $this->_run(array('assoc_handle', 'assoc_type', 'session_type', 'ns'));
 | |
|     }
 | |
| 
 | |
|     function test_missingHandle_openid2()
 | |
|     {
 | |
|         $this->_run(array('expires_in', 'assoc_type', 'session_type', 'ns'));
 | |
|     }
 | |
| 
 | |
|     function test_missingAssocType_openid2()
 | |
|     {
 | |
|         $this->_run(array('expires_in', 'assoc_handle', 'session_type', 'ns'));
 | |
|     }
 | |
| 
 | |
|     function test_missingSessionType_openid2()
 | |
|     {
 | |
|         $this->_run(array('expires_in', 'assoc_handle', 'assoc_type', 'ns'));
 | |
|     }
 | |
| }
 | |
| 
 | |
| /**
 | |
|  * Test for returning an error upon missing fields in association
 | |
|  * responses for OpenID 2
 | |
|  */
 | |
| class TestExtractAssociationMissingFieldsOpenID1 extends Tests_Auth_OpenID_AssociationResponse {
 | |
|     function test_noFields_openid1()
 | |
|     {
 | |
|         $this->_run(array());
 | |
|     }
 | |
| 
 | |
|     function test_missingExpires_openid1()
 | |
|     {
 | |
|         $this->_run(array('assoc_handle', 'assoc_type'));
 | |
|     }
 | |
| 
 | |
|     function test_missingHandle_openid1()
 | |
|     {
 | |
|         $this->_run(array('expires_in', 'assoc_type'));
 | |
|     }
 | |
| 
 | |
|     function test_missingAssocType_openid1()
 | |
|     {
 | |
|         $this->_run(array('expires_in', 'assoc_handle'));
 | |
|     }
 | |
| }
 | |
| 
 | |
| class DummyAssocationSession {
 | |
|     function DummyAssocationSession($session_type, $allowed_assoc_types=array())
 | |
|     {
 | |
|         $this->session_type = $session_type;
 | |
|         $this->allowed_assoc_types = $allowed_assoc_types;
 | |
|     }
 | |
| }
 | |
| 
 | |
| class ExtractAssociationSessionTypeMismatch extends Tests_Auth_OpenID_AssociationResponse {
 | |
|     function _run($requested_session_type, $response_session_type, $openid1=false)
 | |
|     {
 | |
|         global $association_response_values;
 | |
| 
 | |
|         $assoc_session = new DummyAssocationSession($requested_session_type);
 | |
|         $keys = array_keys($association_response_values);
 | |
|         if ($openid1) {
 | |
|             if (in_array('ns', $keys)) {
 | |
|                 unset($keys[array_search('ns', $keys)]);
 | |
|             }
 | |
|         }
 | |
| 
 | |
|         $msg = mkAssocResponse($keys);
 | |
|         $msg->setArg(Auth_OpenID_OPENID_NS, 'session_type',
 | |
|                      $response_session_type);
 | |
|         $this->assertTrue(
 | |
|            $this->consumer->_extractAssociation($msg, $assoc_session) === null);
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchNoEncBlank_openid2()
 | |
|     {
 | |
|         $this->_run('no-encryption', '');
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchDHSHA1NoEnc_openid2()
 | |
|     {
 | |
|         $this->_run('DH-SHA1', 'no-encryption');
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchDHSHA256NoEnc_openid2()
 | |
|     {
 | |
|         $this->_run('DH-SHA256', 'no-encryption');
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchNoEncDHSHA1_openid2()
 | |
|     {
 | |
|         $this->_run('no-encryption', 'DH-SHA1');
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchDHSHA1NoEnc_openid1()
 | |
|     {
 | |
|         $this->_run('DH-SHA1', 'DH-SHA256', true);
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchDHSHA256NoEnc_openid1()
 | |
|     {
 | |
|         $this->_run('DH-SHA256', 'DH-SHA1', true);
 | |
|     }
 | |
| 
 | |
|     function test_typeMismatchNoEncDHSHA1_openid1()
 | |
|     {
 | |
|         $this->_run('no-encryption', 'DH-SHA1', true);
 | |
|     }
 | |
| }
 | |
| 
 | |
| class TestOpenID1AssociationResponseSessionType extends Tests_Auth_OpenID_AssociationResponse {
 | |
|     function _run($expected_session_type, $session_type_value)
 | |
|     {
 | |
|         // Create a Message with just 'session_type' in it, since
 | |
|         // that's all this function will use. 'session_type' may be
 | |
|         // absent if it's set to None.
 | |
|         $args = array();
 | |
|         if ($session_type_value !== null) {
 | |
|             $args['session_type'] = $session_type_value;
 | |
|         }
 | |
|         $message = Auth_OpenID_Message::fromOpenIDArgs($args);
 | |
|         $this->assertTrue($message->isOpenID1());
 | |
| 
 | |
|         $actual_session_type = $this->consumer->_getOpenID1SessionType($message);
 | |
|         $error_message = sprintf('Returned sesion type parameter %s was expected ' .
 | |
|                                  'to yield session type %s, but yielded %s',
 | |
|                                  $session_type_value, $expected_session_type,
 | |
|                                  $actual_session_type);
 | |
|         $this->assertEquals(
 | |
|                             $expected_session_type,
 | |
|                             $actual_session_type,
 | |
|                             $error_message);
 | |
|     }
 | |
| 
 | |
|     function test_none()
 | |
|     {
 | |
|         $this->_run('no-encryption', null);
 | |
|     }
 | |
| 
 | |
|     function test_empty()
 | |
|     {
 | |
|         $this->_run('no-encryption', '');
 | |
|     }
 | |
| 
 | |
|     function test_explicitNoEncryption()
 | |
|     {
 | |
|         $this->_run('no-encryption', 'no-encryption');
 | |
|     }
 | |
| 
 | |
|     function test_dhSHA1()
 | |
|     {
 | |
|         $this->_run('DH-SHA1', 'DH-SHA1');
 | |
|     }
 | |
| 
 | |
|     // DH-SHA256 is not a valid session type for OpenID1, but this
 | |
|     // function does not test that. This is mostly just to make sure
 | |
|     // that it will pass-through stuff that is not explicitly handled,
 | |
|     // so it will get handled the same way as it is handled for OpenID
 | |
|     // 2
 | |
|     function test_dhSHA256()
 | |
|     {
 | |
|         $this->_run('DH-SHA256', 'DH-SHA256');
 | |
|     }
 | |
| }
 | |
| 
 | |
| class DummyAssociationSession {
 | |
|     var $secret = "shh! don't tell!";
 | |
|     var $extract_secret_called = false;
 | |
|     var $session_type = null;
 | |
|     var $allowed_assoc_types = null;
 | |
| 
 | |
|     function extractSecret($message)
 | |
|     {
 | |
|         $this->extract_secret_called = true;
 | |
|         return $this->secret;
 | |
|     }
 | |
| }
 | |
| 
 | |
| class TestInvalidFields extends Tests_Auth_OpenID_AssociationResponse {
 | |
|     function setUp()
 | |
|     {
 | |
|         parent::setUp();
 | |
|         $this->session_type = 'testing-session';
 | |
| 
 | |
|         // This must something that works for Association.fromExpiresIn
 | |
|         $this->assoc_type = 'HMAC-SHA1';
 | |
| 
 | |
|         $this->assoc_handle = 'testing-assoc-handle';
 | |
| 
 | |
|         // These arguments should all be valid
 | |
|         $this->assoc_response = Auth_OpenID_Message::fromOpenIDArgs(array(
 | |
|             'expires_in' => '1000',
 | |
|             'assoc_handle' => $this->assoc_handle,
 | |
|             'assoc_type' => $this->assoc_type,
 | |
|             'session_type' => $this->session_type,
 | |
|             'ns' => Auth_OpenID_OPENID2_NS,
 | |
|             ));
 | |
| 
 | |
|         $this->assoc_session = new DummyAssociationSession();
 | |
| 
 | |
|         // Make the session for the response's session type
 | |
|         $this->assoc_session->session_type = $this->session_type;
 | |
|         $this->assoc_session->allowed_assoc_types = array($this->assoc_type);
 | |
|     }
 | |
| 
 | |
|     function test_worksWithGoodFields()
 | |
|     {
 | |
|         // Handle a full successful association response
 | |
|         $assoc = $this->consumer->_extractAssociation(
 | |
|                    $this->assoc_response, $this->assoc_session);
 | |
|         $this->assertTrue($this->assoc_session->extract_secret_called);
 | |
|         $this->assertEquals($this->assoc_session->secret, $assoc->secret);
 | |
|         $this->assertEquals(1000, $assoc->lifetime);
 | |
|         $this->assertEquals($this->assoc_handle, $assoc->handle);
 | |
|         $this->assertEquals($this->assoc_type, $assoc->assoc_type);
 | |
|     }
 | |
| 
 | |
|     function test_badAssocType()
 | |
|     {
 | |
|         // Make sure that the assoc type in the response is not valid
 | |
|         // for the given session.
 | |
|         $this->assoc_session->allowed_assoc_types = array();
 | |
|         $this->assertTrue(
 | |
|              $this->consumer->_extractAssociation($this->assoc_response,
 | |
|                                                   $this->assoc_session) === null);
 | |
|     }
 | |
| 
 | |
|     function test_badExpiresIn()
 | |
|     {
 | |
|         // Invalid value for expires_in should cause failure
 | |
|         $this->assoc_response->setArg(Auth_OpenID_OPENID_NS, 'expires_in', 'forever');
 | |
|         $assoc = $this->consumer->_extractAssociation($this->assoc_response,
 | |
|                                                       $this->assoc_session);
 | |
|         $this->assertTrue(Auth_OpenID::isFailure($assoc));
 | |
|     }
 | |
| }
 | |
| 
 | |
| class TestExtractAssociationDiffieHellman extends Tests_Auth_OpenID_AssociationResponse {
 | |
|     var $secret = 'xxxxxxxxxxxxxxxxxxxx';
 | |
| 
 | |
|     function _setUpDH()
 | |
|     {
 | |
|         list($sess, $message) = $this->consumer->_createAssociateRequest(
 | |
|                                   $this->endpoint, 'HMAC-SHA1', 'DH-SHA1');
 | |
| 
 | |
|         // XXX: this is testing _createAssociateRequest
 | |
|         $this->assertEquals($this->endpoint->compatibilityMode(),
 | |
|                             $message->isOpenID1());
 | |
| 
 | |
|         $server_sess = Auth_OpenID_DiffieHellmanSHA1ServerSession::fromMessage($message);
 | |
|         $server_resp = $server_sess->answer($this->secret);
 | |
|         $server_resp['assoc_type'] = 'HMAC-SHA1';
 | |
|         $server_resp['assoc_handle'] = 'handle';
 | |
|         $server_resp['expires_in'] = '1000';
 | |
|         $server_resp['session_type'] = 'DH-SHA1';
 | |
|         return array($sess, Auth_OpenID_Message::fromOpenIDArgs($server_resp));
 | |
|     }
 | |
| 
 | |
|     function test_success()
 | |
|     {
 | |
|         list($sess, $server_resp) = $this->_setUpDH();
 | |
|         $ret = $this->consumer->_extractAssociation($server_resp, $sess);
 | |
|         $this->assertTrue($ret !== null);
 | |
|         $this->assertEquals($ret->assoc_type, 'HMAC-SHA1');
 | |
|         $this->assertEquals($ret->secret, $this->secret);
 | |
|         $this->assertEquals($ret->handle, 'handle');
 | |
|         $this->assertEquals($ret->lifetime, 1000);
 | |
|     }
 | |
| 
 | |
|     function test_openid2success()
 | |
|     {
 | |
|         // Use openid 2 type in endpoint so _setUpDH checks
 | |
|         // compatibility mode state properly
 | |
|         $this->endpoint->type_uris = array(Auth_OpenID_TYPE_2_0,
 | |
|                                            Auth_OpenID_TYPE_1_1);
 | |
|         $this->test_success();
 | |
|     }
 | |
| 
 | |
|     /**
 | |
|      * Can't run this test because the base64 decoder is broken.
 | |
|      */
 | |
|     /*
 | |
|     function test_badDHValues()
 | |
|     {
 | |
|         list($sess, $server_resp) = $this->_setUpDH();
 | |
|         $server_resp->setArg(Auth_OpenID_OPENID_NS, 'enc_mac_key', "\x00\x00\x00");
 | |
|         $this->assertTrue($this->consumer->_extractAssociation($server_resp, $sess) === null);
 | |
|     }
 | |
|     */
 | |
| }
 | |
| 
 | |
| global $Tests_Auth_OpenID_AssociationResponse_other;
 | |
| $Tests_Auth_OpenID_AssociationResponse_other = array(
 | |
|                                                      new TestInvalidFields(),
 | |
|                                                      new TestOpenID1AssociationResponseSessionType(),
 | |
|                                                      new ExtractAssociationSessionTypeMismatch(),
 | |
|                                                      new TestExtractAssociationMissingFieldsOpenID1(),
 | |
|                                                      new TestExtractAssociationMissingFieldsOpenID2()
 | |
|                                                      );
 | |
| 
 | |
| if (!defined('Auth_OpenID_NO_MATH_SUPPORT')) {
 | |
|     $Tests_Auth_OpenID_AssociationResponse_other[] = new TestExtractAssociationDiffieHellman();
 | |
| }
 | |
| 
 |