diff --git a/local/config/vufind/FincILS.ini b/local/config/vufind/FincILS.ini index e7130606055e143ff0927761be1fc60ade505186..e4c97195dceaf3706027d530d18196c32aa9fb03 100644 --- a/local/config/vufind/FincILS.ini +++ b/local/config/vufind/FincILS.ini @@ -56,6 +56,10 @@ ; baseUrl = http://139.18.19.238:9080/paiatheca/paia/ISIL/ ; baseUrl = http://139.18.19.238:9080/paialibero/paia/ISIL/ +;FincILS specific configuration for PAIA root-access +;root_username = 'root' +;root_password = '' + ; config-examples: ; DE-15 diff --git a/module/finc/config/module.config.php b/module/finc/config/module.config.php index 88fbecf913598000f5a8ae91c1e42f06e8167406..f2cd21b9e14f4ff3b4424dd12841c444f2ca3112 100644 --- a/module/finc/config/module.config.php +++ b/module/finc/config/module.config.php @@ -9,6 +9,11 @@ $config = [ ], 'vufind' => [ 'plugin_managers' => [ + 'auth' => [ + 'invokables' => [ + 'shibboleth' => 'finc\Auth\Shibboleth', + ], + ], 'ils_driver' => [ 'factories' => [ 'fincils' => 'finc\ILS\Driver\Factory::getFincILS', diff --git a/module/finc/src/finc/Auth/Shibboleth.php b/module/finc/src/finc/Auth/Shibboleth.php new file mode 100644 index 0000000000000000000000000000000000000000..4f12492361866d6181cc1112ef44b4eea4dfb4f4 --- /dev/null +++ b/module/finc/src/finc/Auth/Shibboleth.php @@ -0,0 +1,106 @@ +<?php +/** + * Shibboleth authentication module. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2014. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2, + * as published by the Free Software Foundation. + * + * This program 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 this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * @category VuFind2 + * @package Authentication + * @author Franck Borel <franck.borel@gbv.de> + * @author Jochen Lienhard <lienhard@ub.uni-freiburg.de> + * @author Bernd Oberknapp <bo@ub.uni-freiburg.de> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://www.vufind.org Main Page + */ +namespace finc\Auth; +use \VuFind\Exception\Auth as AuthException; +use \VuFind\XSLT\Import\VuFind; + +/** + * Shibboleth authentication module. + * + * @category VuFind2 + * @package Authentication + * @author Franck Borel <franck.borel@gbv.de> + * @author Jochen Lienhard <lienhard@ub.uni-freiburg.de> + * @author Bernd Oberknapp <bo@ub.uni-freiburg.de> + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://www.vufind.org Main Page + */ +class Shibboleth extends \VuFind\Auth\Shibboleth +{ + /** + * Attempt to authenticate the current user. Throws exception if login fails. + * + * @param \Zend\Http\PhpEnvironment\Request $request Request object containing + * account credentials. + * + * @throws AuthException + * @return \VuFind\Db\Row\User Object representing logged-in user. + */ + public function authenticate($request) + { + // Check if username is set. + $shib = $this->getConfig()->Shibboleth; + $username = $request->getServer()->get($shib->username); + if (empty($username)) { + throw new AuthException('authentication_error_admin'); + } + + // Check if required attributes match up: + foreach ($this->getRequiredAttributes() as $key => $value) { + if (!preg_match('/' . $value . '/', $request->getServer()->get($key))) { + throw new AuthException('authentication_error_denied'); + } + } + + // If we made it this far, we should log in the user! + $user = $this->getUserTable()->getByUsername($username); + + // Variable to hold catalog password (handled separately from other + // attributes since we need to use saveCredentials method to store it): + $catPassword = null; + + // Has the user configured attributes to use for populating the user table? + $attribsToCheck = [ + 'cat_username', 'cat_password', 'email', 'lastname', 'firstname', + 'college', 'major', 'home_library' + ]; + foreach ($attribsToCheck as $attribute) { + if (isset($shib->$attribute)) { + $value = $request->getServer()->get($shib->$attribute); + if ($attribute != 'cat_password') { + $user->$attribute = $value; + } else { + $catPassword = $value; + } + } + } + + // Save credentials if applicable: + if (!empty($user->cat_username)) { + $user->saveCredentials($user->cat_username, $catPassword); + } + + // Save and return the user object: + $user->save(); + return $user; + } +} \ No newline at end of file diff --git a/module/finc/src/finc/ILS/Driver/FincILS.php b/module/finc/src/finc/ILS/Driver/FincILS.php index 2006e61ef59ff128bbfd61afbbd54175e2e19a15..2fa392fc19e77025ef6abecea625dc73aad19a22 100644 --- a/module/finc/src/finc/ILS/Driver/FincILS.php +++ b/module/finc/src/finc/ILS/Driver/FincILS.php @@ -41,6 +41,11 @@ use VuFind\Exception\ILS as ILSException, class FincILS extends PAIA implements LoggerAwareInterface { + private $_username; + private $_password; + private $_root_username; + private $_root_password; + /** * Array that stores the mapping of VuFind record_id to the ILS-specific * identifier retrieved by @_getILSRecordId() @@ -125,6 +130,14 @@ class FincILS extends PAIA implements LoggerAwareInterface $this->ilsIdentifier = $this->config['DAIA']['ilsIdentifier']; } + // get PAIA root credentials if configured + if (isset($this->config['PAIA']['root_username']) + && isset($this->config['PAIA']['root_username']) + ) { + $this->_root_username = $this->config['PAIA']['root_username']; + $this->_root_password = $this->config['PAIA']['root_password']; + } + // get ISIL from config if ILS-specific recordId is barcode for // interaction with ILS if (!isset($this->mainConfig['InstitutionInfo']['isil'])) { @@ -172,6 +185,92 @@ class FincILS extends PAIA implements LoggerAwareInterface ); } + /** + * Patron Login + * + * This is responsible for authenticating a patron against the catalog. + * + * @param string $username The patron's username + * @param string $password The patron's login password + * + * @return mixed Associative array of patron info on successful login, + * null on unsuccessful login. + * + * @throws ILSException + */ + public function patronLogin($username, $password) + { + if (!empty($this->_root_username) && !empty($this->_root_password)) { + if ($username == '') { + throw new ILSException('Invalid Login, Please try again.'); + } + $this->_username = $username; + $this->_password = $password; + + try { + return $this->paiaRootLogin($username, $password); + } catch (ILSException $e) { + throw new ILSException($e->getMessage()); + } + } else { + return parent::patronLogin($username, $password); + } + } + + /** + * Private authentication function - use PAIA root credentials for authentication + * + * @param string $username Username + * @param string $password Password + * + * @return mixed Associative array of patron info on successful login, + * null on unsuccessful login, PEAR_Error on error. + * @throws ILSException + */ + protected function paiaRootLogin($username, $password) + { + $post_data = [ + "username" => $this->_root_username, + "password" => $this->_root_password, + "grant_type" => "password", + "scope" => "read_patron read_fees read_items write_items change_password" + ]; + $responseJson = $this->paiaPostRequest('auth/login', $post_data); + + try { + $responseArray = $this->paiaParseJsonAsArray($responseJson); + } catch (ILSException $e) { + if ($e->getMessage() === 'access_denied') { + return null; + } + throw new ILSException( + $e->getCode() . ':' . $e->getMessage() + ); + } + + if (array_key_exists('access_token', $responseArray)) { + $_SESSION['paiaToken'] = $responseArray['access_token']; + if (array_key_exists('patron', $responseArray)) { + if ($responseArray['patron'] === 'root') { + $patron = $this->paiaGetUserDetails($username); + $patron['cat_username'] = $username; + $patron['cat_password'] = $password; + } else { + $patron = $this->paiaGetUserDetails($responseArray['patron']); + $patron['cat_username'] = $responseArray['patron']; + $patron['cat_password'] = $password; + } + return $patron; + } else { + throw new ILSException( + 'Login credentials accepted, but got no patron ID?!?' + ); + } + } else { + throw new ILSException('Unknown error! Access denied.'); + } + } + /** * Get the Record-Object from the RecordDriver. *