Initial commit

This commit is contained in:
2018-04-02 08:07:38 +02:00
commit 7330c1ed3e
2054 changed files with 405203 additions and 0 deletions

View File

@@ -0,0 +1,301 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Security;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Extbase\Domain\Model\FrontendUser;
use TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup;
use TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository;
use TYPO3\CMS\Extbase\Persistence\ObjectStorage;
use TYPO3\CMS\Fluid\Core\ViewHelper\AbstractConditionViewHelper;
/**
* ### Base class: Security ViewHelpers
*
* @author Claus Due <claus@namelesscoder.net>
* @package Vhs
* @subpackage ViewHelpers\Security
*/
abstract class AbstractSecurityViewHelper extends AbstractConditionViewHelper {
/**
* @var \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository
*/
protected $frontendUserRepository;
/**
* @return NULL
*/
public function render() {
return NULL;
}
/**
* @param \TYPO3\CMS\Extbase\Domain\Repository\FrontendUserRepository $frontendUserRepository
* @return void
*/
public function injectFrontendUserRepository(FrontendUserRepository $frontendUserRepository) {
$this->frontendUserRepository = $frontendUserRepository;
$query = $this->frontendUserRepository->createQuery();
$querySettings = $query->getQuerySettings();
$querySettings->setRespectStoragePage(FALSE);
$querySettings->setRespectSysLanguage(FALSE);
$this->frontendUserRepository->setDefaultQuerySettings($querySettings);
}
/**
* @return void
*/
public function initializeArguments() {
$this->registerArgument('anyFrontendUser', 'boolean', 'If TRUE, allows any FrontendUser unless other arguments disallows each specific FrontendUser', FALSE, FALSE);
$this->registerArgument('anyFrontendUserGroup', 'boolean', 'If TRUE, allows any FrontendUserGroup unless other arguments disallows each specific FrontendUser', FALSE, FALSE);
$this->registerArgument('frontendUser', 'TYPO3\CMS\Extbase\Domain\Model\FrontendUser', 'The FrontendUser to allow/deny');
$this->registerArgument('frontendUsers', '<TYPO3\CMS\Extbase\Persistence\ObjectStorage>\TYPO3\CMS\Extbase\Domain\Model\FrontendUser', 'The FrontendUsers ObjectStorage to allow/deny');
$this->registerArgument('frontendUserGroup', 'TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup', 'The FrontendUserGroup to allow/deny');
$this->registerArgument('frontendUserGroups', '<TYPO3\CMS\Extbase\Persistence\ObjectStorage>\TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup', 'The FrontendUserGroups ObjectStorage to allow/deny');
$this->registerArgument('anyBackendUser', 'boolean', 'If TRUE, allows any backend user unless other arguments disallows each specific backend user', FALSE, FALSE);
$this->registerArgument('backendUser', 'integer', 'The uid of a backend user to allow/deny');
$this->registerArgument('backendUsers', 'mixed', 'The backend users list to allow/deny. If string, CSV of uids is assumed, if array, array of uids is assumed');
$this->registerArgument('backendUserGroup', 'integer', 'The uid of the backend user group to allow/deny');
$this->registerArgument('backendUserGroups', 'mixed', 'The backend user groups list to allow/deny. If string, CSV of uids is assumed, if array, array of uids is assumed');
$this->registerArgument('admin', 'boolean', 'If TRUE, a backend user which is also an admin is required');
$this->registerArgument('evaluationType', 'string', 'Specify AND or OR (case sensitive) to determine how arguments must be processed. Default is AND, requiring all arguments to be satisfied if used', FALSE, 'AND');
}
/**
* Returns TRUE if all conditions from arguments are satisfied. The
* type of evaluation (AND or OR) can be set using argument "evaluationType"
*
* @return boolean
*/
protected function evaluateArguments() {
$evaluationType = $this->arguments['evaluationType'];
$evaluations = array();
if (TRUE === (boolean) $this->arguments['anyFrontendUser']) {
$evaluations['anyFrontendUser'] = intval($this->assertFrontendUserLoggedIn());
}
if (TRUE === (boolean) $this->arguments['anyFrontendUserGroup']) {
$evaluations['anyFrontendUserGroup'] = intval($this->assertFrontendUserGroupLoggedIn());
}
if (TRUE === isset($this->arguments['frontendUser'])) {
$evaluations['frontendUser'] = intval($this->assertFrontendUserLoggedIn($this->arguments['frontendUser']));
}
if (TRUE === isset($this->arguments['frontendUsers'])) {
$evaluations['frontendUsers'] = intval($this->assertFrontendUsersLoggedIn($this->arguments['frontendUsers']));
}
if (TRUE === isset($this->arguments['frontendUserGroup'])) {
$evaluations['frontendUserGroup'] = intval($this->assertFrontendUserGroupLoggedIn($this->arguments['frontendUserGroup']));
}
if (TRUE === isset($this->arguments['frontendUserGroups'])) {
$evaluations['frontendUserGroups'] = intval($this->assertFrontendUserGroupLoggedIn($this->arguments['frontendUserGroups']));
}
if (TRUE === (boolean) $this->arguments['anyBackendUser']) {
$evaluations['anyBackendUser'] = intval($this->assertBackendUserLoggedIn());
}
if (TRUE === (boolean) $this->arguments['anyBackendUserGroup']) {
$evaluations['anyBackendUserGroup'] = intval($this->assertBackendUserGroupLoggedIn());
}
if (TRUE === isset($this->arguments['backendUser'])) {
$evaluations['backendUser'] = intval($this->assertBackendUserLoggedIn($this->arguments['backendUser']));
}
if (TRUE === isset($this->arguments['backendUsers'])) {
$evaluations['backendUsers'] = intval($this->assertBackendUserLoggedIn($this->arguments['backendUsers']));
}
if (TRUE === isset($this->arguments['backendUserGroup'])) {
$evaluations['backendUserGroup'] = intval($this->assertBackendUserGroupLoggedIn($this->arguments['backendUserGroup']));
}
if (TRUE === isset($this->arguments['backendUserGroups'])) {
$evaluations['backendUserGroups'] = intval($this->assertBackendUserGroupLoggedIn($this->arguments['backendUserGroups']));
}
if (TRUE === (boolean) $this->arguments['admin']) {
$evaluations['admin'] = intval($this->assertAdminLoggedIn());
}
$sum = array_sum($evaluations);
return (boolean) ('AND' === $evaluationType ? count($evaluations) === $sum : $sum > 0);
}
/**
* Returns TRUE only if a FrontendUser is currently logged in. Use argument
* to return TRUE only if the FrontendUser logged in must be that specific user.
*
* @param FrontendUser $frontendUser
* @return boolean
* @api
*/
public function assertFrontendUserLoggedIn(FrontendUser $frontendUser = NULL) {
$currentFrontendUser = $this->getCurrentFrontendUser();
if (FALSE === $currentFrontendUser instanceof FrontendUser) {
return FALSE;
}
if (TRUE === $frontendUser instanceof FrontendUser && TRUE === $currentFrontendUser instanceof FrontendUser) {
if ($currentFrontendUser->getUid() === $frontendUser->getUid()) {
return TRUE;
} else {
return FALSE;
}
}
return (boolean) (TRUE === is_object($currentFrontendUser));
}
/**
* Returns TRUE only if currently logged in frontend user is in list.
*
* @param ObjectStorage $frontendUsers
* @return boolean
* @api
*/
public function assertFrontendUsersLoggedIn(ObjectStorage $frontendUsers = NULL) {
foreach ($frontendUsers as $frontendUser) {
if (TRUE === $this->assertFrontendUserLoggedIn($frontendUser)) {
return TRUE;
}
}
return FALSE;
}
/**
* Returns TRUE if a FrontendUserGroup (specific given argument, else not) is logged in
*
* @param mixed $groups One \TYPO3\CMS\Extbase\Domain\Model\FrontendUserGroup or ObjectStorage containing same
* @return boolean
* @api
*/
public function assertFrontendUserGroupLoggedIn($groups = NULL) {
$currentFrontendUser = $this->getCurrentFrontendUser();
if (FALSE === $currentFrontendUser instanceof FrontendUser) {
return FALSE;
}
$currentFrontendUserGroups = $currentFrontendUser->getUsergroup();
if (NULL === $groups) {
return (boolean) (0 < $currentFrontendUserGroups->count());
} elseif (TRUE === $groups instanceof FrontendUserGroup) {
return $currentFrontendUserGroups->contains($groups);
} elseif (TRUE === $groups instanceof ObjectStorage) {
$currentFrontendUserGroupsClone = clone $currentFrontendUserGroups;
$currentFrontendUserGroupsClone->removeAll($groups);
return ($currentFrontendUserGroups->count() !== $currentFrontendUserGroupsClone->count());
} else {
return FALSE;
}
}
/**
* Returns TRUE only if a backend user is currently logged in. If used,
* argument specifies that the logged in user must be that specific user
*
* @param integer $backendUser
* @return boolean
* @api
*/
public function assertBackendUserLoggedIn($backendUser = NULL) {
$currentBackendUser = $this->getCurrentBackendUser();
if (NULL !== $backendUser) {
if ((integer) $currentBackendUser['uid'] === (integer) $backendUser) {
return TRUE;
} else {
return FALSE;
}
}
return (boolean) (TRUE === is_array($currentBackendUser));
}
/**
* Returns TRUE only if a backend user is logged in and either has any group
* (if param left out) or is a member of the group $groups or a group in
* the array/CSV $groups
*
* @param mixed $groups Array of group uids or CSV of group uids or one group uid
* @return boolean
* @api
*/
public function assertBackendUserGroupLoggedIn($groups = NULL) {
if (FALSE === $this->assertBackendUserLoggedIn()) {
return FALSE;
}
$currentBackendUser = $this->getCurrentBackendUser();
$currentUserGroups = trim($currentBackendUser['usergroup'], ',');
$userGroups = FALSE === empty($currentUserGroups) ? explode(',', $currentUserGroups) : array();
if (0 === count($userGroups)) {
return FALSE;
}
if (TRUE === is_string($groups)) {
$groups = trim($groups, ',');
$groups = FALSE === empty($groups) ? explode(',', $groups) : array();
}
if (0 < count($groups)) {
return (boolean) (0 < count(array_intersect($userGroups, $groups)));
}
return FALSE;
}
/**
* Returns TRUE only if there is a current user logged in and this user
* is an admin class backend user
*
* @return boolean
* @api
*/
public function assertAdminLoggedIn() {
if (FALSE === $this->assertBackendUserLoggedIn()) {
return FALSE;
}
$currentBackendUser = $this->getCurrentBackendUser();
return (boolean) $currentBackendUser['admin'];
}
/**
* Gets the currently logged in Frontend User
*
* @return FrontendUser|NULL
* @api
*/
public function getCurrentFrontendUser() {
if (TRUE === empty($GLOBALS['TSFE']->loginUser)) {
return NULL;
}
return $this->frontendUserRepository->findByUid($GLOBALS['TSFE']->fe_user->user['uid']);
}
/**
* Returns a be_user record as lowerCamelCase indexed array if a BE user is
* currently logged in.
*
* @return array
* @api
*/
public function getCurrentBackendUser() {
return $GLOBALS['BE_USER']->user;
}
/**
* Override: forcibly disables page caching - a TRUE condition
* in this ViewHelper means page content would be depending on
* the current visitor's session/cookie/auth etc.
*
* Returns value of "then" attribute.
* If then attribute is not set, iterates through child nodes and renders ThenViewHelper.
* If then attribute is not set and no ThenViewHelper and no ElseViewHelper is found, all child nodes are rendered
*
* @return string rendered ThenViewHelper or contents of <f:if> if no ThenViewHelper was found
* @api
*/
protected function renderThenChild() {
if (TRUE === $this->isFrontendContext()) {
$GLOBALS['TSFE']->no_cache = 1;
}
return parent::renderThenChild();
}
/**
* @return boolean
*/
protected function isFrontendContext() {
return 'FE' === TYPO3_MODE;
}
}

