/**
  * TODO: Document this Method! ( assignVariables )
  */
 public function preToolbarRendering()
 {
     $account = $this->context->getAccount();
     $votes = array();
     $privilege = array('PRIVILEGE_ABSTAIN', 'PRIVILEGE_GRANT', 'PRIVILEGE_DENY');
     $roleVotes = \Debug\Toolbar\Service\DataStorage::get('Security:RoleVotes');
     if (is_array($roleVotes)) {
         foreach ($roleVotes as $key => $value) {
             $vote = array('role' => (string) $value['role']);
             $vote['privilege'] = '';
             if (is_array($value['privileges'])) {
                 foreach ($value['privileges'] as $k => $p) {
                     $vote['privilege'] = $privilege[$p];
                 }
             }
             $votes[$value['role'] . ':' . $vote['privilege']] = $vote;
         }
     } else {
         $roles = $this->context->getRoles();
         foreach ($roles as $key => $value) {
             $vote = array('role' => (string) $value);
             $votes[] = $vote;
         }
     }
     \Debug\Toolbar\Service\Collector::getModule('Security')->getToolbar()->addIcon('user')->addText(is_object($account) ? $account->getAccountIdentifier() : 'Guest')->getPopup()->addPartial('Security', array('roles' => $this->context->getRoles(), 'account' => $this->context->getaccount(), 'votes' => $votes))->getPanel()->addPartial('Security', array('roles' => $this->context->getRoles(), 'account' => $this->context->getaccount(), 'votes' => $votes));
 }
 /**
  * Gets the SQL query part to add to a query.
  *
  * @param ClassMetaData $targetEntity Metadata object for the target entity to be filtered
  * @param string $targetTableAlias The target table alias used in the current query
  * @return string The constraint SQL if there is available, empty string otherwise
  */
 public function addFilterConstraint(ClassMetadata $targetEntity, $targetTableAlias)
 {
     $this->initializeDependencies();
     /*
      * TODO: Instead of checking for class account we could introduce some interface for white listing entities from entity security checks
      * Problem with checking the Account is, that this filter calls getRoles() on the security context while accounts are not
      * yet fully initialized. By this we get a half built account object that will end up in access denied exception,
      * as it has no roles (and other properties) set
      */
     if ($this->securityContext->areAuthorizationChecksDisabled() || $targetEntity->getName() === \TYPO3\Flow\Security\Account::class) {
         return '';
     }
     if (!$this->securityContext->isInitialized()) {
         if (!$this->securityContext->canBeInitialized()) {
             return '';
         }
         $this->securityContext->initialize();
     }
     // This is needed to include the current context of roles into query cache identifier
     $this->setParameter('__contextHash', $this->securityContext->getContextHash(), 'string');
     $sqlConstraints = array();
     $grantedConstraints = array();
     $deniedConstraints = array();
     foreach ($this->securityContext->getRoles() as $role) {
         $entityPrivileges = $role->getPrivilegesByType(\TYPO3\Flow\Security\Authorization\Privilege\Entity\EntityPrivilegeInterface::class);
         /** @var EntityPrivilegeInterface $privilege */
         foreach ($entityPrivileges as $privilege) {
             if (!$privilege->matchesEntityType($targetEntity->getName())) {
                 continue;
             }
             $sqlConstraint = $privilege->getSqlConstraint($targetEntity, $targetTableAlias);
             if ($sqlConstraint === null) {
                 continue;
             }
             $sqlConstraints[] = ' NOT (' . $sqlConstraint . ')';
             if ($privilege->isGranted()) {
                 $grantedConstraints[] = ' NOT (' . $sqlConstraint . ')';
             } elseif ($privilege->isDenied()) {
                 $deniedConstraints[] = ' NOT (' . $sqlConstraint . ')';
             }
         }
     }
     $grantedConstraints = array_diff($grantedConstraints, $deniedConstraints);
     $effectiveConstraints = array_diff($sqlConstraints, $grantedConstraints);
     if (count($effectiveConstraints) > 0) {
         return ' (' . implode(') AND (', $effectiveConstraints) . ') ';
     }
     return '';
 }
 /**
  * Checks, if the current policy allows the retrieval of the object fetched by getObjectDataByIdentifier()
  *
  * @Flow\Around("within(TYPO3\Flow\Persistence\PersistenceManagerInterface) && method(.*->getObjectByIdentifier()) && setting(TYPO3.Flow.security.enable)")
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current joinpoint
  * @return array The object data of the original object, or NULL if access is not permitted
  */
 public function checkAccessAfterFetchingAnObjectByIdentifier(JoinPointInterface $joinPoint)
 {
     $result = $joinPoint->getAdviceChain()->proceed($joinPoint);
     if ($this->securityContext->areAuthorizationChecksDisabled() === TRUE || $this->policyService->hasPolicyEntriesForEntities() === FALSE) {
         return $result;
     }
     if ($this->securityContext->isInitialized() === FALSE) {
         if ($this->securityContext->canBeInitialized() === TRUE) {
             $this->securityContext->initialize();
         } else {
             return $result;
         }
     }
     $authenticatedRoles = $this->securityContext->getRoles();
     $entityType = $this->reflectionService->getClassNameByObject($result);
     if ($this->policyService->hasPolicyEntryForEntityType($entityType, $authenticatedRoles)) {
         if ($this->policyService->isGeneralAccessForEntityTypeGranted($entityType, $authenticatedRoles) === FALSE) {
             return NULL;
         }
         $policyConstraintsDefinition = $this->policyService->getResourcesConstraintsForEntityTypeAndRoles($entityType, $authenticatedRoles);
         if ($this->checkConstraintDefinitionsOnResultObject($policyConstraintsDefinition, $result) === FALSE) {
             return NULL;
         }
     }
     return $result;
 }
 /**
  * This is the default Policy voter, it votes for the access privilege for the given resource
  *
  * @param \TYPO3\Flow\Security\Context $securityContext The current security context
  * @param string $resource The resource to vote for
  * @return integer One of: VOTE_GRANT, VOTE_ABSTAIN, VOTE_DENY
  */
 public function voteForResource(\TYPO3\Flow\Security\Context $securityContext, $resource)
 {
     $accessGrants = 0;
     $accessDenies = 0;
     foreach ($securityContext->getRoles() as $role) {
         try {
             $privilege = $this->policyService->getPrivilegeForResource($role, $resource);
         } catch (\TYPO3\Flow\Security\Exception\NoEntryInPolicyException $e) {
             return self::VOTE_ABSTAIN;
         }
         if ($privilege === NULL) {
             continue;
         }
         if ($privilege === \TYPO3\Flow\Security\Policy\PolicyService::PRIVILEGE_GRANT) {
             $accessGrants++;
         } elseif ($privilege === \TYPO3\Flow\Security\Policy\PolicyService::PRIVILEGE_DENY) {
             $accessDenies++;
         }
     }
     if ($accessDenies > 0) {
         return self::VOTE_DENY;
     }
     if ($accessGrants > 0) {
         return self::VOTE_GRANT;
     }
     return self::VOTE_ABSTAIN;
 }
 /**
  * Returns a string message, giving insights what happened during privilege evaluation.
  *
  * @param string $privilegeReasonMessage
  * @return string
  */
 protected function renderDecisionReasonMessage($privilegeReasonMessage)
 {
     if (count($this->securityContext->getRoles()) === 0) {
         $rolesMessage = 'No authenticated roles';
     } else {
         $rolesMessage = 'Authenticated roles: ' . implode(', ', array_keys($this->securityContext->getRoles()));
     }
     return sprintf('Access denied for method' . chr(10) . 'Method: %s::%s()' . chr(10) . chr(10) . '%s' . chr(10) . chr(10) . '%s', $this->joinPoint->getClassName(), $this->joinPoint->getMethodName(), $privilegeReasonMessage, $rolesMessage);
 }
 /**
  * @return array
  */
 public function getAccountRoleIdentifiers()
 {
     $roleIdentifiers = [];
     foreach ($this->securityContext->getRoles() as $role) {
         /** @var Role $role */
         $roleIdentifiers[] = $role->getIdentifier();
     }
     return $roleIdentifiers;
 }
 /**
  * Check if an administrator is logged in and deny access if someone else is trying to access
  */
 public function checkAdministratorAndDenyIfNeeded()
 {
     // check if the user has access to this project
     if (!array_key_exists('GIB.GradingTool:Administrator', $this->securityContext->getRoles())) {
         // add a flash message
         $message = new \TYPO3\Flow\Error\Message('Access denied.', \TYPO3\Flow\Error\Message::SEVERITY_ERROR);
         $this->flashMessageContainer->addMessage($message);
         $this->redirect('index', 'Standard');
     }
 }
 /**
  * Allow access to content if it is my content or when i have the allowed role
  *
  * @param string $contentUserIdentifier
  * @param array $allowedRoles
  * @param array $disallowedRoles
  * @return string
  */
 public function render($contentUserIdentifier, $allowedRoles = [], $disallowedRoles = [])
 {
     try {
         $profile = $this->profileService->getCurrentPartyProfile();
     } catch (\Exception $exception) {
         return;
     }
     $myRoles = $this->securityContext->getRoles();
     $accessBasedOnRole = FALSE;
     foreach (array_unique($allowedRoles) as $role) {
         if (in_array($role, $myRoles)) {
             $accessBasedOnRole = TRUE;
         }
     }
     foreach (array_unique($disallowedRoles) as $role) {
         if (in_array($role, $myRoles)) {
             $accessBasedOnRole = FALSE;
         }
     }
     if ($profile->getIdentifier() === $contentUserIdentifier || $accessBasedOnRole === TRUE) {
         return $this->renderThenChild();
     }
     return $this->renderElseChild();
 }
 /**
  * Returns the publish path and filename to be used to publish the specified persistent resource
  *
  * @Flow\Around("method(TYPO3\Flow\Resource\Publishing\FileSystemPublishingTarget->buildPersistentResourcePublishPathAndFilename()) && setting(TYPO3.Flow.security.enable)")
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point
  * @return mixed Result of the target method
  */
 public function rewritePersistentResourcePublishPathAndFilenameForPrivateResources(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint)
 {
     $resource = $joinPoint->getMethodArgument('resource');
     /** @var $configuration \TYPO3\Flow\Security\Authorization\Resource\SecurityPublishingConfiguration */
     $configuration = $resource->getPublishingConfiguration();
     $returnFilename = $joinPoint->getMethodArgument('returnFilename');
     if ($configuration === NULL || $configuration instanceof \TYPO3\Flow\Security\Authorization\Resource\SecurityPublishingConfiguration === FALSE) {
         return $joinPoint->getAdviceChain()->proceed($joinPoint);
     }
     $publishingPath = FALSE;
     $allowedRoles = $configuration->getAllowedRoles();
     if (count(array_intersect($allowedRoles, $this->securityContext->getRoles())) > 0) {
         $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($joinPoint->getProxy()->getResourcesPublishingPath(), 'Persistent/', $this->session->getID())) . '/';
         $filename = $resource->getResourcePointer()->getHash() . '.' . $resource->getFileExtension();
         \TYPO3\Flow\Utility\Files::createDirectoryRecursively($publishingPath);
         $this->accessRestrictionPublisher->publishAccessRestrictionsForPath($publishingPath);
         if ($this->settings['resource']['publishing']['fileSystem']['mirrorMode'] === 'link') {
             foreach ($allowedRoles as $role) {
                 $roleDirectory = \TYPO3\Flow\Utility\Files::concatenatePaths(array($this->environment->getPathToTemporaryDirectory(), 'PrivateResourcePublishing/', $role));
                 \TYPO3\Flow\Utility\Files::createDirectoryRecursively($roleDirectory);
                 if (file_exists($publishingPath . $role)) {
                     if (\TYPO3\Flow\Utility\Files::is_link(\TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role))) && realpath(\TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role))) === $roleDirectory) {
                         continue;
                     }
                     unlink($publishingPath . $role);
                     symlink($roleDirectory, \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role)));
                 } else {
                     symlink($roleDirectory, \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $role)));
                 }
             }
             $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $allowedRoles[0])) . '/';
         }
         if ($returnFilename === TRUE) {
             $publishingPath = \TYPO3\Flow\Utility\Files::concatenatePaths(array($publishingPath, $filename));
         }
     }
     return $publishingPath;
 }
 /**
  * @param NodeInterface $node
  * @return string[] Array of granted node property names
  */
 public function getDeniedNodePropertiesForEditing(NodeInterface $node)
 {
     $privilegeSubject = new PropertyAwareNodePrivilegeSubject($node);
     $deniedNodePropertyNames = array();
     $grantedNodePropertyNames = array();
     $abstainedNodePropertyNames = array();
     foreach ($this->securityContext->getRoles() as $role) {
         /** @var EditNodePropertyPrivilege $editNodePropertyPrivilege */
         foreach ($role->getPrivilegesByType(EditNodePropertyPrivilege::class) as $editNodePropertyPrivilege) {
             if (!$editNodePropertyPrivilege->matchesSubject($privilegeSubject)) {
                 continue;
             }
             if ($editNodePropertyPrivilege->isGranted()) {
                 $grantedNodePropertyNames = array_merge($grantedNodePropertyNames, $editNodePropertyPrivilege->getNodePropertyNames());
             } elseif ($editNodePropertyPrivilege->isDenied()) {
                 $deniedNodePropertyNames = array_merge($deniedNodePropertyNames, $editNodePropertyPrivilege->getNodePropertyNames());
             } else {
                 $abstainedNodePropertyNames = array_merge($abstainedNodePropertyNames, $editNodePropertyPrivilege->getNodePropertyNames());
             }
         }
     }
     $implicitlyDeniedNodePropertyNames = array_diff($abstainedNodePropertyNames, $grantedNodePropertyNames);
     return array_merge($implicitlyDeniedNodePropertyNames, $deniedNodePropertyNames);
 }
 /**
  * Returns TRUE if access is granted on the given privilege target in the current security context
  *
  * @param string $privilegeTargetIdentifier The identifier of the privilege target to decide on
  * @param array $privilegeParameters Optional array of privilege parameters (simple key => value array)
  * @return boolean TRUE if access is granted, FALSE otherwise
  */
 public function isPrivilegeTargetGranted($privilegeTargetIdentifier, array $privilegeParameters = array())
 {
     return $this->isPrivilegeTargetGrantedForRoles($this->securityContext->getRoles(), $privilegeTargetIdentifier, $privilegeParameters);
 }
 /**
  * @param \Exception $exception
  * @return void
  */
 public function logException(\Exception $exception)
 {
     if (!isset($this->settings['host']) || strlen($this->settings['host']) === 0) {
         return;
     }
     $statusCode = NULL;
     if ($exception instanceof FlowException) {
         $statusCode = $exception->getStatusCode();
     }
     // skip exceptions with status codes matching "skipStatusCodes" setting
     if (isset($this->settings['skipStatusCodes']) && in_array($statusCode, $this->settings['skipStatusCodes'])) {
         return;
     }
     $host = $this->settings['host'];
     $port = isset($this->settings['port']) ? $this->settings['port'] : UdpTransport::DEFAULT_PORT;
     // set chunk size option to wan (default) or lan
     if (isset($this->settings['chunksize']) && strtolower($this->settings['chunksize']) === 'lan') {
         $chunkSize = UdpTransport::CHUNK_SIZE_LAN;
     } else {
         $chunkSize = UdpTransport::CHUNK_SIZE_WAN;
     }
     // setup connection to graylog server
     $transport = new UdpTransport($host, $port, $chunkSize);
     $publisher = new Publisher();
     $publisher->addTransport($transport);
     // set logLevel depending on http status code
     $logLevel = 4;
     // warning
     if ($statusCode === 500) {
         $logLevel = 3;
         // error
     }
     // build message context
     $messageContext = array('full_message' => $exception->getTraceAsString(), 'reference_code' => $exception instanceof FlowException ? $exception->getReferenceCode() : NULL, 'response_status' => $statusCode, 'short_message' => sprintf('%d %s', $statusCode, Response::getStatusMessageByCode($statusCode)), 'code' => $exception->getCode(), 'file' => $exception->getFile(), 'line' => $exception->getLine());
     if ($this->securityContext !== NULL && $this->securityContext->isInitialized()) {
         $account = $this->securityContext->getAccount();
         if ($account !== NULL) {
             $messageContext['authenticated_account'] = $account->getAccountIdentifier() . ' (' . $this->persistenceManager->getIdentifierByObject($account) . ')';
             $messageContext['authenticated_roles'] = implode(', ', array_keys($this->securityContext->getRoles()));
             if ($this->objectManager->isRegistered(PartyService::class)) {
                 /** @var PartyService $partyService */
                 $partyService = $this->objectManager->get(PartyService::class);
                 $person = $partyService->getAssignedPartyOfAccount($account);
                 if ($person instanceof Person) {
                     $messageContext['authenticated_person'] = (string) $person->getName() . ' (' . $this->persistenceManager->getIdentifierByObject($person) . ')';
                 }
             }
         }
     }
     // prepare request details
     if (Bootstrap::$staticObjectManager instanceof ObjectManagerInterface) {
         $bootstrap = Bootstrap::$staticObjectManager->get('TYPO3\\Flow\\Core\\Bootstrap');
         /* @var Bootstrap $bootstrap */
         $requestHandler = $bootstrap->getActiveRequestHandler();
         if ($requestHandler instanceof HttpRequestHandlerInterface) {
             $request = $requestHandler->getHttpRequest();
             $requestData = array('request_domain' => $request->getHeader('Host'), 'request_remote_addr' => $request->getClientIpAddress(), 'request_path' => $request->getRelativePath(), 'request_uri' => $request->getUri()->getPath(), 'request_user_agent' => $request->getHeader('User-Agent'), 'request_method' => $request->getMethod(), 'request_port' => $request->getPort());
             $messageContext = array_merge($messageContext, $requestData);
         }
     }
     // send message to graylog server
     $logger = new Logger($publisher);
     $logger->log($logLevel, $exception->getMessage(), $messageContext);
 }