Skip to content

Commit

Permalink
PHPCAS-109 Allow exiting in normal mode or throwing exceptions when t…
Browse files Browse the repository at this point in the history
…esting via phpunit.

This is an alternative to commit 24935 which should be reverted if this commit is kept.

git-svn-id: https://source.jasig.org/cas-clients/phpcas/branches/PHPCAS-109@24940 f5dbab47-78f9-eb45-b975-e544023573eb
  • Loading branch information
adamfranco committed Sep 10, 2011
1 parent 9908d7a commit 3b47c80
Show file tree
Hide file tree
Showing 4 changed files with 153 additions and 2 deletions.
25 changes: 24 additions & 1 deletion source/CAS.php
Original file line number Diff line number Diff line change
Expand Up @@ -1756,7 +1756,30 @@ public static function addRebroadcastHeader($header) {
}
$PHPCAS_CLIENT->addRebroadcastHeader($header);
phpCAS :: traceEnd();
}
}

private static $throwExceptionsInsteadOfExiting = false;
/**
* Force phpcas to thow Exceptions instead of calling exit()
* Needed for unit testing. Generally shouldn't be used in production
* due to an increase in Apache error logging if CAS_GracefulTerminiationExceptions
* are not caught and handled.
*/
public static function throwExceptionsInsteadOfExiting() {
self::$throwExceptionsInsteadOfExiting = true;
}

/**
* Answer true if throwExceptionsInsteadOfExiting() has been set.
* Needed for unit testing. Generally shouldn't be used in production
* due to an increase in Apache error logging if CAS_GracefulTerminiationExceptions
* are not caught and handled.
*
* @return boolean
*/
public static function shouldThrowExceptionsInsteadOfExiting () {
return self::$throwExceptionsInsteadOfExiting;
}
}

// ########################################################################
Expand Down
5 changes: 4 additions & 1 deletion source/CAS/Client.php
Original file line number Diff line number Diff line change
Expand Up @@ -1227,7 +1227,10 @@ private function wasPreviouslyAuthenticated()
public function redirectToCas($gateway=false,$renew=false){
phpCAS::traceBegin();
$cas_url = $this->getServerLoginURL($gateway,$renew);
header('Location: '.$cas_url);
if (php_sapi_name() === 'cli')
@header('Location: '.$cas_url);
else
header('Location: '.$cas_url);
phpCAS::trace( "Redirect to : ".$cas_url );

$this->printHTMLHeader($this->getString(CAS_STR_AUTHENTICATION_WANTED));
Expand Down
18 changes: 18 additions & 0 deletions source/CAS/GracefullTerminationException.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,24 @@ class CAS_GracefullTerminationException
extends RuntimeException
implements CAS_Exception
{

/**
* Test if exceptions should be thrown or if we should just exit.
* In production usage we want to just exit cleanly when prompting the user
* for a redirect without filling the error logs with uncaught exceptions.
* In unit testing scenarios we cannot exit or we won't be able to continue
* with our tests.
*/
public function __construct ($message = 'Terminate Gracefully', $code = 0) {
// Throw exceptions to allow unit testing to continue;
if (phpCAS::shouldThrowExceptionsInsteadOfExiting()) {
parent::__construct($message, $code);
}
// Exit cleanly to avoid filling up the logs with uncaught exceptions.
else {
exit;
}
}

}
?>
107 changes: 107 additions & 0 deletions test/tests/AuthenticationTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
<?php
require_once dirname(__FILE__).'/../harness/DummyRequest.php';
require_once dirname(__FILE__).'/../harness/BasicResponse.php';

/**
* Test class for verifying the operation of service tickets.
*
*
* Generated by PHPUnit on 2010-09-07 at 13:33:53.
*/
class AuthenticationTest extends PHPUnit_Framework_TestCase
{
/**
* @var CAS_Client
*/
protected $object;

/**
* Sets up the fixture, for example, opens a network connection.
* This method is called before a test is executed.
*/
protected function setUp()
{
// phpCAS::setDebug(dirname(__FILE__).'/../test.log');
// error_reporting(E_ALL);

phpCAS::throwExceptionsInsteadOfExiting();

$_SERVER['SERVER_NAME'] = 'www.clientapp.com';
$_SERVER['SERVER_PORT'] = '80';
$_SERVER['SERVER_PROTOCOL'] = 'HTTP/1.1';
$_SERVER['SERVER_ADMIN'] = 'root@localhost';
$_SERVER['REQUEST_URI'] = '/';
$_SERVER['SCRIPT_NAME'] = '/index.php';
$_SERVER['PHP_SELF'] = '/index.php';
$_SESSION = array();

$this->object = new CAS_Client(
CAS_VERSION_2_0, // Server Version
true, // Proxy
'cas.example.edu', // Server Hostname
443, // Server port
'/cas/', // Server URI
false // Start Session
);

$this->object->setRequestImplementation('CAS_TestHarness_DummyRequest');
$this->object->setCasServerCACert('/path/to/ca_cert.crt');


/*********************************************************
* Enumerate our responses
*********************************************************/

// Set up our response.
$response = new CAS_TestHarness_BasicResponse('https', 'cas.example.edu', '/cas/serviceValidate');
$response->setResponseHeaders(array(
'HTTP/1.1 200 OK',
'Date: Wed, 29 Sep 2010 19:20:57 GMT',
'Server: Apache-Coyote/1.1',
'Pragma: no-cache',
'Expires: Thu, 01 Jan 1970 00:00:00 GMT',
'Cache-Control: no-cache, no-store',
'Content-Type: text/html;charset=UTF-8',
'Content-Language: en-US',
'Via: 1.1 cas.example.edu',
'Connection: close',
'Transfer-Encoding: chunked',
));
$response->setResponseBody(
"<cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'>
<cas:authenticationSuccess>
<cas:user>jsmith</cas:user>
</cas:authenticationSuccess>
</cas:serviceResponse>
");
CAS_TestHarness_DummyRequest::addResponse($response);


}

/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown()
{
CAS_TestHarness_DummyRequest::clearResponses();
$_SESSION = array();
}

/**
* Test that the user is redirected to the CAS server
*/
public function test_redirect() {
try {
ob_start();
$this->object->forceAuthentication();
$this->assertTrue(false, 'Should have thrown a CAS_GracefullTerminationException.');
} catch (CAS_GracefullTerminationException $e) {
ob_end_clean();
// It would be great to test for the existance of headers here, but
// the don't get set properly due to output before the test.
}

}
}

0 comments on commit 3b47c80

Please sign in to comment.