Project

General

Profile

Actions

Feature #95175

closed

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

Added by Dieter Porth about 3 years ago. Updated 5 months ago.

Status:
Rejected
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;
    }
}

Related issues 1 (0 open1 closed)

Related to TYPO3 Core - Feature #89983: Allow comma separated list of roles in f:security.ifHasRoleRejected2019-12-18

Actions
Actions #1

Updated by Benni Mack about 3 years ago

  • Target version changed from 11 LTS to Candidate for patchlevel
Actions #2

Updated by Georg Ringer 5 months ago

  • Related to Feature #89983: Allow comma separated list of roles in f:security.ifHasRole added
Actions #3

Updated by Georg Ringer 5 months ago

  • Status changed from New to Rejected

hey,

thanks for sharing your ideas and code! this really looks like this should be done in your controller. as such checks get quickly complex and are bound to heavily to your application/extension/needs I am closing this issue. Feel free to share your ideas with a small extensions!

Actions

Also available in: Atom PDF