From a19d77ef97ded1cb198fac4522d2834a6f413513 Mon Sep 17 00:00:00 2001
From: Demian Katz <demian.katz@villanova.edu>
Date: Wed, 18 Nov 2015 09:23:23 -0500
Subject: [PATCH] Improved EDS permission handling.

---
 config/vufind/EDS.ini                         |  8 +++-
 config/vufind/permissions.ini                 |  7 ++++
 .../VuFind/Controller/EdsrecordController.php | 24 ++++--------
 .../Search/Factory/EdsBackendFactory.php      |  4 +-
 .../src/VuFindSearch/Backend/EDS/Backend.php  | 37 ++++++++++---------
 5 files changed, 44 insertions(+), 36 deletions(-)

diff --git a/config/vufind/EDS.ini b/config/vufind/EDS.ini
index 56404656056..8a8b35f5edc 100644
--- a/config/vufind/EDS.ini
+++ b/config/vufind/EDS.ini
@@ -1,3 +1,8 @@
+; IMPORTANT NOTE: By default, VuFind will block access to certain EDS content
+; unless it knows which users are authorized (by IP, etc.). Please configure the
+; access.EDSExtendedResults permission in permissions.ini to allow users to
+; see this content. You are responsible for complying with your license.
+
 ; This section contains global settings affecting search behavior.
 [General]
 ; This setting controls the default sort order of search results; the selected
@@ -184,8 +189,9 @@ next_prev_navigation = false
 ; If using IP Authentication, then the user_id and password should remain blank
 ; and ip_auth should be set to true.
 [EBSCO_Account]
+; IP authentication for the API
 ip_auth = false
 user_name = [USERNAME]
 password  = [PASSWORD]
 profile   = [PROFILE]
-organization_id =
\ No newline at end of file
+organization_id = "VuFind 2.x from MyUniversity"
diff --git a/config/vufind/permissions.ini b/config/vufind/permissions.ini
index d0950159d3e..44ed60c13ae 100644
--- a/config/vufind/permissions.ini
+++ b/config/vufind/permissions.ini
@@ -62,6 +62,7 @@
 ;
 ; access.AdminModule - Controls access to the admin panel (if enabled in config.ini)
 ; access.DebugMode - Allows ?debug=true GET parameter to turn on debug mode
+; access.EDSExtendedResults - Controls visibility of protected EDS results
 ; access.EITModule - Controls access to the EBSCO EIT module (if active)
 ; access.StaffViewTab - Controls access to the staff view tab in record mode
 ; access.SummonExtendedResults - Controls visibility of protected Summon results
@@ -82,6 +83,12 @@ permission = access.StaffViewTab
 ;username[] = admin
 ;permission = access.DebugMode
 
+; Example for EDS
+;[default.EDSModule]
+;ipRange[] = "127.0.0.1"
+;ipRange[] = "192.168.11"
+;permission = access.EDSExtendedResults
+
 ; Examples for Shibboleth
 ;
 ; Only users that have either common-lib-terms and entityid from idp1 or 
diff --git a/module/VuFind/src/VuFind/Controller/EdsrecordController.php b/module/VuFind/src/VuFind/Controller/EdsrecordController.php
index ec35238dc39..3095a5d06ea 100644
--- a/module/VuFind/src/VuFind/Controller/EdsrecordController.php
+++ b/module/VuFind/src/VuFind/Controller/EdsrecordController.php
@@ -26,6 +26,7 @@
  * @link     http://vufind.org   Main Site
  */
 namespace VuFind\Controller;
+use VuFind\Exception\Forbidden as ForbiddenException;
 
 /**
  * EDS Record Controller
@@ -60,11 +61,14 @@ class EdsrecordController extends AbstractRecord
     {
         $driver = $this->loadRecord();
         //if the user is a guest, redirect them to the login screen.
-        if (!$this->isAuthenticationIP() && false == $this->getUser()) {
-            return $this->forceLogin();
-        } else {
-            return $this->redirect()->toUrl($driver->getPdfLink());
+        $auth = $this->getAuthorizationService();
+        if (!$auth->isGranted('access.EDSExtendedResults')) {
+            if (!$this->getUser()) {
+                return $this->forceLogin();
+            }
+            throw new ForbiddenException('Access denied.');
         }
+        return $this->redirect()->toUrl($driver->getPdfLink());
     }
 
     /**
@@ -78,16 +82,4 @@ class EdsrecordController extends AbstractRecord
         return (isset($config->Record->next_prev_navigation)
             && $config->Record->next_prev_navigation);
     }
-
-     /**
-     * Is IP Authentication being used?
-     *
-     * @return bool
-     */
-    protected function isAuthenticationIP()
-    {
-        $config = $this->getServiceLocator()->get('VuFind\Config')->get('EDS');
-        return (isset($config->EBSCO_Account->ip_auth)
-            && 'true' ==  $config->EBSCO_Account->ip_auth);
-    }
 }
