Feature #95175

security.ifByRoles-Viewhelper, which allows to check different groups and allowes mixed use of usergruop-IDs and -names

Added by Dieter Porth 3 months ago. Updated about 2 months ago.

Status:
New
Priority:
Should have
Assignee:
-
Category:
Fluid
Start date:
2021-09-10
Due date:
% Done:

0%

Estimated time:
PHP Version:
7.3
Tags:
Complexity:
Sprint Focus:

Description

Let the code speak.

The ifHasRole-Viewhelper is too limited.


namespace TYPO3\CMS\Fluid\ViewHelpers\Security;

/*
 * This file is part of the TYPO3 CMS project.
 *
 * It is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License, either version 2
 * of the License, or any later version.
 *
 * For the full copyright and license information, please read the
 * LICENSE.txt file that was distributed with this source code.
 *
 * The TYPO3 project - inspiring people to share!
 */

use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Context\UserAspect;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\ViewHelper\AbstractConditionViewHelper;

/*
 * This ViewHelper implements an ifHasRole/else condition for frontend groups.
 *
 * Examples
 * ========
 *
 * Basic usage
 * -----------
 *
 * ::
 *   normal-case
 *
 *    <f:security.switchByRoles roles=" Administrator, 5 " >
 *         <f:then> USER contain to at least one role. </f:then>
 *         <f:else> USER IS UNLOGGED or USER contain none of the usergroups. , The default-limiter is `,`.</f:else>
 *    </f:security.switchByRoles>
 * 
 *   
 *    anti-normal-case
 *
 *    <f:security.switchByRoles roles="Administrator;5" limiter=";" unlogged="true">
 *         <f:then> USER IS UNLOGGED or USER contain to at least one of the roles. The limiter is `;`. </f:then>
 *         <f:else> USER contain none of the usergroups</f:else>
 *    </f:security.switchByRoles>
 *
 *
 */
class IfByRolesViewHelper extends AbstractConditionViewHelper
{
    protected const BRANCH_THEN = true;
    protected const BRANCH_ELSE = false;
    protected const ATTR_ROLES = 'roles';
    protected const ATTR_LIMITER = 'limiter';
    protected const ATTR_UNLOGGED = 'unlogged';

    /** Initializes the "roles", ""limiter" and "unlogged"-flag as  argument.
     */
    public function initializeArguments()
    {
        parent::initializeArguments();
        $this->registerArgument(self::ATTR_ROLES, 'string', 'Whitespaces will be trimmed. A limiter(comma) separated list of usergroups, which are represented by name or id. If the user contain to one of the groups, the THEN-branch will shown.');
        $this->registerArgument(self::ATTR_LIMITER, 'string', 'The limiter for your list.', false, ',');
        $this->registerArgument(self::ATTR_UNLOGGED, 'boolean', 'If `false` is set, the ELSE-branch will shown to an unlogged user and the user defined by roles will view the THEN-branch.  If `true` is set, the THEN-branch will shown to an unlogged user and the THEN-branch will shown to user, which contain at least one of the roles. ', false, false);
    }

    /*
     * This method decides if the condition is TRUE or FALSE. It can be overridden in extending viewhelpers to adjust functionality.
     *
     * @param array $arguments ViewHelper arguments to evaluate the condition for this ViewHelper, allows for flexiblity in overriding this method.
     * @return bool
     */
    protected static function evaluateCondition($arguments = null)
    {
        /** @var UserAspect $userAspect */
        $userAspect = GeneralUtility::makeInstance(Context::class)->getAspect('frontend.user');
        $roles = $arguments[self::ATTR_ROLES];
        if ((!$userAspect->isLoggedIn()) ||
            (empty($roles))
        ) {
            return (empty($arguments[self::ATTR_ROLES]) ?
                self::BRANCH_ELSE :
                self::BRANCH_THEN
            );
        }
        $limiter = ($arguments[self::ATTR_LIMITER] ?? ',');
        $roleList = array_filter(
            array_map(
                'trim',
                explode($limiter, $roles)
            )
        );
        $groupIds = $userAspect->getGroupIds();
        $getGroupNames = $userAspect->getGroupNames();
        $groups = array_merge($groupIds, $getGroupNames);
        if (!empty(array_intersect($groups, $roleList))) {
            return self::BRANCH_THEN;
        }
        return self::BRANCH_ELSE;
    }
}

Also available in: Atom PDF