diff --git a/config/vufind/permissions.ini b/config/vufind/permissions.ini index 9f555da90b0d667460ad9f6a7cdde15aed945be7..875772f156c78863484329be345d96cedddd91ca 100644 --- a/config/vufind/permissions.ini +++ b/config/vufind/permissions.ini @@ -35,6 +35,12 @@ ; with optional modifier ~ (match instead of string comparison, values ; are treated as regular expressions), ! (not) or !~ (no match). Only ; one of the values must match (OR). +; shibboleth - Same as serverParam with support for Shibboleth multi-valued +; attributes (values separated by semicolons). The IdP entityId can be +; referenced with idpentityid. Please note that only checking the IdP +; entityId is dangerous (no authorization, anybody with a valid login +; gets the permission) so this should always be combined with a second +; rule that checks an attribute. ; username - Grant the permission to logged-in users whose usernames match the ; specified value(s). Accepts a string or an array. ; @@ -66,4 +72,23 @@ permission = access.EITModule [default.StaffViewTab] role[] = guest role[] = loggedin -permission = access.StaffViewTab \ No newline at end of file +permission = access.StaffViewTab + +; Examples for Shibboleth +; +; Only users that have either common-lib-terms and entityid from idp1 or +; member and entityid from idp2 may have access to EITModule +;[shibboleth.EITModule1] +;shibboleth[] = "entityid https://testidp1.example.org/idp/shibboleth" +;shibboleth[] = "affiliation member@example.org" +;permission = access.EITModule +; +;[shibboleth.EITModule2] +;shibboleth[] = "entityid https://testidp2.example.org/idp/shibboleth" +;shibboleth[] = "entitlement urn:mace:dir:entitlement:common-lib-terms" +;permission = access.EITModule +; +; Only users with a staff affiliation can access the staff view tab +;[shibboleth.StaffView] +;shibboleth = "affiliation staff@example.org" +;permission = access.StaffViewTab \ No newline at end of file diff --git a/module/VuFind/config/module.config.php b/module/VuFind/config/module.config.php index 2a639ccad26186d0b2365edee6025664ca20bd9e..2e9a1598cd43598de060a2a3dd784aa6069aa83e 100644 --- a/module/VuFind/config/module.config.php +++ b/module/VuFind/config/module.config.php @@ -678,6 +678,7 @@ $config = [ 'ipRange' => 'VuFind\Role\PermissionProvider\Factory::getIpRange', 'ipRegEx' => 'VuFind\Role\PermissionProvider\Factory::getIpRegEx', 'serverParam' => 'VuFind\Role\PermissionProvider\Factory::getServerParam', + 'shibboleth' => 'VuFind\Role\PermissionProvider\Factory::getShibboleth', 'username' => 'VuFind\Role\PermissionProvider\Factory::getUsername', ], 'invokables' => [ diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php b/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php index f6944195a1a86740df06260453793b99a8d7ed75..f2f1ee84249e311c752a03e36f3413160ff0010d 100644 --- a/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/Factory.php @@ -77,6 +77,18 @@ class Factory return new ServerParam($sm->getServiceLocator()->get('Request')); } + /** + * Factory for Shibboleth + * + * @param ServiceManager $sm Service manager. + * + * @return Shibboleth + */ + public static function getShibboleth(ServiceManager $sm) + { + return new Shibboleth($sm->getServiceLocator()->get('Request')); + } + /** * Factory for Username * diff --git a/module/VuFind/src/VuFind/Role/PermissionProvider/Shibboleth.php b/module/VuFind/src/VuFind/Role/PermissionProvider/Shibboleth.php new file mode 100644 index 0000000000000000000000000000000000000000..171c5ee44de4c38daefce158e9f22fc7e21876c9 --- /dev/null +++ b/module/VuFind/src/VuFind/Role/PermissionProvider/Shibboleth.php @@ -0,0 +1,88 @@ +<?php +/** + * Shibboleth 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> + * @author Bernd Oberknapp <bo@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; +use VuFind\Role\PermissionProvider\ServerParam; + +/** + * Shibboleth permission provider for VuFind. + * + * @category VuFind2 + * @package Authorization + * @author Demian Katz <demian.katz@villanova.edu> + * @author Jochen Lienhard <lienhard@ub.uni-freiburg.de> + * @author Bernd Oberknapp <bo@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 Shibboleth extends ServerParam +{ + use \VuFind\Log\LoggerAwareTrait; + + /** + * Request object + * + * @var Request + */ + protected $request; + + /** + * Constructor + * + * @param Request $request Request object + */ + public function __construct(Request $request) + { + parent::__construct($request); + + $this->aliases = ['idpentityid' => 'Shib-Identity-Provider']; + $this->serverParamDelimiter = ';'; + $this->serverParamEscape = '\\'; + } + + /** + * 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 ($this->request->getServer()->get('Shib-Identity-Provider') === false) { + $this->logWarning('getPermissions: Shibboleth server params missing'); + + return []; + } + + return parent::getPermissions($options); + } +} diff --git a/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/ShibbolethTest.php b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/ShibbolethTest.php new file mode 100644 index 0000000000000000000000000000000000000000..86d752494c7d9a37edc8c3d1087234ac6b3b71de --- /dev/null +++ b/module/VuFind/tests/unit-tests/src/VuFindTest/Role/PermissionProvider/ShibbolethTest.php @@ -0,0 +1,103 @@ +<?php +/** + * PermissionProvider Shibboleth 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> + * @author Bernd Oberknapp <bo@ub.uni-freiburg.de> + * @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\Shibboleth; + +/** + * PermissionProvider Shibboleth Test Class + * + * @category VuFind2 + * @package Tests + * @author Demian Katz <demian.katz@villanova.edu> + * @author Bernd Oberknapp <bo@ub.uni-freiburg.de> + * @license http://opensource.org/licenses/gpl-2.0.php GNU General Public License + * @link http://vufind.org/wiki/vufind2:unit_tests Wiki + */ +class ShibbolethTest extends \VuFindTest\Unit\TestCase +{ + /** + * Test option alias idpentityid for Shib-Identity-Provider + * + * @return void + */ + public function testAliasIdpentityidTrue() + { + $this->checkShibboleth( + ['Shib-Identity-Provider' => 'https://example.org/shibboleth-idp'], + ['idpentityid https://example.org/shibboleth-idp'], + ['loggedin'] + ); + } + + /** + * Test multi-valued option with matching header + * + * @return void + */ + public function testMultivaluedOptionTrue() + { + $this->checkShibboleth( + ['affiliation' => 'student@example.org;member@example.org'], + ['affiliation member@example.org'], + ['loggedin'] + ); + } + + /** + * Test multi-valued option with matching no header + * + * @return void + */ + public function testMultivaluedOptionFalse() + { + $this->checkShibboleth( + ['affiliation' => 'student@example.org;member@example.org'], + ['affiliation staff@example.org'], + [] + ); + } + + /** + * Setup request and shibboleth objects, run getPermissions and check the result + * + * @param array $headers Request headers + * @param mixed $options options as from configuration + * @param array $expectedResult expected result returned by getPermissions + * + * @return void + */ + protected function checkShibboleth($headers, $options, $expectedResult) + { + $request = new \Zend\Http\PhpEnvironment\Request(); + $request->setServer(new \Zend\Stdlib\Parameters($headers)); + $shibboleth = new Shibboleth($request); + $result = $shibboleth->getPermissions($options); + $this->assertEquals($result, $expectedResult); + } +} \ No newline at end of file