\ No newline at end of file
diff --git a/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
index 955cd455494..995e493ab62 100644
--- a/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
+++ b/module/VuFind/src/VuFind/Search/Factory/EdsBackendFactory.php
@@ -103,10 +103,12 @@ class EdsBackendFactory implements FactoryInterface
      */
     protected function createBackend(Connector $connector)
     {
+        $auth = $this->serviceLocator->get('ZfcRbac\Service\AuthorizationService');
+        $isGuest = !$auth->isGranted('access.EDSExtendedResults');
         $backend = new Backend(
             $connector, $this->createRecordCollectionFactory(),
             $this->serviceLocator->get('VuFind\CacheManager')->getCache('object'),
-            new \Zend\Session\Container('EBSCO'), $this->edsConfig
+            new \Zend\Session\Container('EBSCO'), $this->edsConfig, $isGuest
         );
         $backend->setAuthManager($this->serviceLocator->get('VuFind\AuthManager'));
         $backend->setLogger($this->logger);
diff --git a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Backend.php b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Backend.php
index 845a9e43133..85711249409 100644
--- a/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Backend.php
+++ b/module/VuFindSearch/src/VuFindSearch/Backend/EDS/Backend.php
@@ -27,6 +27,8 @@
  */
 namespace VuFindSearch\Backend\EDS;
 
+use Exception;
+
 use VuFindSearch\Backend\EDS\Zend2 as ApiClient;
 
 use VuFindSearch\Query\AbstractQuery;
@@ -132,6 +134,13 @@ class Backend extends AbstractBackend
      */
     protected $session;
 
+    /**
+     * Is the current user a guest?
+     *
+     * @var bool
+     */
+    protected $isGuest;
+
     /**
      * Constructor.
      *
@@ -140,16 +149,18 @@ class Backend extends AbstractBackend
      * @param CacheAdapter                     $cache   Object cache
      * @param SessionContainer                 $session Session container
      * @param Config                           $config  Object representing EDS.ini
+     * @param bool                             $isGuest Is the current user a guest?
      */
     public function __construct(ApiClient $client,
         RecordCollectionFactoryInterface $factory, CacheAdapter $cache,
-        SessionContainer $session, Config $config = null
+        SessionContainer $session, Config $config = null, $isGuest = true
     ) {
-        // Save dependencies:
+        // Save dependencies/incoming parameters:
         $this->client = $client;
         $this->setRecordCollectionFactory($factory);
         $this->cache = $cache;
         $this->session = $session;
+        $this->isGuest = $isGuest;
 
         // Extract key values from configuration:
         if (isset($config->EBSCO_Account->user_name)) {
@@ -297,7 +308,7 @@ class Backend extends AbstractBackend
                         $sessionToken = $this->getSessionToken(true);
                     }
                     $response = $this->client->retrieve(
-                        $an, $dbId,  $authenticationToken, $sessionToken, $hlTerms
+                        $an, $dbId, $authenticationToken, $sessionToken, $hlTerms
                     );
                 } catch(Exception $e) {
                     throw new BackendException($e->getMessage(), $e->getCode(), $e);
@@ -498,23 +509,13 @@ class Backend extends AbstractBackend
     }
 
     /**
-     * Determines whether or not the current user session is identifed as a guest
-     * session
+     * Is the current user a guest? If so, return 'y' else 'n'.
      *
-     * @return string 'y'|'n'
+     * @return string
      */
     protected function isGuest()
     {
-        // If the user is not logged in, then treat them as a guest. Unless they are
-        // using IP Authentication.
-        // If IP Authentication is used, then don't treat them as a guest.
-        if ($this->ipAuth) {
-            return 'n';
-        }
-        if (isset($this->authManager)) {
-            return $this->authManager->isLoggedIn() ? 'n' : 'y';
-        }
-        return 'y';
+        return $this->isGuest ? 'y' : 'n';
     }
 
     /**
@@ -531,7 +532,7 @@ class Backend extends AbstractBackend
     {
         try {
             $authToken = $this->getAuthenticationToken();
-            $results = $this->client->createSession($profile,  $isGuest, $authToken);
+            $results = $this->client->createSession($profile, $isGuest, $authToken);
         } catch(\EbscoEdsApiException $e) {
             $errorCode = $e->getApiErrorCode();
             $desc = $e->getApiErrorDescription();
@@ -543,7 +544,7 @@ class Backend extends AbstractBackend
                 try {
                     $authToken = $this->getAuthenticationToken(true);
                     $results = $this->client
-                        ->createSession($this->profile,  $isGuest, $authToken);
+                        ->createSession($this->profile, $isGuest, $authToken);
                 } catch(Exception $e) {
                     throw new BackendException(
                         $e->getMessage(),
-- 
GitLab