diff --git a/src/HAB/Pica/Auth/AbstractHttpAuthentication.php b/src/HAB/Pica/Auth/AbstractHttpAuthentication.php new file mode 100644 index 0000000000000000000000000000000000000000..6c48840f3371180e5b97ac7ce03f238f60e8c011 --- /dev/null +++ b/src/HAB/Pica/Auth/AbstractHttpAuthentication.php @@ -0,0 +1,70 @@ +<?php + +/** + * This file is part of PicaAuth. + * + * PicaAuth is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * PicaAuth is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with PicaAuth. If not, see <http://www.gnu.org/licenses/>. + * + * @author David Maus <maus@hab.de> + * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel + * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher + */ + +namespace HAB\Pica\Auth; + +use RuntimeException; + +/** + * Abstract base class of HTTP based authentication. + * + * @author David Maus <maus@hab.de> + * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel + * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher + */ +abstract class AbstractHttpAuthentication +{ + /** + * Send a HTTP request. + * + * @param string $method + * @param string $url + * @param array $header + * @param string $body + * @return string + */ + public function sendRequest ($method, $url, array $header = array(), $body = null) + { + $ctxOptions = array( + 'http' => array( + 'method' => $method, + 'header' => implode("\r\n", $header), + 'content' => $body + ) + ); + $ctx = stream_context_create($ctxOptions); + $response = @file_get_contents($url, false, $ctx); + if ($response === false) { + throw new RuntimeException("Error sending HTTP '{$method}' request to '{$url}'"); + } + + $statuscode = null; + if (preg_match('@^HTTP/\d+\.\d+ (?<statuscode>\d+)@i', $http_response_header[0], $matches)) { + $statuscode = $matches['statuscode']; + } + if ($statuscode < 200 || $statuscode > 299) { + throw new RuntimeException("Unexpected HTTP status code in server response: {$statuscode}"); + } + return $response; + } +} \ No newline at end of file diff --git a/src/HAB/Pica/Auth/LBSAuthentication.php b/src/HAB/Pica/Auth/LBSAuthentication.php index 6c76e5529cd47f6031918f0bbe72533f4a41631c..236b0276a413f4b4b4bd51dc9b7ba1ea8ec06fe3 100644 --- a/src/HAB/Pica/Auth/LBSAuthentication.php +++ b/src/HAB/Pica/Auth/LBSAuthentication.php @@ -25,9 +25,6 @@ namespace HAB\Pica\Auth; use RuntimeException; -use GuzzleHttp\Client; -use GuzzleHttp\Exception\RequestException; - /** * Authenticate user against the LBS4 Authentication webservice. * @@ -35,7 +32,7 @@ use GuzzleHttp\Exception\RequestException; * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher */ -class LBSAuthentication implements AuthenticationInterface +class LBSAuthentication extends AbstractHttpAuthentication implements AuthenticationInterface { /** * Service URL. @@ -58,13 +55,6 @@ class LBSAuthentication implements AuthenticationInterface */ private $lbsUserNumber; - /** - * HTTP client. - * - * @var Client - */ - private $client; - /** * Constructor. * @@ -92,28 +82,11 @@ class LBSAuthentication implements AuthenticationInterface 'FNO' => $this->catalogNumber, 'LNG' => 'EN' ); - try { - $response = $this->getClient()->get($this->serviceUrl, array('query' => $query)); - } catch (RequestException $e) { - throw new RuntimeException(null, -1, $e); - } - $attributes = $this->parseResponseBody($response->getBody()); + $response = $this->sendRequest('GET', sprintf('%s?%s', $this->serviceUrl, http_build_query($query))); + $attributes = $this->parseResponseBody($response); return $attributes; } - /** - * Return HTTP client. - * - * @return Client - */ - public function getClient () - { - if ($this->client === null) { - $this->client = new Client(); - } - return $this->client; - } - /** * Parse response body and user return attributes. * diff --git a/src/HAB/Pica/Auth/LOAN3WebAuthentication.php b/src/HAB/Pica/Auth/LOAN3WebAuthentication.php index 323ce6b4a1eaecf0c7fd603afa24d57f5c86ea10..a1bc35bf74500c009477a29e9c43b219cb2a3f41 100644 --- a/src/HAB/Pica/Auth/LOAN3WebAuthentication.php +++ b/src/HAB/Pica/Auth/LOAN3WebAuthentication.php @@ -23,11 +23,6 @@ namespace HAB\Pica\Auth; -use RuntimeException; - -use GuzzleHttp\Client; -use GuzzleHttp\Exception\RequestException; - /** * Authenticate user against a LOAN3 web interface. * @@ -35,7 +30,7 @@ use GuzzleHttp\Exception\RequestException; * @copyright (c) 2015 by Herzog August Bibliothek Wolfenbüttel * @license http://www.gnu.org/licenses/gpl.txt GNU General Public License v3 or higher */ -class LOAN3WebAuthentication implements AuthenticationInterface +class LOAN3WebAuthentication extends AbstractHttpAuthentication implements AuthenticationInterface { /** * Service URL. @@ -44,13 +39,6 @@ class LOAN3WebAuthentication implements AuthenticationInterface */ private $serviceUrl; - /** - * HTTP client. - * - * @var Client - */ - private $client; - /** * Constructor. * @@ -72,27 +60,16 @@ class LOAN3WebAuthentication implements AuthenticationInterface 'BOR_PW' => $password, 'ACT' => 'UI_DATA', ); - try { - $response = $this->getClient()->post($this->serviceUrl, array('body' => $query)); - } catch (RequestException $e) { - throw new RuntimeException(null, -1, $e); - } - $attributes = $this->parseResponseBody($response->getBody()); + $response = $this->sendRequest( + 'POST', + $this->serviceUrl, + array('Content-Type: application/x-www-form-urlencoded'), + http_build_query($query) + ); + $attributes = $this->parseResponseBody($response); return $attributes; } - /** - * Return HTTP client. - * - * @return Client - */ - public function getClient () - { - if ($this->client === null) { - $this->client = new Client(); - } - return $this->client; - } /** * Parse response body and user return attributes. diff --git a/tests/unit-tests/data/lbs4authentication.error.response b/tests/unit-tests/data/lbs4authentication.error.response index 6af4cd127b9045d0dd489b0acaa4b6ffb2094214..953d378b2a69bf582265a1127b737b00489415e2 100644 --- a/tests/unit-tests/data/lbs4authentication.error.response +++ b/tests/unit-tests/data/lbs4authentication.error.response @@ -1,7 +1 @@ -HTTP/1.1 200 OK -Date: Wed, 06 May 2015 09:43:16 GMT -Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11 -Content-Length: 168 -Content-Type: application/xml - <?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>NOK</status><error>Wrong password and/or number.</error></AuthenticationResponse> \ No newline at end of file diff --git a/tests/unit-tests/data/lbs4authentication.success.response b/tests/unit-tests/data/lbs4authentication.success.response index 7d048ffe719710f44bbc90b8a3825737f60b6b9b..a3291cbc4cf1a8114a3326b896dc41919bf54d4e 100644 --- a/tests/unit-tests/data/lbs4authentication.success.response +++ b/tests/unit-tests/data/lbs4authentication.success.response @@ -1,7 +1 @@ -HTTP/1.1 200 OK -Date: Wed, 06 May 2015 09:42:33 GMT -Server: Apache/2.2.13 (Unix) mod_jk/1.2.28 mod_ssl/2.2.13 OpenSSL/0.9.8k PHP/5.2.11 -Content-Length: 232 -Content-Type: application/xml - <?xml version="1.0" encoding="UTF-8" standalone="yes"?><AuthenticationResponse><status>OK</status><sessionID>c3ac4981-eb02-46f5-b092-d7261d08386f</sessionID><userKey>username</userKey><userGroup>20</userGroup></AuthenticationResponse> \ No newline at end of file diff --git a/tests/unit-tests/data/loan3authentication.error.response b/tests/unit-tests/data/loan3authentication.error.response index 834c16552aa8b7fa990da13c0760debf8f7b6156..10d5b0a9b316c8b99060d366ee36e9ea65e5647b 100644 --- a/tests/unit-tests/data/loan3authentication.error.response +++ b/tests/unit-tests/data/loan3authentication.error.response @@ -1,15 +1,3 @@ -HTTP/1.1 200 OK -Date: Wed, 06 May 2015 12:12:11 GMT -Server: opc4/2.8.4.0-vzg8-dbs1 -Content-Length: 18777 -X-PSI-Class: loan -X-PSI-Context: USERINFO_LOGIN -Content-Type: text/html; charset=UTF-8 -Keep-Alive: timeout=5, max=100 -Connection: Keep-Alive -X-Pad: avoid browser bug - - <HTML> <HEAD> <TITLE>OPC4 - borrower/identification</TITLE> diff --git a/tests/unit-tests/data/loan3authentication.success.response b/tests/unit-tests/data/loan3authentication.success.response index ad9d9769163272543c47a33b532033022fb855a5..2c7cd2e9a849f813309f68b23ee16037cb953f1e 100644 --- a/tests/unit-tests/data/loan3authentication.success.response +++ b/tests/unit-tests/data/loan3authentication.success.response @@ -1,14 +1,3 @@ -HTTP/1.1 200 OK -Date: Wed, 06 May 2015 12:13:33 GMT -Server: opc4/2.8.4.0-vzg8-dbs1 -Content-Length: 17414 -X-PSI-Class: loan -X-PSI-Context: USERINFO -Content-Type: text/html; charset=UTF-8 -Keep-Alive: timeout=5, max=100 -Connection: Keep-Alive - - <HTML> <HEAD> <TITLE>OPC4 - borrower/userdata</TITLE> diff --git a/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php index 08c1e73a2743c5e8f4ae4a7fb55f652566877349..a04798548b9872f4e64588bbd0f345418b731fe2 100644 --- a/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php +++ b/tests/unit-tests/src/HAB/Pica/Auth/LBSAuthenticationTest.php @@ -23,8 +23,6 @@ namespace HAB\Pica\Auth; -use GuzzleHttp\Subscriber\Mock; - use PHPUnit_Framework_TestCase as TestCase; /** @@ -36,31 +34,25 @@ use PHPUnit_Framework_TestCase as TestCase; */ class LBSAuthenticationTest extends TestCase { - /** - * @expectedException RuntimeException - */ - public function testRuntimeExceptionOnRemoteError () - { - $service = new LBSAuthentication('invalid://example.org/', 0, 0); - $response = new Mock(array('HTTP/1.1 500 Internal Server Error')); - $service->getClient()->getEmitter()->attach($response); - $service->authenticate('username', 'password'); - } - public function testAuthenticationFailure () { - $service = new LBSAuthentication('invalid://example.org/', 0, 0); - $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.error.response'))); - $service->getClient()->getEmitter()->attach($response); + $service = $this->getMock('HAB\Pica\Auth\LBSAuthentication', array('sendRequest'), array('', 0, 0)); + $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.error.response'); + $service->expects($this->once()) + ->method('sendRequest') + ->will($this->returnValue($response)); + $attributes = $service->authenticate('username', 'password'); $this->assertFalse($attributes); } public function testAuthenticationSuccess () { - $service = new LBSAuthentication('invalid://example.org/', 0, 0); - $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.success.response'))); - $service->getClient()->getEmitter()->attach($response); + $service = $this->getMock('HAB\Pica\Auth\LBSAuthentication', array('sendRequest'), array('', 0, 0)); + $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/lbs4authentication.success.response'); + $service->expects($this->once()) + ->method('sendRequest') + ->will($this->returnValue($response)); $attributes = $service->authenticate('username', 'password'); $this->assertInternalType('array', $attributes); $this->assertNotEmpty($attributes); diff --git a/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php b/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php index cf707cae02a0011d6a779d7ff41b34702855b72a..f8d81680851def9f14099df27774e1084ca1a933 100644 --- a/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php +++ b/tests/unit-tests/src/HAB/Pica/Auth/LOAN3WebAuthenticationTest.php @@ -23,8 +23,6 @@ namespace HAB\Pica\Auth; -use GuzzleHttp\Subscriber\Mock; - use PHPUnit_Framework_TestCase as TestCase; /** @@ -36,31 +34,25 @@ use PHPUnit_Framework_TestCase as TestCase; */ class LOAN3WebAuthenticationTest extends TestCase { - /** - * @expectedException RuntimeException - */ - public function testRuntimeExceptionOnRemoteError () - { - $service = new LOAN3WebAuthentication('invalid://example.lorg'); - $response = new Mock(array('HTTP/1.1 500 Internal Server Error')); - $service->getClient()->getEmitter()->attach($response); - $service->authenticate('username', 'password'); - } public function testAuthenticationFailure () { - $service = new LOAN3WebAuthentication('invalid://example.org/', 0, 0); - $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.error.response'))); - $service->getClient()->getEmitter()->attach($response); + $service = $this->getMock('HAB\Pica\Auth\LOAN3WebAuthentication', array('sendRequest'), array('invalid://example.org/')); + $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.error.response'); + $service->expects($this->once()) + ->method('sendRequest') + ->will($this->returnValue($response)); $attributes = $service->authenticate('username', 'password'); $this->assertFalse($attributes); } public function testAuthenticationSuccess () { - $service = new LOAN3WebAuthentication('invalid://example.org/', 0, 0); - $response = new Mock(array(file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.success.response'))); - $service->getClient()->getEmitter()->attach($response); + $service = $this->getMock('HAB\Pica\Auth\LOAN3WebAuthentication', array('sendRequest'), array('invalid://example.org/')); + $response = file_get_contents(APP_TESTDIR . '/unit-tests/data/loan3authentication.success.response'); + $service->expects($this->once()) + ->method('sendRequest') + ->will($this->returnValue($response)); $attributes = $service->authenticate('username', 'password'); $this->assertInternalType('array', $attributes); $this->assertNotEmpty($attributes);