diff --git a/config/vufind/permissionBehavior.ini b/config/vufind/permissionBehavior.ini index 550838fb0c9fecda480485c6388b1e286a961c29..3390fd023d82bca3924145c1bd4b97e94b793366 100644 --- a/config/vufind/permissionBehavior.ini +++ b/config/vufind/permissionBehavior.ini @@ -66,6 +66,18 @@ defaultDeniedControllerBehavior = "promptLogin" ; (False means "use the default behavior defined by the template"). defaultDeniedTemplateBehavior = false +; This setting can be used to override access permissions for controllers. You can +; set a controller class name inside the brackets to explicitly override that +; controller's access permission (and that of any of its children, unless more +; specific permissions are set for those subclasses), whether or not it has a +; default defined in the class. You can use * inside the brackets to set a default +; access permission that is applied to all controllers that do not have an +; internally-defined default (the MyResearchController is also excluded from +; this setting to avoid infinite login redirects). This can be useful if you +; wish to password-protect your entire site. +;controllerAccess[*] = access.VuFindInterface +;controllerAccess[VuFind\Controller\SearchController] = access.SearchResults + ; Example configuration for non-standard favorites permission behavior: ;[feature.Favorites] ;deniedTemplateBehavior = "showMessage:Login for Favorites" diff --git a/module/VuFind/src/VuFind/Controller/AbstractBase.php b/module/VuFind/src/VuFind/Controller/AbstractBase.php index 69fdaf2c5c7f20ab3b8b32e6390db5410ece9aac..90e9961f4f173c2174b259b063776552f9b62379 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractBase.php +++ b/module/VuFind/src/VuFind/Controller/AbstractBase.php @@ -51,11 +51,12 @@ class AbstractBase extends AbstractActionController { /** * Permission that must be granted to access this module (false for no - * restriction) + * restriction, null to use configured default (which is usually the same + * as false)). * * @var string|bool */ - protected $accessPermission = false; + protected $accessPermission = null; /** * Behavior when access is denied (used unless overridden through @@ -105,6 +106,29 @@ class AbstractBase extends AbstractActionController } } + /** + * Getter for access permission. + * + * @return string|bool + */ + public function getAccessPermission() + { + return $this->accessPermission; + } + + /** + * Getter for access permission. + * + * @param string $ap Permission to require for access to the controller (false + * for no requirement) + * + * @return void + */ + public function setAccessPermission($ap) + { + $this->accessPermission = empty($ap) ? false : $ap; + } + /** * Register the default events for this controller * diff --git a/module/VuFind/src/VuFind/Controller/AbstractBaseFactory.php b/module/VuFind/src/VuFind/Controller/AbstractBaseFactory.php index 6f3d621cc8a42f64a02a5cc252718a906dde3aa6..f16c84b5708fd901823ff6aa1e924436333d894a 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractBaseFactory.php +++ b/module/VuFind/src/VuFind/Controller/AbstractBaseFactory.php @@ -41,6 +41,46 @@ use Zend\ServiceManager\Factory\FactoryInterface; */ class AbstractBaseFactory implements FactoryInterface { + /** + * Apply permission settings to the controller. + * + * @param ContainerInterface $container Service manager + * @param AbstractBase $controller Controller to configure + * + * @return AbstractBase + */ + protected function applyPermissions($container, $controller) + { + $config = $container->get(\VuFind\Config\PluginManager::class) + ->get('permissionBehavior'); + $permissions = $config->global->controllerAccess ?? []; + + if (!empty($permissions)) { + // Iterate through parent classes until we find the most specific + // class access permission defined (if any): + $class = get_class($controller); + do { + if (isset($permissions[$class])) { + $controller->setAccessPermission($permissions[$class]); + break; + } + $class = get_parent_class($class); + } while ($class); + + // If the controller's current permission is null (as opposed to false + // or a string), that means it has no internally configured default, and + // setAccessPermission was not called above; thus, we should apply the + // default value: + if (isset($permissions['*']) + && $controller->getAccessPermission() === null + ) { + $controller->setAccessPermission($permissions['*']); + } + } + + return $controller; + } + /** * Create an object * @@ -61,6 +101,6 @@ class AbstractBaseFactory implements FactoryInterface if (!empty($options)) { throw new \Exception('Unexpected options sent to factory.'); } - return new $requestedName($container); + return $this->applyPermissions($container, new $requestedName($container)); } } diff --git a/module/VuFind/src/VuFind/Controller/AbstractBaseWithConfigFactory.php b/module/VuFind/src/VuFind/Controller/AbstractBaseWithConfigFactory.php index b6a6f5c731f912daa49fa3dc1937c378156a34aa..f9efa5a7e22287a3147f7964093ea717cc06d1cf 100644 --- a/module/VuFind/src/VuFind/Controller/AbstractBaseWithConfigFactory.php +++ b/module/VuFind/src/VuFind/Controller/AbstractBaseWithConfigFactory.php @@ -28,7 +28,6 @@ namespace VuFind\Controller; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; /** * Generic controller factory (with config injection). @@ -39,7 +38,7 @@ use Zend\ServiceManager\Factory\FactoryInterface; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ -class AbstractBaseWithConfigFactory implements FactoryInterface +class AbstractBaseWithConfigFactory extends AbstractBaseFactory { /** * Create an object @@ -63,6 +62,8 @@ class AbstractBaseWithConfigFactory implements FactoryInterface } $config = $container->get(\VuFind\Config\PluginManager::class) ->get('config'); - return new $requestedName($container, $config); + return $this->applyPermissions( + $container, new $requestedName($container, $config) + ); } } diff --git a/module/VuFind/src/VuFind/Controller/CartControllerFactory.php b/module/VuFind/src/VuFind/Controller/CartControllerFactory.php index bb56f89a8b958f05151767a0f076a2bed9ace5de..5e5a908056d627b45eba6d87db6aeebbbd31e6cb 100644 --- a/module/VuFind/src/VuFind/Controller/CartControllerFactory.php +++ b/module/VuFind/src/VuFind/Controller/CartControllerFactory.php @@ -28,7 +28,6 @@ namespace VuFind\Controller; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; /** * Cart controller factory. @@ -39,7 +38,7 @@ use Zend\ServiceManager\Factory\FactoryInterface; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ -class CartControllerFactory implements FactoryInterface +class CartControllerFactory extends AbstractBaseFactory { /** * Create an object @@ -64,6 +63,9 @@ class CartControllerFactory implements FactoryInterface $session = new \Zend\Session\Container( 'cart_followup', $container->get(\Zend\Session\SessionManager::class) ); - return new $requestedName($container, $session); + return $this->applyPermissions( + $container, + new $requestedName($container, $session) + ); } } diff --git a/module/VuFind/src/VuFind/Controller/ChannelsControllerFactory.php b/module/VuFind/src/VuFind/Controller/ChannelsControllerFactory.php index d3ca628582eb65491f5da5918beeacdfe3d2a58d..28e3c9217069161a887681a45b7ca48a117f08ed 100644 --- a/module/VuFind/src/VuFind/Controller/ChannelsControllerFactory.php +++ b/module/VuFind/src/VuFind/Controller/ChannelsControllerFactory.php @@ -28,7 +28,6 @@ namespace VuFind\Controller; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; /** * Channels controller factory. @@ -39,7 +38,7 @@ use Zend\ServiceManager\Factory\FactoryInterface; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ -class ChannelsControllerFactory implements FactoryInterface +class ChannelsControllerFactory extends AbstractBaseFactory { /** * Create an object @@ -62,6 +61,6 @@ class ChannelsControllerFactory implements FactoryInterface throw new \Exception('Unexpected options sent to factory.'); } $loader = $container->get(\VuFind\ChannelProvider\ChannelLoader::class); - return new $requestedName($loader); + return $this->applyPermissions($container, new $requestedName($loader)); } } diff --git a/module/VuFind/src/VuFind/Controller/MyResearchController.php b/module/VuFind/src/VuFind/Controller/MyResearchController.php index 0c3dcad453da21776c0fd1ea4866c827a512228c..30d7d1e1f1823a890e0bae5cd9adeb7ccee54011 100644 --- a/module/VuFind/src/VuFind/Controller/MyResearchController.php +++ b/module/VuFind/src/VuFind/Controller/MyResearchController.php @@ -49,6 +49,19 @@ use Zend\View\Model\ViewModel; */ class MyResearchController extends AbstractBase { + /** + * Permission that must be granted to access this module (false for no + * restriction, null to use configured default (which is usually the same + * as false)). + * + * For this controller, we default to false rather than null because + * we don't want a default setting to override the controller's accessibility + * and break the login process! + * + * @var string|bool + */ + protected $accessPermission = false; + /** * ILS Pagination Helper * diff --git a/module/VuFind/src/VuFind/Controller/UpgradeControllerFactory.php b/module/VuFind/src/VuFind/Controller/UpgradeControllerFactory.php index 928b0daeb65aed7d28b26d40be2ecd6e11f3d71f..572b9d0c345211c57be4a982f50a3cfabe7ff521 100644 --- a/module/VuFind/src/VuFind/Controller/UpgradeControllerFactory.php +++ b/module/VuFind/src/VuFind/Controller/UpgradeControllerFactory.php @@ -28,7 +28,6 @@ namespace VuFind\Controller; use Interop\Container\ContainerInterface; -use Zend\ServiceManager\Factory\FactoryInterface; /** * Upgrade controller factory. @@ -39,7 +38,7 @@ use Zend\ServiceManager\Factory\FactoryInterface; * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License * @link https://vufind.org/wiki/development Wiki */ -class UpgradeControllerFactory implements FactoryInterface +class UpgradeControllerFactory extends AbstractBaseFactory { /** * Create an object @@ -65,6 +64,9 @@ class UpgradeControllerFactory implements FactoryInterface $session = new \Zend\Session\Container( 'upgrade', $container->get(\Zend\Session\SessionManager::class) ); - return new $requestedName($container, $cookieManager, $session); + return $this->applyPermissions( + $container, + new $requestedName($container, $cookieManager, $session) + ); } }