diff --git a/config/application.config.php b/config/application.config.php index 49d744a6fb86eeebb7c0ae00de908daf1de54170..2efe44d7c654c251eeed4e4c8232a1ad8bb1f5fe 100644 --- a/config/application.config.php +++ b/config/application.config.php @@ -2,7 +2,7 @@ // Set up modules: $modules = array( - 'VuFindTheme', 'VuFindSearch', 'VuFind', 'VuFindAdmin' + 'ZfcRbac', 'VuFindTheme', 'VuFindSearch', 'VuFind', 'VuFindAdmin' ); if (PHP_SAPI == 'cli' && !defined('VUFIND_PHPUNIT_RUNNING')) { $modules[] = 'VuFindConsole'; diff --git a/config/vufind/EIT.ini b/config/vufind/EIT.ini index 7c8cc2f918a6c6d5db77fe631bbfaa1e392430fb..a7226ae04a9353de960cd9f7cfca4dfe2f930f01 100644 --- a/config/vufind/EIT.ini +++ b/config/vufind/EIT.ini @@ -10,10 +10,11 @@ ; that is not available via the EBSCOhost API - will cause EBSCO searches to fail ; entirely. ; -; Because of licensing restrictions, EBSCO results are only shown to users -; who have logged in to VuFind. Please be aware of any potential licensing issues -; that may arise if you allow users who are unaffiliated with your institution to -; create accounts in your VuFind instance. +; NOTE: Because of licensing restrictions, by default, EBSCO results are only shown +; to users who have logged in to VuFind. This behavior can be changed by adjusting +; permissions.ini. Please be aware of any potential licensing issues that may arise +; if you allow users who are unaffiliated with your institution to create accounts +; in your VuFind instance or if you reconfigure the default behavior. prof = prof.prof.prof pwd = password dbs = aph,reh,ehh,etc @@ -31,7 +32,6 @@ default_sort = relevance ; through the translator, so be sure to update language files if necessary. ; The order of these settings will be maintained in the drop-down list in the ; UI. - [Basic_Searches] TX = "All Fields" TI = Title diff --git a/config/vufind/Summon.ini b/config/vufind/Summon.ini index b2ae971d9ba1adfb2f5504616eb62cd2e4e7c008..df38e57522543412bab7e95807da207ab520f47b 100644 --- a/config/vufind/Summon.ini +++ b/config/vufind/Summon.ini @@ -1,3 +1,8 @@ +; IMPORTANT NOTE: By default, VuFind will not show any search results that +; require "authenticated" status for visibility. Please configure the +; access.SummonExtendedResults permission in permissions.ini to allow users to +; see these results. 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 @@ -243,16 +248,6 @@ enabled = true ; through the current result set from within the record view. next_prev_navigation = false -; Users will see more records if Summon is set to "authenticated" mode. It is -; up to you to determine how to identify authenticated users in compliance with -; your Summon contract. Authentication is disabled by default; you can turn on -; settings below to activate it based on various conditions. -[Auth] -; set to true to authenticate Summon based on user's login status within VuFind: -check_login = false -; set to a regular expression for matching valid IPs to activate IP whitelisting: -;ip_range = "/1\.2\.3\.[0-2]?[0-9]?[0-9]/" - ; This section defines the view options available on standard search results. ; If only one view is required, set default_view under [General] above, and ; leave this section commented out. diff --git a/config/vufind/config.ini b/config/vufind/config.ini index df7b68b0e3ab8deea8cd24498d61e5d5fb9c299c..e46c919095b332068d73c2374cd1f825f0bcdeaa 100644 --- a/config/vufind/config.ini +++ b/config/vufind/config.ini @@ -77,8 +77,8 @@ defaultRecordTab= Holdings hideHoldingsTabWhenEmpty = false ; This page will show by default when a user accesses the MyResearch module: defaultAccountPage = Favorites -; Allow access to the Admin module? (See [AdminAuth] below for more granular ways -; to restrict Admin access). +; Allow access to the Admin module? (See the access.AdminModule setting in +; permissions.ini for more granular ways to restrict Admin access). admin_enabled = false ; Show sidebar on the left side instead of right sidebarOnLeft = false @@ -445,7 +445,7 @@ database = mysql://root@localhost/vufind ;college = HTTP_COLLEGE ;major = HTTP_MAJOR ;home_library = HTTP_HOME_LIBRARY -; + ; CAS is optional. This section only needs to exist if the ; Authentication Method is set to CAS. ;[CAS] @@ -1042,19 +1042,6 @@ dewey = title [Security] HMACkey = mySuperSecretValue -; This section restricts access to the Admin module of VuFind. -;[AdminAuth] -; This setting can be used to restrict the Admin module to IP addresses matching a -; regular expression; leave it commented out to allow all IP addresses. When -; generating regular expressions, remember that the "." character is a wildcard; -; you have to use "\." to represent an actual dot! -;ipRegEx = "/1\.2\.3\.4|1\.2\.3\.5/" -; This setting can be used to restrict the Admin module to a particular set of users. -; The userWhitelist[] setting can be repeated as many times as necessary. If it is -; commented out, login will not be required to access the Admin module. -;userWhitelist[] = username1 -;userWhitelist[] = username2 - ; This section sets global defaults for caches; file caching is used by default. ;[Cache] ; Set time to live value for Zend caches (in seconds), 0 means maximum possible. diff --git a/config/vufind/permissions.ini b/config/vufind/permissions.ini new file mode 100644 index 0000000000000000000000000000000000000000..734f88ee6f21ae18890d2b5f2801254086300850 --- /dev/null +++ b/config/vufind/permissions.ini @@ -0,0 +1,55 @@ +; This file controls how permissions are assigned to roles within VuFind. +; +; Each section of the file contains a group of rules that grant permissions. The name +; of the section is unimportant as long as each section has a unique name. This +; section contains several keys: +; +; require - Set to 'ALL' to require all conditions in the section to be met in +; order to grant the permission(s). Set to 'ANY' to allow any one or +; more of the conditions to grant the permission(s). Defaults to 'ALL' +; if unset. Note that this rule is used for combining the output of +; permission provider services. When a single permission provider +; accepts multiple lines of configuration, the way those lines are +; combined may vary from provider to provider (see below). +; permission - The name(s) of the permission(s) to grant. May be a single string or +; an array of strings. +; +; Any other keys in the section should be the names of permission provider services. +; The values associated with these keys will be passed along to the services. +; You can define your own permission providers, or use some of the following: +; +; ipRange - Grant the permission to the single IP adresse or to the range. +; Accepts a single IP adresse or a range with a minus character without +; blanks as seperator. +; ipRegEx - Grant the permission to IP addresses matching the provided regular +; expression(s). Accepts a string or an array; if an array is passed, +; permission will be granted if ANY one of the expressions matches. +; role - Grant the permission automatically to the role or roles specified +; (accepts a string or an array). Note that VuFind uses 'guest' for +; logged-out users and 'loggedin' for all logged-in users. You may +; define additional roles with custom code. +; username - Grant the permission to logged-in users whose usernames match the +; specified value(s). Accepts a string or an array. +; +; Example configuration (grants the "sample.permission" permission to users named +; admin1 or admin2, or anyone coming from the IP addresses 1.2.3.4 or 1.2.3.5): +; +; [sample.rules] +; require = ANY +; username[] = admin1 +; username[] = admin2 +; ipRegEx = "/1\.2\.3\.4|1\.2\.3\.5/" +; ipRange[] = "1.2.3.4" +; ipRange[] = "1.2.3.7-1.2.5.254" +; permission = sample.permission +; +; List of permissions that you may wish to configure: +; +; access.AdminModule - Controls access to the admin panel (if enabled in config.ini) +; access.EITModule - Controls access to the EBSCO EIT module (if active) +; access.SummonExtendedResults - Controls visibility of protected Summon results + +; Default configuration for the EIT module; see EIT.ini for some notes on this. +[default.EITModule] +role = loggedin +permission = access.EITModule \ No newline at end of file diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 6a6e4e7147b17d00e3fa29dd6fc501fdc2631ba9..e39d27a8de70f74c3ff7297f0471fdb9a33f66bb 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -104,6 +104,9 @@ $config = array( 'worldcat' => 'VuFind\Controller\WorldcatController', 'worldcatrecord' => 'VuFind\Controller\WorldcatrecordController', ), + 'initializers' => array( + 'ZfcRbac\Initializer\AuthorizationServiceInitializer' + ), ), 'controller_plugins' => array( 'factories' => array( @@ -652,6 +655,31 @@ $config = array( ), ), ), + // Authorization configuration: + 'zfc_rbac' => array( + 'identity_provider' => 'VuFind\AuthManager', + 'guest_role' => 'guest', + 'role_provider' => array( + 'VuFind\Role\DynamicRoleProvider' => array( + 'map_legacy_settings' => true, + ), + ), + 'role_provider_manager' => array( + 'factories' => array( + 'VuFind\Role\DynamicRoleProvider' => 'VuFind\Role\DynamicRoleProviderFactory', + ), + ), + 'vufind_permission_provider_manager' => array( + 'factories' => array( + 'ipRange' => 'VuFind\Role\PermissionProvider\Factory::getIpRange', + 'ipRegEx' => 'VuFind\Role\PermissionProvider\Factory::getIpRegEx', + 'username' => 'VuFind\Role\PermissionProvider\Factory::getUsername', + ), + 'invokables' => array( + 'role' => 'VuFind\Role\PermissionProvider\Role', + ), + ), + ), ); // Define record view routes -- route name => controller diff --git a/module/VuFind/src/VuFind/Auth/Manager.php b/module/VuFind/src/VuFind/Auth/Manager.php index f0382c8e3d1eff438f38419465bf238f9ae8ea58..44eb99e55e43dc2b7e2712d062e61767ee824f9b 100644 --- a/module/VuFind/src/VuFind/Auth/Manager.php +++ b/module/VuFind/src/VuFind/Auth/Manager.php @@ -39,7 +39,7 @@ use VuFind\Db\Row\User as UserRow, VuFind\Db\Table\User as UserTable, * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link http://www.vufind.org Main Page */ -class Manager +class Manager implements \ZfcRbac\Identity\IdentityProviderInterface { /** * Authentication modules @@ -391,6 +391,16 @@ class Manager return $this->currentUser; } + /** + * Get the identity + * + * @return \ZfcRbac\Identity\IdentityInterface|null + */ + public function getIdentity() + { + return ($user = $this->isLoggedIn()) ?: null; + } + /** * Resets the session if the logged in user's credentials have expired. * diff --git a/module/VuFind/src/VuFind/Config/Upgrade.php b/module/VuFind/src/VuFind/Config/Upgrade.php index 77187d31435438d0de745ed85abfbfc273f1bf4c..0f40db360334e96e60bbd4c4dca98c9a39af7b09 100644 --- a/module/VuFind/src/VuFind/Config/Upgrade.php +++ b/module/VuFind/src/VuFind/Config/Upgrade.php @@ -110,6 +110,13 @@ class Upgrade */ protected $inPlaceUpgrade; + /** + * Have we modified permissions.ini? + * + * @var bool + */ + protected $permissionsModified = false; + /** * Constructor * @@ -154,6 +161,10 @@ class Upgrade $this->upgradeSummon(); $this->upgradeWorldCat(); + // The previous upgrade routines may have added values to permissions.ini, + // so we should save it last. It doesn't have its own upgrade routine. + $this->saveModifiedConfig('permissions.ini'); + // The following routines load special configurations that were not // explicitly loaded by loadConfigs: if ($this->from < 2) { // some pieces only apply to 1.x upgrade! @@ -280,7 +291,8 @@ class Upgrade // first so that getOldConfigPath can work properly! $configs = array( 'config.ini', 'authority.ini', 'facets.ini', 'reserves.ini', - 'searches.ini', 'Summon.ini', 'WorldCat.ini', 'sms.ini' + 'searches.ini', 'Summon.ini', 'WorldCat.ini', 'sms.ini', + 'permissions.ini' ); foreach ($configs as $config) { // Special case for config.ini, since we may need to overlay extra @@ -343,7 +355,11 @@ class Upgrade // If we're doing an in-place upgrade, and the source file is empty, // there is no point in upgrading anything (the file doesn't exist). if (empty($this->oldConfigs[$filename]) && $this->inPlaceUpgrade) { - return; + // Special case: if we set up custom permissions, we need to + // write the file even if it didn't previously exist. + if (!$this->permissionsModified || $filename !== 'permissions.ini') { + return; + } } // If target file already exists, back it up: @@ -611,6 +627,9 @@ class Upgrade unset($newConfig['Syndetics']['url']); } + // Translate obsolete permission settings: + $this->upgradeAdminPermissions(); + // Deal with shard settings (which may have to be moved to another file): $this->upgradeShardSettings(); @@ -618,6 +637,39 @@ class Upgrade $this->saveModifiedConfig('config.ini'); } + /** + * Translate obsolete permission settings. + * + * @return void + */ + protected function upgradeAdminPermissions() + { + $config = & $this->newConfigs['config.ini']; + $permissions = & $this->newConfigs['permissions.ini']; + + if (isset($config['AdminAuth'])) { + $permissions['access.AdminModule'] = []; + if (isset($config['AdminAuth']['ipRegEx'])) { + $permissions['access.AdminModule']['ipRegEx'] + = $config['AdminAuth']['ipRegEx']; + } + if (isset($config['AdminAuth']['userWhitelist'])) { + $permissions['access.AdminModule']['username'] + = $config['AdminAuth']['userWhitelist']; + } + // If no settings exist in config.ini, we grant access to everyone + // by allowing both logged-in and logged-out roles. + if (empty($permissions['access.AdminModule'])) { + $permissions['access.AdminModule']['role'] = ['guest', 'loggedin']; + } + $permissions['access.AdminModule']['permission'] = 'access.AdminModule'; + $this->permissionsModified = true; + + // Remove any old settings remaining in config.ini: + unset($config['AdminAuth']); + } + } + /** * Upgrade facets.ini. * @@ -856,12 +908,49 @@ class Upgrade } } + // update permission settings + $this->upgradeSummonPermissions(); + $this->upgradeSpellingSettings('Summon.ini'); // save the file $this->saveModifiedConfig('Summon.ini'); } + /** + * Translate obsolete permission settings. + * + * @return void + */ + protected function upgradeSummonPermissions() + { + $config = & $this->newConfigs['Summon.ini']; + $permissions = & $this->newConfigs['permissions.ini']; + if (isset($config['Auth'])) { + $permissions['access.SummonExtendedResults'] = []; + if (isset($config['Auth']['check_login']) + && $config['Auth']['check_login'] + ) { + $permissions['access.SummonExtendedResults']['role'] = ['loggedin']; + } + if (isset($config['Auth']['ip_range'])) { + $permissions['access.SummonExtendedResults']['ipRegEx'] + = $config['Auth']['ip_range']; + } + if (!empty($permissions['access.SummonExtendedResults'])) { + $permissions['access.SummonExtendedResults']['boolean'] = 'OR'; + $permissions['access.SummonExtendedResults']['permission'] + = 'access.SummonExtendedResults'; + $this->permissionsModified = true; + } else { + unset($permissions['access.SummonExtendedResults']); + } + + // Remove any old settings remaining in config.ini: + unset($config['Auth']); + } + } + /** * Upgrade WorldCat.ini. * diff --git a/module/VuFind/src/VuFind/Controller/AbstractBase.php b/module/VuFind/src/VuFind/Controller/AbstractBase.php index 3a5ea10e4222ddd2bd0ef0e3aac3027d06130bdf..2b163bfd200c48099f87e82ab5e921eeaa8fdafe 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractBase.php +++ b/module/VuFind/src/VuFind/Controller/AbstractBase.php @@ -27,7 +27,13 @@ * @link http://vufind.org/wiki/vufind2:building_a_controller Wiki */ namespace VuFind\Controller; -use Zend\Mvc\Controller\AbstractActionController, Zend\View\Model\ViewModel; + +use VuFind\Exception\Forbidden as ForbiddenException, + Zend\Mvc\Controller\AbstractActionController, + Zend\Mvc\MvcEvent, + Zend\View\Model\ViewModel, + ZfcRbac\Service\AuthorizationServiceAwareInterface, + ZfcRbac\Service\AuthorizationServiceAwareTrait; /** * VuFind controller base class (defines some methods that can be shared by other @@ -41,7 +47,54 @@ use Zend\Mvc\Controller\AbstractActionController, Zend\View\Model\ViewModel; * @SuppressWarnings(PHPMD.NumberOfChildren) */ class AbstractBase extends AbstractActionController + implements AuthorizationServiceAwareInterface { + use AuthorizationServiceAwareTrait; + + /** + * Permission that must be granted to access this module (false for no + * restriction) + * + * @var string|bool + */ + protected $accessPermission = false; + + /** + * preDispatch -- block access when appropriate. + * + * @param MvcEvent $e Event object + * + * @return void + */ + public function preDispatch(MvcEvent $e) + { + // Make sure the current user has permission to access the module: + if ($this->accessPermission + && !$this->getAuthorizationService()->isGranted($this->accessPermission) + ) { + if (!$this->getUser()) { + $e->setResponse($this->forceLogin(null, array(), false)); + return; + } + throw new ForbiddenException('Access denied.'); + } + } + + /** + * Register the default events for this controller + * + * @return void + */ + protected function attachDefaultListeners() + { + parent::attachDefaultListeners(); + // Attach preDispatch event if we need to check permissions. + if ($this->accessPermission) { + $events = $this->getEventManager(); + $events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 1000); + } + } + /** * Constructor */ diff --git a/module/VuFind/src/VuFind/Controller/EITController.php b/module/VuFind/src/VuFind/Controller/EITController.php index 0f28bc22eb461a7083602c72470ad40045e6769d..25c63320187c3c2c770a4b9a0d818815badf7967 100644 --- a/module/VuFind/src/VuFind/Controller/EITController.php +++ b/module/VuFind/src/VuFind/Controller/EITController.php @@ -43,6 +43,7 @@ class EITController extends AbstractSearch */ public function __construct() { + $this->accessPermission = 'access.EITModule'; $this->searchClassId = 'EIT'; parent::__construct(); } @@ -77,14 +78,6 @@ class EITController extends AbstractSearch */ public function searchAction() { - // We currently restrict EIT to logged in users. - // TODO: make this configurable, similar to what is found in - // \VuFind\Search\Factory\SummonBackendFactory::isAuthed(). - $account = $this->getAuthManager(); - if ($account->isLoggedIn() == false) { - return $this->forceLogin(); - } return $this->resultsAction(); } -} - +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Controller/EITrecordController.php b/module/VuFind/src/VuFind/Controller/EITrecordController.php index de2e0b7351b60471cef379299861606c99331226..49a82660b44ae7d92e5f140b503efc9b3222b048 100644 --- a/module/VuFind/src/VuFind/Controller/EITrecordController.php +++ b/module/VuFind/src/VuFind/Controller/EITrecordController.php @@ -49,6 +49,7 @@ class EITrecordController extends AbstractRecord public function __construct() { // Override some defaults: + $this->accessPermission = 'access.EITModule'; $this->searchClassId = 'EIT'; $this->defaultTab = 'Description'; diff --git a/module/VuFind/src/VuFind/Db/Row/User.php b/module/VuFind/src/VuFind/Db/Row/User.php index 583f12f02a254733b091f07224132d3121e9f84f..f2f3d4dfbfb36b7a3b23e14a0ab1af3003ede929 100644 --- a/module/VuFind/src/VuFind/Db/Row/User.php +++ b/module/VuFind/src/VuFind/Db/Row/User.php @@ -42,7 +42,8 @@ use Zend\Db\Sql\Expression, * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link http://vufind.org Main Site */ -class User extends RowGateway implements \VuFind\Db\Table\DbTableAwareInterface +class User extends RowGateway implements \VuFind\Db\Table\DbTableAwareInterface, + \ZfcRbac\Identity\IdentityInterface { use \VuFind\Db\Table\DbTableAwareTrait; @@ -436,4 +437,14 @@ class User extends RowGateway implements \VuFind\Db\Table\DbTableAwareInterface ) . (time() % pow(10, 10)); return $this->save(); } + + /** + * Get the list of roles of this identity + * + * @return string[]|\Rbac\Role\RoleInterface[] + */ + public function getRoles() + { + return array('loggedin'); + } } diff --git a/module/VuFind/src/VuFind/Role/DynamicRoleProvider.php b/module/VuFind/src/VuFind/Role/DynamicRoleProvider.php new file mode 100644 index 0000000000000000000000000000000000000000..c7ad23371b04e1a5ac340e049179343577616667 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/DynamicRoleProvider.php @@ -0,0 +1,192 @@ +<?php +/** + * VuFind dynamic role provider. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @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 VuFind\Role; +use ZfcRbac\Role\RoleProviderInterface; +use Rbac\Role\Role; + +/** + * VuFind dynamic role provider. + * + * @category VuFind2 + * @package Authorization + * @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 DynamicRoleProvider implements RoleProviderInterface +{ + /** + * Cache of role objects. + * + * @var array + */ + protected $roles = false; + + /** + * Permission provider manager + * + * @var PermissionProviderPluginManager + */ + protected $manager; + + /** + * Configuration for determining permissions. + * + * @var array + */ + protected $config; + + /** + * Constructor + * + * @param PermissionProvider\PluginManager $manager Permission provider manager + * @param array $config Configuration for determining + * permissions + */ + public function __construct(PermissionProvider\PluginManager $manager, + array $config + ) { + $this->manager = $manager; + $this->config = $config; + } + + /** + * Get the roles from the provider + * + * @param string[] $roleNames Role(s) to look up. + * + * @return \Rbac\Role\RoleInterface[] + */ + public function getRoles(array $roleNames) + { + return array_map(array($this, 'getRole'), $roleNames); + } + + /** + * Get a role object by name. + * + * @param string $name Role name + * + * @return Role + */ + protected function getRole($name) + { + // Retrieve permissions from providers if not already done: + if (false === $this->roles) { + $this->populateRoles(); + } + + // Create role object if missing: + if (!isset($this->roles[$name])) { + $this->roles[$name] = new Role($name); + } + + return $this->roles[$name]; + } + + /** + * Populate the internal role array. + * + * @return void + */ + protected function populateRoles() + { + // Reset internal role array: + $this->roles = array(); + + // Map permission configuration to the expected output format. + foreach ($this->getPermissionsArray() as $roleName => $permissionArr) { + $role = $this->getRole($roleName); + foreach ($permissionArr as $permission) { + $role->addPermission($permission); + } + } + } + + /** + * Get an associative array of role name => permissions using the provided + * configuration. + * + * @return array + */ + protected function getPermissionsArray() + { + // Loop through all of the permissions: + $retVal = []; + foreach ($this->config as $settings) { + $current = $this->getRolesForSettings($settings); + foreach ($current['roles'] as $role) { + if (!isset($retVal[$role])) { + $retVal[$role] = []; + } + foreach ($current['permissions'] as $permission) { + $retVal[$role][] = $permission; + } + } + } + return $retVal; + } + + /** + * Given a settings array, return the appropriate roles. + * + * @param array $settings Settings for finding roles that allow a permission + * + * @return array + */ + protected function getRolesForSettings($settings) + { + // Extract require setting: + if (isset($settings['require'])) { + $mode = strtoupper(trim($settings['require'])); + unset($settings['require']); + } else { + $mode = 'ALL'; + } + + // Extract permission setting: + $permissions = isset($settings['permission']) + ? (array)$settings['permission'] : []; + unset($settings['permission']); + + // Process everything: + $roles = null; + foreach ($settings as $provider => $options) { + $providerObj = $this->manager->get($provider); + $currentRoles = $providerObj->getPermissions($options); + if ($roles === null) { + $roles = $currentRoles; + } else if ($mode == 'ANY') { + $roles = array_merge($roles, $currentRoles); + } else { + $roles = array_intersect($roles, $currentRoles); + } + } + return compact('permissions', 'roles'); + } +} diff --git a/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php b/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php new file mode 100644 index 0000000000000000000000000000000000000000..623880becc0e9f97256b798b919c6cd7ce9442f8 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/DynamicRoleProviderFactory.php @@ -0,0 +1,191 @@ +<?php +/** + * VuFind dynamic role provider factory. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @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 VuFind\Role; +use Zend\ServiceManager\Config; +use Zend\ServiceManager\FactoryInterface; +use Zend\ServiceManager\ServiceLocatorInterface; + +/** + * VuFind dynamic role provider factory. + * + * @category VuFind2 + * @package Authorization + * @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 DynamicRoleProviderFactory implements FactoryInterface +{ + /** + * Create the service. + * + * @param ServiceLocatorInterface $serviceLocator Service locator + * + * @return DynamicRoleProvider + */ + public function createService(ServiceLocatorInterface $serviceLocator) + { + $config = $serviceLocator->getServiceLocator()->get('config'); + $rbacConfig = $config['zfc_rbac']; + return new DynamicRoleProvider( + $this->getPermissionProviderPluginManager($serviceLocator, $rbacConfig), + $this->getPermissionConfiguration($serviceLocator, $rbacConfig) + ); + } + + /** + * Create the supporting plugin manager. + * + * @param ServiceLocatorInterface $serviceLocator Service locator + * @param array $rbacConfig ZfcRbac configuration + * + * @return PermissionProviderPluginManager + */ + protected function getPermissionProviderPluginManager( + ServiceLocatorInterface $serviceLocator, array $rbacConfig + ) { + $pm = new PermissionProvider\PluginManager( + new Config($rbacConfig['vufind_permission_provider_manager']) + ); + $pm->setServiceLocator($serviceLocator->getServiceLocator()); + return $pm; + } + + /** + * Get a configuration array. + * + * @param ServiceLocatorInterface $serviceLocator Service locator + * @param array $rbacConfig ZfcRbac configuration + * + * @return array + */ + protected function getPermissionConfiguration( + ServiceLocatorInterface $serviceLocator, array $rbacConfig + ) { + // Get role provider settings from the ZfcRbac configuration: + $config = $rbacConfig['role_provider']['VuFind\Role\DynamicRoleProvider']; + + // Load the permissions: + $configLoader = $serviceLocator->getServiceLocator()->get('VuFind\Config'); + $permissions = $configLoader->get('permissions')->toArray(); + + // If we're configured to map legacy settings, do so now: + if (isset($config['map_legacy_settings']) + && $config['map_legacy_settings'] + ) { + $permissions = $this->addLegacySettings($configLoader, $permissions); + } + + return $permissions; + } + + /** + * Map legacy VuFind settings into the permissions.ini setup. + * + * @param \VuFind\Config\PluginManager $loader Config loader + * @param array $permissions Permissions to update + * + * @return array + */ + protected function addLegacySettings(\VuFind\Config\PluginManager $loader, + array $permissions + ) { + // Add admin settings if they are absent: + if (!$this->permissionDefined($permissions, 'access.AdminModule')) { + $config = $loader->get('config')->toArray(); + $permissions['legacy.AdminModule'] = []; + if (isset($config['AdminAuth']['ipRegEx'])) { + $permissions['legacy.AdminModule']['ipRegEx'] + = $config['AdminAuth']['ipRegEx']; + } + if (isset($config['AdminAuth']['userWhitelist'])) { + $permissions['legacy.AdminModule']['username'] + = $config['AdminAuth']['userWhitelist']; + } + // If no settings exist in config.ini, we grant access to everyone + // by allowing both logged-in and logged-out roles. + if (empty($permissions['legacy.AdminModule'])) { + $permissions['legacy.AdminModule']['role'] = ['guest', 'loggedin']; + } + $permissions['legacy.AdminModule']['permission'] = 'access.AdminModule'; + } + + // Add EIT settings if they are absent: + if (!$this->permissionDefined($permissions, 'access.EITModule')) { + $permissions['legacy.EITModule'] = [ + 'role' => 'loggedin', + 'permission' => 'access.EITModule', + ]; + } + + // Add Summon settings if they are absent: + // Check based on login status + $defined = $this + ->permissionDefined($permissions, 'access.SummonExtendedResults'); + if (!$defined) { + $config = $loader->get('Summon'); + $permissions['legacy.SummonExtendedResults'] = []; + if (isset($config->Auth->check_login) && $config->Auth->check_login) { + $permissions['legacy.SummonExtendedResults']['role'] = ['loggedin']; + } + if (isset($config->Auth->ip_range)) { + $permissions['legacy.SummonExtendedResults']['ipRegEx'] + = $config->Auth->ip_range; + } + if (!empty($permissions['legacy.SummonExtendedResults'])) { + $permissions['legacy.SummonExtendedResults']['boolean'] = 'OR'; + $permissions['legacy.SummonExtendedResults']['permission'] + = 'access.SummonExtendedResults'; + } else { + unset($permissions['legacy.SummonExtendedResults']); + } + } + + return $permissions; + } + + /** + * Is the specified permission already defined in the provided configuration? + * + * @param array $config Configuration + * @param string $permission Permission to check + * + * @return bool + */ + protected function permissionDefined(array $config, $permission) + { + foreach ($config as $current) { + if (isset($current['permission']) + && in_array($permission, (array)$current['permission']) + ) { + return true; + } + } + return false; + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php b/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php new file mode 100644 index 0000000000000000000000000000000000000000..87a1af81e60650f4b0df3d949f25dc3a441034a1 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php @@ -0,0 +1,80 @@ +<?php +/** + * Permission Provider Factory Class + * + * 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 Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:hierarchy_components Wiki + */ +namespace VuFind\Role\PermissionProvider; +use Zend\ServiceManager\ServiceManager; + +/** + * Permission Provider Factory Class + * + * @category VuFind2 + * @package Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:hierarchy_components Wiki + * @codeCoverageIgnore + */ +class Factory +{ + /** + * Factory for IpRange + * + * @param ServiceManager $sm Service manager. + * + * @return IpRange + */ + public static function getIpRange(ServiceManager $sm) + { + return new IpRange($sm->getServiceLocator()->get('Request')); + } + + /** + * Factory for IpRegEx + * + * @param ServiceManager $sm Service manager. + * + * @return IpRegEx + */ + public static function getIpRegEx(ServiceManager $sm) + { + return new IpRegEx($sm->getServiceLocator()->get('Request')); + } + + /** + * Factory for Username + * + * @param ServiceManager $sm Service manager. + * + * @return Username + */ + public static function getUsername(ServiceManager $sm) + { + return new Username( + $sm->getServiceLocator()->get('ZfcRbac\Service\AuthorizationService') + ); + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/IpRange.php b/module/VuFind/src/VuFind/Role/PermissionProvider/IpRange.php new file mode 100644 index 0000000000000000000000000000000000000000..e4d081959b7c78ac0c1afaa6ac71ae24c9dfceab --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/IpRange.php @@ -0,0 +1,113 @@ +<?php +/** + * IpRange permission provider for VuFind. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @author Jochen Lienhard <lienhard@ub.uni-freiburg.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://www.vufind.org Main Page + */ +namespace VuFind\Role\PermissionProvider; +use Zend\Http\PhpEnvironment\Request; + +/** + * IpRange permission provider for VuFind. + * + * @category VuFind2 + * @package Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @author Jochen Lienhard <lienhard@ub.uni-freiburg.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://www.vufind.org Main Page + */ +class IpRange implements PermissionProviderInterface +{ + /** + * Request object + * + * @var Request + */ + protected $request; + + /** + * Constructor + * + * @param Request $request Request object + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options provided from configuration. + * + * @return array + */ + public function getPermissions($options) + { + // Check if any regex matches.... + $ip = $this->request->getServer()->get('REMOTE_ADDR'); + if (checkIP($ip, $options)) { + // Match? Grant to all users (guest or logged in). + return ['guest', 'loggedin']; + } + + // No match? No permissions. + return []; + } + + /** + * Return true or false + * + * @param ip adress $remoteIP ip adress of the user + * @param array $rangeIP ip and ranges of adresses + * + * @return boolean + */ + // ToDo: Implementin IPv6 check + private function checkIP($remoteIP, $rangeIP) { + $mylist = array(); + $count = 0; + $inList = false; + foreach ((array)$rangeIP as $range) { + if (preg_match('/-/',$range)) { + $tmp=preg_split('/-/',$range); + $mylist[$count]["start"]=$tmp[0]; + $mylist[$count]["end"]=$tmp[1]; + } else { + $mylist[$count]["start"]=$range; + $mylist[$count]["end"]=$range; + } + $count++; + } + foreach ($mylist as $check) { + if (ip2long($remoteIP) >= ip2long($check["start"]) && ip2long($remoteIP) <= ip2long($check["end"])) { + $inList=true; + } + } + return $inList; + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/IpRegEx.php b/module/VuFind/src/VuFind/Role/PermissionProvider/IpRegEx.php new file mode 100644 index 0000000000000000000000000000000000000000..a99c02fdaf8b1890c04ae84e9a175bb77d0ee819 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/IpRegEx.php @@ -0,0 +1,81 @@ +<?php +/** + * IpRegEx permission provider for VuFind. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @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 VuFind\Role\PermissionProvider; +use Zend\Http\PhpEnvironment\Request; + +/** + * IpRegEx permission provider for VuFind. + * + * @category VuFind2 + * @package Authorization + * @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 IpRegEx implements PermissionProviderInterface +{ + /** + * Request object + * + * @var Request + */ + protected $request; + + /** + * Constructor + * + * @param Request $request Request object + */ + public function __construct(Request $request) + { + $this->request = $request; + } + + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options provided from configuration. + * + * @return array + */ + public function getPermissions($options) + { + // Check if any regex matches.... + $ip = $this->request->getServer()->get('REMOTE_ADDR'); + foreach ((array)$options as $current) { + if (preg_match($current, $ip)) { + // Match? Grant to all users (guest or logged in). + return ['guest', 'loggedin']; + } + } + + // No match? No permissions. + return []; + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/PermissionProviderInterface.php b/module/VuFind/src/VuFind/Role/PermissionProvider/PermissionProviderInterface.php new file mode 100644 index 0000000000000000000000000000000000000000..25bea165376590644f6b800341210b0e646a32f8 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/PermissionProviderInterface.php @@ -0,0 +1,50 @@ +<?php +/** + * Permission provider interface + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * 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 Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:building_a_related_record_module Wiki + */ +namespace VuFind\Role\PermissionProvider; + +/** + * Permission provider interface + * + * @category VuFind2 + * @package Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:building_a_related_record_module Wiki + */ +interface PermissionProviderInterface +{ + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options provided from configuration. + * + * @return array + */ + public function getPermissions($options); +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php new file mode 100644 index 0000000000000000000000000000000000000000..a4230ca1d6946a05cf30dcb891e573ded0c255f4 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/PluginManager.php @@ -0,0 +1,51 @@ +<?php +/** + * Permission provider plugin manager + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * 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 Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:building_a_related_record_module Wiki + */ +namespace VuFind\Role\PermissionProvider; + +/** + * Permission provider plugin manager + * + * @category VuFind2 + * @package Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:building_a_related_record_module Wiki + */ +class PluginManager extends \VuFind\ServiceManager\AbstractPluginManager +{ + /** + * Return the name of the base class or interface that plug-ins must conform + * to. + * + * @return string + */ + protected function getExpectedInterface() + { + return 'VuFind\Role\PermissionProvider\PermissionProviderInterface'; + } +} \ No newline at end of file diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/Role.php b/module/VuFind/src/VuFind/Role/PermissionProvider/Role.php new file mode 100644 index 0000000000000000000000000000000000000000..d8dd1159971e668b01f35616bbf13f575c5d4bb0 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/Role.php @@ -0,0 +1,55 @@ +<?php +/** + * Role permission provider for VuFind. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @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 VuFind\Role\PermissionProvider; + +/** + * Role permission provider for VuFind. + * + * @category VuFind2 + * @package Authorization + * @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 Role implements PermissionProviderInterface +{ + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options provided from configuration. + * + * @return array + */ + public function getPermissions($options) + { + // We should be receiving a role string or an array of roles; we should + // simply normalize it to an array and send it back. + return (array)$options; + } +} diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/Username.php b/module/VuFind/src/VuFind/Role/PermissionProvider/Username.php new file mode 100644 index 0000000000000000000000000000000000000000..d78a91981f2caefa82367dc5fad52a6258a4467b --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/Username.php @@ -0,0 +1,79 @@ +<?php +/** + * Username permission provider for VuFind. + * + * PHP version 5 + * + * Copyright (C) Villanova University 2007. + * + * 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 Authorization + * @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 VuFind\Role\PermissionProvider; +use ZfcRbac\Service\AuthorizationService; + +/** + * Username permission provider for VuFind. + * + * @category VuFind2 + * @package Authorization + * @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 Username implements PermissionProviderInterface +{ + /** + * Authorization object + * + * @var AuthorizationService + */ + protected $auth; + + /** + * Constructor + * + * @param AuthorizationService $authorization Authorization service + */ + public function __construct(AuthorizationService $authorization) + { + $this->auth = $authorization; + } + + /** + * Return an array of roles which may be granted the permission based on + * the options. + * + * @param mixed $options Options provided from configuration. + * + * @return array + */ + public function getPermissions($options) + { + // If no user is logged in, or the user doesn't match the passed-in + // whitelist, we can't grant the permission to any roles. + $user = $this->auth->getIdentity(); + if (!$user || !in_array($user->username, (array)$options)) { + return []; + } + + // If we got this far, we can grant the permission to the loggedin role. + return ['loggedin']; + } +} diff --git a/module/VuFind/src/VuFind/Search/Factory/SummonBackendFactory.php b/module/VuFind/src/VuFind/Search/Factory/SummonBackendFactory.php index fcbf90ab66aafe09c5f52d9b827ced1b947fc325..b6e439e0b624f59731c26066535e94e4a89baf36 100644 --- a/module/VuFind/src/VuFind/Search/Factory/SummonBackendFactory.php +++ b/module/VuFind/src/VuFind/Search/Factory/SummonBackendFactory.php @@ -146,35 +146,8 @@ class SummonBackendFactory implements FactoryInterface */ protected function isAuthed() { - // Check based on login status - if (isset($this->summonConfig->Auth->check_login) - && $this->summonConfig->Auth->check_login - ) { - $authManager = $this->serviceLocator->get('VuFind\AuthManager'); - if ($authManager->isLoggedIn()) { - return true; - } - } - - // Check based on IP range - if (isset($this->summonConfig->Auth->ip_range)) { - $request = $this->serviceLocator->get('Request'); - $match = preg_match( - $this->summonConfig->Auth->ip_range, - $request->getServer()->get('REMOTE_ADDR') - ); - if ($match === false) { - throw new \Exception( - 'Bad regular expression in Summon.ini [Auth] ip_range setting.' - ); - } - if ($match) { - return true; - } - } - - // If we got this far, we're not authenticated. - return false; + return $this->serviceLocator->get('ZfcRbac\Service\AuthorizationService') + ->isGranted('access.SummonExtendedResults'); } /** diff --git a/module/VuFind/tests/fixtures/configs/permissions/Summon.ini b/module/VuFind/tests/fixtures/configs/permissions/Summon.ini new file mode 100644 index 0000000000000000000000000000000000000000..c869f53227a63483dcb5b04a060adae3bd03a9db --- /dev/null +++ b/module/VuFind/tests/fixtures/configs/permissions/Summon.ini @@ -0,0 +1,3 @@ +[Auth] +ip_range = "/1\.2\.3\.4|1\.2\.3\.5/" +check_login = true \ No newline at end of file diff --git a/module/VuFind/tests/fixtures/configs/permissions/config.ini b/module/VuFind/tests/fixtures/configs/permissions/config.ini new file mode 100644 index 0000000000000000000000000000000000000000..06718d6b570df235d7a8ccf7536c592657908ccc --- /dev/null +++ b/module/VuFind/tests/fixtures/configs/permissions/config.ini @@ -0,0 +1,7 @@ +[AdminAuth] +ipRegEx = "/1\.2\.3\.4|1\.2\.3\.5/" +userWhitelist[] = username1 +userWhitelist[] = username2 + +[Summon] +apiKey = fake \ No newline at end of file diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php index 2b3bf4fc01bff1ec6bb2ea005718f437a8761d80..87a86e2156f174a690434a1aba0c18b5e9a523b9 100644 --- a/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Config/UpgradeTest.php @@ -259,6 +259,42 @@ class UpgradeTest extends \VuFindTest\Unit\TestCase ); } + /** + * Test permission upgrade + * + * @return void + */ + public function testPermissionUpgrade() + { + $upgrader = $this->getUpgrader('permissions'); + $upgrader->run(); + $results = $upgrader->getNewConfigs(); + $this->assertFalse(isset($results['config.ini']['AdminAuth'])); + $this->assertFalse(isset($results['Summon.ini']['Auth'])); + $adminConfig = [ + 'ipRegEx' => '/1\.2\.3\.4|1\.2\.3\.5/', + 'username' => ['username1', 'username2'], + 'permission' => 'access.AdminModule' + ]; + $this->assertEquals( + $adminConfig, $results['permissions.ini']['access.AdminModule'] + ); + $summonConfig = [ + 'role' => ['loggedin'], + 'ipRegEx' => '/1\.2\.3\.4|1\.2\.3\.5/', + 'boolean' => 'OR', + 'permission' => 'access.SummonExtendedResults' + ]; + $this->assertEquals( + $summonConfig, + $results['permissions.ini']['access.SummonExtendedResults'] + ); + $eitConfig = ['role' => 'loggedin', 'permission' => 'access.EITModule']; + $this->assertEquals( + $eitConfig, $results['permissions.ini']['default.EITModule'] + ); + } + /** * Test Google-related warnings. * diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Role/DynamicRoleProviderTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/DynamicRoleProviderTest.php new file mode 100644 index 0000000000000000000000000000000000000000..bd295a51c355e9c6522b8283dd30b7b642136fff --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/DynamicRoleProviderTest.php @@ -0,0 +1,108 @@ +<?php +/** + * Dynamic Role Provider Test Class + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * 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 Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +namespace VuFindTest\Role; +use VuFind\Role\DynamicRoleProvider, VuFind\Role\PermissionProvider\PluginManager; + +/** + * Dynamic Role Provider Test Class + * + * @category VuFind2 + * @package Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +class DynamicRoleProviderTest extends \VuFindTest\Unit\TestCase +{ + /** + * Test that configurations get processed correctly + * + * @return void + */ + public function testConfiguration() + { + $config = [ + 'testRequireAny' => [ + 'require' => 'any', + 'a' => 'foo', + 'b' => 'bar', + 'permission' => 'perm1', + ], + 'testRequireAll' => [ + 'require' => 'all', + 'a' => 'foo', + 'b' => 'bar', + 'permission' => 'perm2', + ], + 'testAcceptArray' => [ + 'c' => [1, 2, 3], + 'permission' => 'perm3', + ], + ]; + $pm = $this->getFakePluginManager(); + $pm->get('a')->expects($this->any())->method('getPermissions')->with($this->equalTo('foo'))->will($this->returnValue([])); + $pm->get('b')->expects($this->any())->method('getPermissions')->with($this->equalTo('bar'))->will($this->returnValue(['role'])); + $pm->get('c')->expects($this->any())->method('getPermissions')->with($this->equalTo([1, 2, 3]))->will($this->returnValue(['role'])); + $result = $this->getDynamicRoleProvider($pm, $config)->getRoles(['role']); + $this->assertEquals(1, count($result)); + $this->assertEquals('role', $result[0]->getName()); + $this->assertTrue($result[0]->hasPermission('perm1')); + $this->assertFalse($result[0]->hasPermission('perm2')); + $this->assertTrue($result[0]->hasPermission('perm3')); + } + + /** + * Get the DynamicRoleProvider to test. + * + * @param PluginManager $pluginManager Permission provider plugin manager + * @param array $config Configuration + * + * @return DynamicRoleProvider + */ + protected function getDynamicRoleProvider($pluginManager = null, $config = []) + { + if (null === $pluginManager) { + $pluginManager = $this->getFakePluginManager(); + } + return new DynamicRoleProvider($pluginManager, $config); + } + + /** + * Get a plugin manager populated with fake services to test. + * + * @return PluginManager + */ + protected function getFakePluginManager() + { + $pm = new PluginManager(); + foreach (['a', 'b', 'c'] as $name) { + $pm->setService($name, $this->getMock('VuFind\Role\PermissionProvider\PermissionProviderInterface')); + } + return $pm; + } +} \ No newline at end of file diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php new file mode 100644 index 0000000000000000000000000000000000000000..7c5a2c16d64ea40aa5c64245b91dab37e5a46d60 --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/PluginManagerTest.php @@ -0,0 +1,65 @@ +<?php +/** + * PermissionProvider Plugin Manager Test Class + * + * PHP version 5 + * + * Copyright (C) Villanova University 2010. + * + * 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 Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +namespace VuFindTest\Role\PermissionProvider; +use VuFind\Role\PermissionProvider\PluginManager; + +/** + * PermissionProvider Plugin Manager Test Class + * + * @category VuFind2 + * @package Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +class PluginManagerTest extends \VuFindTest\Unit\TestCase +{ + /** + * Test results. + * + * @return void + */ + public function testShareByDefault() + { + $pm = new PluginManager(null); + $this->assertTrue($pm->shareByDefault()); + } + + /** + * Test expected interface. + * + * @return void + * @expectedException Zend\ServiceManager\Exception\RuntimeException + * @expectedExceptionMessage Plugin ArrayObject does not belong to VuFind\Role\PermissionProvider\PermissionProviderInterface + */ + public function testExpectedInterface() + { + $pm = new PluginManager(null); + $pm->validatePlugin(new \ArrayObject()); + } +} \ No newline at end of file diff --git a/module/VuFindAdmin/src/VuFindAdmin/Controller/AbstractAdmin.php b/module/VuFindAdmin/src/VuFindAdmin/Controller/AbstractAdmin.php index 3b5bdaeb72cb02daf645f328f9ac02b7f6508e41..d22a6274ecf6ef2785e80103237f66f5cfb11a89 100644 --- a/module/VuFindAdmin/src/VuFindAdmin/Controller/AbstractAdmin.php +++ b/module/VuFindAdmin/src/VuFindAdmin/Controller/AbstractAdmin.php @@ -26,9 +26,7 @@ * @link http://www.vufind.org Main Page */ namespace VuFindAdmin\Controller; -use VuFind\Exception\Forbidden as ForbiddenException, - Zend\Mvc\MvcEvent, - Zend\Stdlib\Parameters; +use Zend\Mvc\MvcEvent; /** * VuFind Admin Controller Base @@ -41,6 +39,15 @@ use VuFind\Exception\Forbidden as ForbiddenException, */ class AbstractAdmin extends \VuFind\Controller\AbstractBase { + /** + * Constructor + */ + public function __construct() + { + parent::__construct(); + $this->accessPermission = 'access.AdminModule'; + } + /** * preDispatch -- block access when appropriate. * @@ -69,49 +76,10 @@ class AbstractAdmin extends \VuFind\Controller\AbstractBase return $redirectPlugin->toRoute('admin/disabled'); } - // Block access by IP when IP checking is enabled: - if (isset($config->AdminAuth->ipRegEx)) { - $ipMatch = preg_match( - $config->AdminAuth->ipRegEx, - $this->getRequest()->getServer()->get('REMOTE_ADDR') - ); - if (!$ipMatch) { - throw new ForbiddenException('Access denied.'); - } - } - - // Block access by username when user whitelist is enabled: - if (isset($config->AdminAuth->userWhitelist)) { - $user = $this->getUser(); - if ($user == false) { - $e->setResponse($this->forceLogin(null, array(), false)); - return; - } - $matchFound = false; - foreach ($config->AdminAuth->userWhitelist as $check) { - if ($check == $user->username) { - $matchFound = true; - break; - } - } - if (!$matchFound) { - throw new ForbiddenException('Access denied.'); - } - } + // Call parent method to do permission checking: + parent::preDispatch($e); } - /** - * Register the default events for this controller - * - * @return void - */ - protected function attachDefaultListeners() - { - parent::attachDefaultListeners(); - $events = $this->getEventManager(); - $events->attach(MvcEvent::EVENT_DISPATCH, array($this, 'preDispatch'), 1000); - } - /** * Display disabled message. *