diff --git a/composer.json b/composer.json index 2de9a8621d..8747b47e78 100644 --- a/composer.json +++ b/composer.json @@ -25,7 +25,7 @@ }, "require-dev": { "satooshi/php-coveralls": "~0.6", - "phpunit/phpunit": "~3.7", + "phpunit/phpunit": "~4.1", "codacy/coverage": "dev-master", "phpunit/phpunit-selenium": "~1.2", "squizlabs/php_codesniffer": "2.*" diff --git a/libraries/Response.php b/libraries/Response.php index dc37f6701f..f66982da3a 100644 --- a/libraries/Response.php +++ b/libraries/Response.php @@ -389,5 +389,24 @@ class Response $buffer->flush(); exit; } -} + /** + * Wrapper around PHP's header() function. + * + * @return void + */ + public function header($text) + { + header($text); + } + + /** + * Wrapper around PHP's headers_sent() function. + * + * @return bool + */ + public function headersSent() + { + return headers_sent(); + } +} diff --git a/libraries/core.lib.php b/libraries/core.lib.php index de55573192..1acd47ffa9 100644 --- a/libraries/core.lib.php +++ b/libraries/core.lib.php @@ -498,21 +498,23 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false) return; } + $response = PMA\libraries\Response::getInstance(); + if (SID) { if (mb_strpos($uri, '?') === false) { - header('Location: ' . $uri . '?' . SID); + $response->header('Location: ' . $uri . '?' . SID); } else { $separator = PMA_URL_getArgSeparator(); - header('Location: ' . $uri . $separator . SID); + $response->header('Location: ' . $uri . $separator . SID); } return; } session_write_close(); - if (headers_sent()) { + if ($response->headersSent()) { if (function_exists('debug_print_backtrace')) { echo '
';
- debug_print_backtrace();
+# debug_print_backtrace();
echo '';
}
trigger_error(
@@ -524,9 +526,9 @@ function PMA_sendHeaderLocation($uri, $use_refresh = false)
// results in a blank page
// but we need it when coming from the cookie login panel)
if (PMA_IS_IIS && $use_refresh) {
- header('Refresh: 0; ' . $uri);
+ $response->header('Refresh: 0; ' . $uri);
} else {
- header('Location: ' . $uri);
+ $response->header('Location: ' . $uri);
}
}
diff --git a/libraries/plugins/auth/AuthenticationHttp.php b/libraries/plugins/auth/AuthenticationHttp.php
index 065b39d405..170d7c1e0e 100644
--- a/libraries/plugins/auth/AuthenticationHttp.php
+++ b/libraries/plugins/auth/AuthenticationHttp.php
@@ -71,16 +71,18 @@ class AuthenticationHttp extends AuthenticationPlugin
} else {
$realm_message = $GLOBALS['cfg']['Server']['auth_http_realm'];
}
+
+ $response = Response::getInstance();
+
// remove non US-ASCII to respect RFC2616
$realm_message = preg_replace('/[^\x20-\x7e]/i', '', $realm_message);
- header('WWW-Authenticate: Basic realm="' . $realm_message . '"');
- header('HTTP/1.0 401 Unauthorized');
+ $response->header('WWW-Authenticate: Basic realm="' . $realm_message . '"');
+ $response->header('HTTP/1.0 401 Unauthorized');
if (php_sapi_name() !== 'cgi-fcgi') {
- header('status: 401 Unauthorized');
+ $response->header('status: 401 Unauthorized');
}
/* HTML header */
- $response = Response::getInstance();
$footer = $response->getFooter();
$footer->setMinimal();
$header = $response->getHeader();
diff --git a/test/classes/plugin/auth/AuthenticationHttpTest.php b/test/classes/plugin/auth/AuthenticationHttpTest.php
index 8fe2818a99..20e5b81b33 100644
--- a/test/classes/plugin/auth/AuthenticationHttpTest.php
+++ b/test/classes/plugin/auth/AuthenticationHttpTest.php
@@ -51,33 +51,8 @@ class AuthenticationHttpTest extends PMATestCase
unset($this->object);
}
- /**
- * Test for PMA\libraries\plugins\auth\AuthenticationHttp::auth
- *
- * @return void
- */
- public function testAuth()
+ public function doMockResponse($set_minimal, $body_id, $set_title)
{
- if (! defined('PMA_TEST_HEADERS')) {
- $this->markTestSkipped(
- 'Cannot redefine constant/function - missing runkit extension'
- );
- }
-
- $_REQUEST['old_usr'] = '1';
- $GLOBALS['cfg']['Server']['LogoutURL'] = 'http://phpmyadmin.net/logout';
-
- $this->assertFalse(
- $this->object->auth()
- );
-
- $this->assertContains(
- 'Location: http://phpmyadmin.net/logout',
- $GLOBALS['header'][0]
- );
-
- // case 2
-
$restoreInstance = PMA\libraries\Response::getInstance();
// mock footer
@@ -86,7 +61,7 @@ class AuthenticationHttpTest extends PMATestCase
->setMethods(array('setMinimal'))
->getMock();
- $mockFooter->expects($this->once())
+ $mockFooter->expects($this->exactly($set_minimal))
->method('setMinimal')
->with();
@@ -99,35 +74,40 @@ class AuthenticationHttpTest extends PMATestCase
)
->getMock();
- $mockHeader->expects($this->once())
+ $mockHeader->expects($this->exactly($body_id))
->method('setBodyId')
->with('loginform');
- $mockHeader->expects($this->once())
+ $mockHeader->expects($this->exactly($set_title))
->method('setTitle')
->with('Access denied!');
- $mockHeader->expects($this->once())
+ $mockHeader->expects($this->exactly($set_title))
->method('disableMenuAndConsole')
->with();
// set mocked headers and footers
$mockResponse = $this->getMockBuilder('PMA\libraries\Response')
->disableOriginalConstructor()
- ->setMethods(array('getHeader', 'getFooter', 'addHTML'))
+ ->setMethods(array('getHeader', 'getFooter', 'addHTML', 'header', 'headersSent'))
->getMock();
- $mockResponse->expects($this->once())
+ $mockResponse->expects($this->exactly($set_title))
->method('getFooter')
->with()
->will($this->returnValue($mockFooter));
- $mockResponse->expects($this->once())
+ $mockResponse->expects($this->exactly($set_title))
->method('getHeader')
->with()
->will($this->returnValue($mockHeader));
- $mockResponse->expects($this->exactly(6))
+ $mockResponse->expects($this->any())
+ ->method('headersSent')
+ ->with()
+ ->will($this->returnValue(false));
+
+ $mockResponse->expects($this->exactly($set_title * 6))
->method('addHTML')
->with();
@@ -135,59 +115,73 @@ class AuthenticationHttpTest extends PMATestCase
$attrInstance->setAccessible(true);
$attrInstance->setValue($mockResponse);
- $GLOBALS['header'] = array();
- $_REQUEST['old_usr'] = '';
- $GLOBALS['cfg']['Server']['verbose'] = 'verboseMessagê';
+ $headers = array_slice(func_get_args(), 3);
+
+ $header_method = $mockResponse->expects($this->exactly(count($headers)))
+ ->method('header');
+
+ call_user_func_array(array($header_method, 'withConsecutive'), $headers);
$this->assertFalse(
$this->object->auth()
);
- $this->assertEquals(
- array(
- 'WWW-Authenticate: Basic realm="phpMyAdmin verboseMessag"',
- 'HTTP/1.0 401 Unauthorized',
- 'status: 401 Unauthorized'
- ),
- $GLOBALS['header']
- );
-
$attrInstance->setValue($restoreInstance);
+ }
- // case 3
+ /**
+ * Test for PMA\libraries\plugins\auth\AuthenticationHttp::auth
+ *
+ * @return void
+ */
+ public function testAuthLogoutUrl()
+ {
- $GLOBALS['header'] = array();
+ $_REQUEST['old_usr'] = '1';
+ $GLOBALS['cfg']['Server']['LogoutURL'] = 'http://phpmyadmin.net/logout';
+
+ $this->doMockResponse(
+ 0, 0, 0,
+ array('Location: http://phpmyadmin.net/logout')
+ );
+ }
+
+ public function testAuthVerbose()
+ {
+ $_REQUEST['old_usr'] = '';
+ $GLOBALS['cfg']['Server']['verbose'] = 'verboseMessagê';
+
+ $this->doMockResponse(
+ 1, 1, 1,
+ array('WWW-Authenticate: Basic realm="phpMyAdmin verboseMessag"'),
+ array('HTTP/1.0 401 Unauthorized'),
+ array('status: 401 Unauthorized')
+ );
+ }
+
+ public function testAuthHost()
+ {
$GLOBALS['cfg']['Server']['verbose'] = '';
$GLOBALS['cfg']['Server']['host'] = 'hòst';
- $this->assertFalse(
- $this->object->auth()
+
+ $this->doMockResponse(
+ 1, 1, 1,
+ array('WWW-Authenticate: Basic realm="phpMyAdmin hst"'),
+ array('HTTP/1.0 401 Unauthorized'),
+ array('status: 401 Unauthorized')
);
+ }
- $this->assertEquals(
- array(
- 'WWW-Authenticate: Basic realm="phpMyAdmin hst"',
- 'HTTP/1.0 401 Unauthorized',
- 'status: 401 Unauthorized'
- ),
- $GLOBALS['header']
- );
-
- // case 4
-
- $GLOBALS['header'] = array();
+ public function testAuthRealm()
+ {
$GLOBALS['cfg']['Server']['host'] = '';
$GLOBALS['cfg']['Server']['auth_http_realm'] = 'rêäealmmessage';
- $this->assertFalse(
- $this->object->auth()
- );
- $this->assertEquals(
- array(
- 'WWW-Authenticate: Basic realm="realmmessage"',
- 'HTTP/1.0 401 Unauthorized',
- 'status: 401 Unauthorized'
- ),
- $GLOBALS['header']
+ $this->doMockResponse(
+ 1, 1, 1,
+ array('WWW-Authenticate: Basic realm="realmmessage"'),
+ array('HTTP/1.0 401 Unauthorized'),
+ array('status: 401 Unauthorized')
);
}