View File

@@ -0,0 +1,50 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Security;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface;
/**
* ### Security: Allow
*
* Allows access to the child content based on given arguments.
* The ViewHelper is a condition based ViewHelper which means it
* supports the `f:then` and `f:else` child nodes - you can use
* this behaviour to invert the access (i.e. use f:else in a check
* if a frontend user is logged in, if you want to hide content
* from authenticated users):
*
* <v:security.allow anyFrontendUser="TRUE">
* <f:then><!-- protected information displayed --></f:then>
* <f:else><!-- link to login form displayed --></f:else>
* </v:security.allow>
*
* Is the mirror opposite of `v:security.deny`.
*
* @author Claus Due
* @package Vhs
* @subpackage ViewHelpers\Security
*/
class AllowViewHelper extends AbstractSecurityViewHelper implements ChildNodeAccessInterface {
/**
* Render allow - i.e. render "then" child if arguments are satisfied
*
* @return string
*/
public function render() {
$evaluation = $this->evaluateArguments();
if (TRUE === $evaluation) {
return $this->renderThenChild();
} else {
return $this->renderElseChild();
}
}
}

View File

@@ -0,0 +1,43 @@
<?php
namespace FluidTYPO3\Vhs\ViewHelpers\Security;
/*
* This file is part of the FluidTYPO3/Vhs project under GPLv2 or later.
*
* For the full copyright and license information, please read the
* LICENSE.md file that was distributed with this source code.
*/
use TYPO3\CMS\Fluid\Core\ViewHelper\Facets\ChildNodeAccessInterface;
/**
* ### Security: Deny
*
* Denies access to the child content based on given arguments.
* The ViewHelper is a condition based ViewHelper which means it
* supports the `f:then` and `f:else` child nodes.
*
* Is the mirror opposite of `v:security.allow`.
*
* @author Claus Due
* @package Vhs
* @subpackage ViewHelpers\Security
*/
class DenyViewHelper extends AbstractSecurityViewHelper implements ChildNodeAccessInterface {
/**
* Render deny - i.e. render "else" child only if arguments are satisfied,
* resulting in an inverse match.
*
* @return string
*/
public function render() {
$evaluation = $this->evaluateArguments();
if (FALSE === $evaluation) {
return $this->renderThenChild();
} else {
return $this->renderElseChild();
}
}
}