/**
  * @return NodeInterface
  */
 public function getCurrentUserNode()
 {
     try {
         return $this->profileService->getCurrentPartyProfile();
     } catch (\Exception $exception) {
         $this->systemLogger->log('Profile node could not be fetched: ' . $exception->getMessage(), LOG_CRIT);
     }
 }
 /**
  * Checks the cache for the route path given in the Request and returns the result
  *
  * @param Request $httpRequest
  * @return array|boolean the cached route values or FALSE if no cache entry was found
  */
 public function getCachedMatchResults(Request $httpRequest)
 {
     $cachedResult = $this->routeCache->get($this->buildRouteCacheIdentifier($httpRequest));
     if ($cachedResult !== FALSE) {
         $this->systemLogger->log(sprintf('Router route(): A cached Route with the cache identifier "%s" matched the path "%s".', $this->buildRouteCacheIdentifier($httpRequest), $httpRequest->getRelativePath()), LOG_DEBUG);
     }
     return $cachedResult;
 }
 private function processReceiverGroup(ReceiverGroup $receiverGroup, $language = NULL)
 {
     $cacheFileName = $receiverGroup->getCacheFileName($language);
     $jqProcess = escapeshellarg('cat ' . escapeshellcmd($receiverGroup->getReceiverSource()->getSourceFileName()) . ' | jq -c ' . escapeshellarg($this->convertFilterIntoJqExpression($receiverGroup->getFilter($language))) . ' > ' . escapeshellcmd($cacheFileName) . ' ; wc -l < ' . escapeshellcmd($cacheFileName) . ' > ' . escapeshellcmd($cacheFileName . '.lines'));
     $finalProcess = 'nohup /bin/bash -c ' . $jqProcess . ' &';
     $this->systemLogger->log('Starting process: ' . $finalProcess);
     $proc = new Process($finalProcess);
     $proc->start();
 }
 /**
  * Before advice for all methods annotated with "@Flow\Session(autoStart=true)".
  * Those methods will trigger a session initialization if a session does not exist
  * yet.
  *
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current join point
  * @return void
  * @fixme The pointcut expression below does not consider the options of the session annotation – needs adjustments in the AOP framework
  * @Flow\Before("methodAnnotatedWith(TYPO3\Flow\Annotations\Session)")
  */
 public function initializeSession(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint)
 {
     if ($this->session->isStarted() === TRUE) {
         return;
     }
     $objectName = $this->objectManager->getObjectNameByClassName(get_class($joinPoint->getProxy()));
     $methodName = $joinPoint->getMethodName();
     $this->systemLogger->log(sprintf('Session initialization triggered by %s->%s.', $objectName, $methodName), LOG_DEBUG);
     $this->session->start();
 }
 /**
  * Flush caches according to the previously registered node changes.
  *
  * @return void
  */
 public function shutdownObject()
 {
     if ($this->tagsToFlush !== array()) {
         foreach ($this->tagsToFlush as $tag => $logMessage) {
             $affectedEntries = $this->contentCache->flushByTag($tag);
             if ($affectedEntries > 0) {
                 $this->systemLogger->log(sprintf('Content cache: Removed %s entries %s', $affectedEntries, $logMessage), LOG_DEBUG);
             }
         }
     }
 }
 /**
  * @param string $event
  * @param string $person
  *
  * @return void
  */
 public function removeAttendeeAction($event, $person = '')
 {
     try {
         $context = $this->contextFactory->create([]);
         $person = $this->getPersonProfile($person, $context);
         $event = $context->getNodeByIdentifier($event);
         $this->eventService->removeAttendeeFromEvent($event, $person);
     } catch (\Exception $exception) {
         $this->systemLogger->log($exception->getMessage(), LOG_ALERT);
     }
     $this->addFlashMessage('Je bent afgemeld');
     $this->redirectToUri('/agenda');
 }
Exemple #7
0
 /**
  * @return void
  */
 public function pingAction()
 {
     $this->systemLogger->log("FOO" . $this->apiKey);
     $apiKey = $this->request->getHttpRequest()->getHeader('X-Api-Key');
     $this->systemLogger->log($apiKey);
     if ($apiKey === $this->apiKey) {
         $this->response->setStatus(204);
         $this->response->send();
     } else {
         $this->response->setStatus(403, 'Invalid Authentication');
         $this->response->send();
     }
     return false;
 }
 /**
  * @param string $value
  * @throws Exception
  * @throws \TYPO3\Flow\Resource\Exception
  * @throws \TYPO3\Flow\Utility\Exception
  */
 protected function initializeValue($value)
 {
     if (!is_array($value)) {
         throw new Exception('Value must be an array, with source URI (sourceUri) and filename (filename)', 1425981082);
     }
     if (!isset($value['sourceUri'])) {
         throw new Exception('Missing source URI', 1425981083);
     }
     $sourceUri = trim($value['sourceUri']);
     if (!isset($value['filename'])) {
         throw new Exception('Missing filename URI', 1425981084);
     }
     $filename = trim($value['filename']);
     $overrideFilename = isset($value['overrideFilename']) ? trim($value['overrideFilename']) : $filename;
     if (!isset($this->options['downloadDirectory'])) {
         throw new Exception('Missing download directory data type option', 1425981085);
     }
     Files::createDirectoryRecursively($this->options['downloadDirectory']);
     $temporaryFileAndPathname = trim($this->options['downloadDirectory'] . $filename);
     $this->download($sourceUri, $temporaryFileAndPathname);
     $sha1Hash = sha1_file($temporaryFileAndPathname);
     # Try to add file extenstion if missing
     if (!$this->downloadCache->has($sha1Hash)) {
         $fileExtension = pathinfo($temporaryFileAndPathname, PATHINFO_EXTENSION);
         if (trim($fileExtension) === '') {
             $mimeTypeGuesser = new MimeTypeGuesser();
             $mimeType = $mimeTypeGuesser->guess($temporaryFileAndPathname);
             $this->logger->log(sprintf('Try to guess mime type for "%s" (%s), result: %s', $sourceUri, $filename, $mimeType), LOG_DEBUG);
             $fileExtension = MediaTypes::getFilenameExtensionFromMediaType($mimeType);
             if ($fileExtension !== '') {
                 $oldTemporaryDestination = $temporaryFileAndPathname;
                 $temporaryDestination = $temporaryFileAndPathname . '.' . $fileExtension;
                 copy($oldTemporaryDestination, $temporaryDestination);
                 $this->logger->log(sprintf('Rename "%s" to "%s"', $oldTemporaryDestination, $temporaryDestination), LOG_DEBUG);
             }
         }
     }
     $resource = $this->resourceManager->getResourceBySha1($sha1Hash);
     if ($resource === NULL) {
         $resource = $this->resourceManager->importResource($temporaryFileAndPathname);
         if ($filename !== $overrideFilename) {
             $resource->setFilename($overrideFilename);
         }
     }
     $this->temporaryFileAndPathname = $temporaryFileAndPathname;
     $this->downloadCache->set($sha1Hash, ['sha1Hash' => $sha1Hash, 'filename' => $filename, 'sourceUri' => $sourceUri, 'temporaryFileAndPathname' => $temporaryFileAndPathname]);
     $this->value = $resource;
 }
 /**
  * Log a deprecation message once
  *
  * @return void
  */
 protected function logDeprecation()
 {
     if (!static::$loggedDeprecation) {
         static::$loggedDeprecation = true;
         $this->logger->log('TYPO3.Media is configured to simulate the deprecated Neos 1.2 behaviour. Please check the setting "TYPO3.Media.behaviourFlag".', LOG_DEBUG);
     }
 }
 /**
  * Renumbers the indexes of all nodes directly below the node specified by the
  * given path.
  *
  * Note that renumbering must happen in-memory and can't be optimized by a clever
  * query executed directly by the database because sorting indexes of new or
  * modified nodes need to be considered.
  *
  * @param string $parentPath Path to the parent node
  * @return void
  * @throws Exception\NodeException
  */
 protected function renumberIndexesInLevel($parentPath)
 {
     $this->systemLogger->log(sprintf('Renumbering nodes in level below %s.', $parentPath), LOG_INFO);
     /** @var \Doctrine\ORM\Query $query */
     $query = $this->entityManager->createQuery('SELECT n FROM TYPO3\\TYPO3CR\\Domain\\Model\\NodeData n WHERE n.parentPathHash = :parentPathHash ORDER BY n.index ASC');
     $query->setParameter('parentPathHash', md5($parentPath));
     $nodesOnLevel = array();
     /** @var $node NodeData */
     foreach ($query->getResult() as $node) {
         $nodesOnLevel[$node->getIndex()] = $node;
     }
     /** @var $node NodeData */
     foreach ($this->addedNodes as $node) {
         if ($node->getParentPath() === $parentPath) {
             $index = $node->getIndex();
             if (isset($nodesOnLevel[$index])) {
                 throw new Exception\NodeException(sprintf('Index conflict for nodes %s and %s: both have index %s', $nodesOnLevel[$index]->getPath(), $node->getPath(), $index), 1317140401);
             }
             $nodesOnLevel[$index] = $node;
         }
     }
     // We need to sort the nodes now, to take unpersisted node orderings into account.
     // This fixes bug #34291
     ksort($nodesOnLevel);
     $newIndex = 100;
     foreach ($nodesOnLevel as $node) {
         if ($newIndex > self::INDEX_MAXIMUM) {
             throw new Exception\NodeException(sprintf('Reached maximum node index of %s while setting index of node %s.', $newIndex, $node->getPath()), 1317140402);
         }
         $node->setIndex($newIndex);
         $newIndex += 100;
     }
 }
 /**
  * @param array $nodes
  */
 public function assignNodes(array $nodes)
 {
     $data = array();
     foreach ($nodes as $node) {
         if ($node->getPath() !== '/') {
             $q = new FlowQuery(array($node));
             $closestDocumentNode = $q->closest('[instanceof TYPO3.Neos:Document]')->get(0);
             if ($closestDocumentNode !== NULL) {
                 $data[] = array('nodeContextPath' => $node->getContextPath(), 'documentNodeContextPath' => $closestDocumentNode->getContextPath());
             } else {
                 $this->systemLogger->log('You have a node that is no longer connected to a parent. Path: ' . $node->getPath() . ' (Identifier: ' . $node->getIdentifier() . ')');
             }
         }
     }
     $this->assign('value', array('data' => $data, 'success' => TRUE));
 }
 /**
  * @Flow\Around("setting(Ttree.Embedly.logApiRequest) && within(Ttree\Embedly\Embedly) && method(public .*->(oembed|preview|objectify|extract|services)())")
  * @param JoinPointInterface $joinPoint The current join point
  * @return mixed
  */
 public function getResponseFromCache(JoinPointInterface $joinPoint)
 {
     $proxy = $joinPoint->getProxy();
     $key = ObjectAccess::getProperty($proxy, 'key');
     $params = $joinPoint->getMethodArgument('params');
     $cacheKey = md5($joinPoint->getClassName() . $joinPoint->getMethodName() . $key . json_encode($params));
     if ($this->responseCache->has($cacheKey)) {
         $this->systemLogger->log(sprintf('   cache hit Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG);
         return $this->responseCache->get($cacheKey);
     } else {
         $this->systemLogger->log(sprintf('   cache miss Embedly::%s', $joinPoint->getMethodName()), LOG_DEBUG);
     }
     $response = $joinPoint->getAdviceChain()->proceed($joinPoint);
     $this->responseCache->set($cacheKey, $response);
     return $response;
 }
 /**
  * Defines template if configured for provider.
  *
  * @param string $providerName
  *
  * @return bool TRUE if some configuration found, FALSE if no configuration defined for given provider.
  */
 private function definePrettyPreRedirectTemplate($providerName)
 {
     $prettyPreRedirectPage = $this->configurationManager->getConfiguration(\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'TYPO3.Flow.security.authentication.providers.' . $providerName . '.providerOptions.Miscellaneous.prettyPreRedirectPage');
     if (empty($prettyPreRedirectPage)) {
         return false;
     }
     $log = '';
     if (isset($prettyPreRedirectPage['layoutRootPath']) && method_exists($this->view, 'setLayoutRootPath')) {
         $this->view->setLayoutRootPath($prettyPreRedirectPage['layoutRootPath']);
     } elseif (isset($prettyPreRedirectPage['layoutRootPath']) && !method_exists($this->view, 'setLayoutRootPath')) {
         $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setLayoutRootPath().', $providerName);
     }
     if (isset($prettyPreRedirectPage['partialRootPath']) && method_exists($this->view, 'setPartialRootPath')) {
         $this->view->setPartialRootPath($prettyPreRedirectPage['partialRootPath']);
     } elseif (isset($prettyPreRedirectPage['partialRootPath']) && !method_exists($this->view, 'setPartialRootPath')) {
         $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setPartialRootPath().', $providerName);
     }
     if (isset($prettyPreRedirectPage['templatePathAndFilename']) && method_exists($this->view, 'setTemplatePathAndFilename')) {
         $this->view->setTemplatePathAndFilename($prettyPreRedirectPage['templatePathAndFilename']);
     } elseif (isset($prettyPreRedirectPage['templatePathAndFilename']) && !method_exists($this->view, 'setTemplatePathAndFilename')) {
         $log .= sprintf('Pretty pre redirect page for "%s" provider can not be used, because you use custom teplating engine and this does not know method setTemplatePathAndFilename().', $providerName);
     }
     if (!empty($log)) {
         $this->systemLogger->log($log, LOG_ERR);
     }
     $this->view->assignMultiple($prettyPreRedirectPage);
     return true;
 }
 /**
  * Filters the classnames available for object management by filter expressions that either include or exclude classes.
  *
  * @param array $classNames All classnames per package
  * @param array $filterConfiguration The filter configuration to apply
  * @param string $includeOrExclude if this is an "include" or "exclude" filter
  * @return array the remaining class
  * @throws \TYPO3\Flow\Configuration\Exception\InvalidConfigurationTypeException
  */
 protected function applyClassFilterConfiguration($classNames, $filterConfiguration, $includeOrExclude = 'include')
 {
     if (!in_array($includeOrExclude, array('include', 'exclude'))) {
         throw new \InvalidArgumentException('The argument $includeOrExclude must be one of "include" or "exclude", the given value was not allowed.', 1423726253);
     }
     foreach ($filterConfiguration as $packageKey => $filterExpressions) {
         if (!array_key_exists($packageKey, $classNames)) {
             $this->systemLogger->log('The package "' . $packageKey . '" specified in the setting "TYPO3.Flow.object.' . $includeOrExclude . 'Classes" was either excluded or is not loaded.', LOG_DEBUG);
             continue;
         }
         if (!is_array($filterExpressions)) {
             throw new \TYPO3\Flow\Configuration\Exception\InvalidConfigurationTypeException('The value given for setting "TYPO3.Flow.object.' . $includeOrExclude . 'Classes.\'' . $packageKey . '\'" is  invalid. It should be an array of expressions. Check the syntax in the YAML file.', 1422357272);
         }
         $classesForPackageUnderInspection = $classNames[$packageKey];
         $classNames[$packageKey] = array();
         foreach ($filterExpressions as $filterExpression) {
             $classesForPackageUnderInspection = array_filter($classesForPackageUnderInspection, function ($className) use($filterExpression, $includeOrExclude) {
                 $match = preg_match('/' . $filterExpression . '/', $className);
                 return $includeOrExclude === 'include' ? $match === 1 : $match !== 1;
             });
             if ($includeOrExclude === 'include') {
                 $classNames[$packageKey] = array_merge($classNames[$packageKey], $classesForPackageUnderInspection);
                 $classesForPackageUnderInspection = $classNames[$packageKey];
             } else {
                 $classNames[$packageKey] = $classesForPackageUnderInspection;
             }
         }
         if ($classNames[$packageKey] === array()) {
             unset($classNames[$packageKey]);
         }
     }
     return $classNames;
 }
 /**
  * Checks if the specified method matches with the method annotation filter pattern
  *
  * @param string $className Name of the class to check against - not used here
  * @param string $methodName Name of the method
  * @param string $methodDeclaringClassName Name of the class the method was originally declared in
  * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection - not used here
  * @return boolean TRUE if the class matches, otherwise FALSE
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     if ($methodDeclaringClassName === null || !method_exists($methodDeclaringClassName, $methodName)) {
         return false;
     }
     $designatedAnnotations = $this->reflectionService->getMethodAnnotations($methodDeclaringClassName, $methodName, $this->annotation);
     if ($designatedAnnotations !== array() || $this->annotationValueConstraints === array()) {
         $matches = $designatedAnnotations !== array();
     } else {
         // It makes no sense to check property values for an annotation that is used multiple times, we shortcut and check the value against the first annotation found.
         $firstFoundAnnotation = $designatedAnnotations;
         $annotationProperties = $this->reflectionService->getClassPropertyNames($this->annotation);
         foreach ($this->annotationValueConstraints as $propertyName => $expectedValue) {
             if (!array_key_exists($propertyName, $annotationProperties)) {
                 $this->systemLogger->log('The property "' . $propertyName . '" declared in pointcut does not exist in annotation ' . $this->annotation, LOG_NOTICE);
                 return false;
             }
             if ($firstFoundAnnotation->{$propertyName} === $expectedValue) {
                 $matches = true;
             } else {
                 return false;
             }
         }
     }
     return $matches;
 }
 /**
  * Iterates over all existing sessions and removes their data if the inactivity
  * timeout was reached.
  *
  * @param boolean $maximumSessionsToRemove How many sessions to remove per run
  * @return integer The number of outdated entries removed
  * @api
  */
 public function collectGarbage($maximumSessionsToRemove = 0)
 {
     if ($this->inactivityTimeout === 0) {
         return 0;
     }
     if ($this->metaDataCache->has('_garbage-collection-running')) {
         return false;
     }
     $sessionRemovalCount = 0;
     $this->metaDataCache->set('_garbage-collection-running', true, array(), 120);
     foreach ($this->metaDataCache->getIterator() as $sessionIdentifier => $sessionInfo) {
         if ($sessionIdentifier === '_garbage-collection-running') {
             continue;
         }
         $lastActivitySecondsAgo = $this->now - $sessionInfo['lastActivityTimestamp'];
         if ($lastActivitySecondsAgo > $this->inactivityTimeout) {
             if ($sessionInfo['storageIdentifier'] === null) {
                 $this->systemLogger->log('SESSION INFO INVALID: ' . $sessionIdentifier, LOG_WARNING, $sessionInfo);
             } else {
                 $this->storageCache->flushByTag($sessionInfo['storageIdentifier']);
                 $sessionRemovalCount++;
             }
             $this->metaDataCache->remove($sessionIdentifier);
         }
         if ($maximumSessionsToRemove > 0 && $sessionRemovalCount >= $maximumSessionsToRemove) {
             break;
         }
     }
     $this->metaDataCache->remove('_garbage-collection-running');
     return $sessionRemovalCount;
 }
 /**
  * Checks if the specified method matches against the method name
  * expression.
  *
  * Returns TRUE if method name, visibility and arguments constraints match and the target
  * method is not final.
  *
  * @param string $className Ignored in this pointcut filter
  * @param string $methodName Name of the method to match against
  * @param string $methodDeclaringClassName Name of the class the method was originally declared in
  * @param mixed $pointcutQueryIdentifier Some identifier for this query - must at least differ from a previous identifier. Used for circular reference detection.
  * @return boolean TRUE if the class matches, otherwise FALSE
  * @throws \TYPO3\Flow\Aop\Exception
  */
 public function matches($className, $methodName, $methodDeclaringClassName, $pointcutQueryIdentifier)
 {
     $matchResult = preg_match('/^' . $this->methodNameFilterExpression . '$/', $methodName);
     if ($matchResult === false) {
         throw new \TYPO3\Flow\Aop\Exception('Error in regular expression', 1168876915);
     } elseif ($matchResult !== 1) {
         return false;
     }
     switch ($this->methodVisibility) {
         case 'public':
             if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodPublic($methodDeclaringClassName, $methodName))) {
                 return false;
             }
             break;
         case 'protected':
             if (!($methodDeclaringClassName !== null && $this->reflectionService->isMethodProtected($methodDeclaringClassName, $methodName))) {
                 return false;
             }
             break;
     }
     if ($methodDeclaringClassName !== null && $this->reflectionService->isMethodFinal($methodDeclaringClassName, $methodName)) {
         return false;
     }
     $methodArguments = $methodDeclaringClassName === null ? array() : $this->reflectionService->getMethodParameters($methodDeclaringClassName, $methodName);
     foreach (array_keys($this->methodArgumentConstraints) as $argumentName) {
         $objectAccess = explode('.', $argumentName, 2);
         $argumentName = $objectAccess[0];
         if (!array_key_exists($argumentName, $methodArguments)) {
             $this->systemLogger->log('The argument "' . $argumentName . '" declared in pointcut does not exist in method ' . $methodDeclaringClassName . '->' . $methodName, LOG_NOTICE);
             return false;
         }
     }
     return true;
 }
 /**
  * Detects changes of the files and directories to be monitored and emits signals
  * accordingly.
  *
  * @return void
  * @api
  */
 public function detectChanges()
 {
     if ($this->changedFiles === null || $this->changedPaths === null) {
         $this->loadDetectedDirectoriesAndFiles();
         $changesDetected = false;
         $this->changedPaths = $this->changedFiles = array();
         $this->changedFiles = $this->detectChangedFiles($this->monitoredFiles);
         foreach ($this->monitoredDirectories as $path => $filenamePattern) {
             $changesDetected = $this->detectChangesOnPath($path, $filenamePattern) ? true : $changesDetected;
         }
         if ($changesDetected) {
             $this->saveDetectedDirectoriesAndFiles();
         }
         $this->directoriesAndFiles = null;
     }
     $changedFileCount = count($this->changedFiles);
     $changedPathCount = count($this->changedPaths);
     if ($changedFileCount > 0) {
         $this->emitFilesHaveChanged($this->identifier, $this->changedFiles);
     }
     if ($changedPathCount > 0) {
         $this->emitDirectoriesHaveChanged($this->identifier, $this->changedPaths);
     }
     if ($changedFileCount > 0 || $changedPathCount) {
         $this->systemLogger->log(sprintf('File Monitor "%s" detected %s changed files and %s changed directories.', $this->identifier, $changedFileCount, $changedPathCount), LOG_INFO);
     }
 }
 /**
  * Deletes the given Resource from the Resource Repository and, if the storage data is no longer used in another
  * Resource object, also deletes the data from the storage.
  *
  * This method will also remove the Resource object from the (internal) ResourceRepository.
  *
  * @param Resource $resource The resource to delete
  * @param boolean $unpublishResource If the resource should be unpublished before deleting it from the storage
  * @return boolean TRUE if the resource was deleted, otherwise FALSE
  * @api
  */
 public function deleteResource(Resource $resource, $unpublishResource = TRUE)
 {
     $collectionName = $resource->getCollectionName();
     $result = $this->resourceRepository->findBySha1($resource->getSha1());
     if (count($result) > 1) {
         $this->systemLogger->log(sprintf('Not removing storage data of resource %s (%s) because it is still in use by %s other Resource object(s).', $resource->getFilename(), $resource->getSha1(), count($result) - 1), LOG_DEBUG);
     } else {
         if (!isset($this->collections[$collectionName])) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s) because it refers to the unknown collection "%s".', $resource->getFilename(), $resource->getSha1(), $collectionName), LOG_WARNING);
             return FALSE;
         }
         $storage = $this->collections[$collectionName]->getStorage();
         if (!$storage instanceof WritableStorageInterface) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s) because it its collection "%s" is read-only.', $resource->getFilename(), $resource->getSha1(), $collectionName), LOG_WARNING);
             return FALSE;
         }
         try {
             $storage->deleteResource($resource);
         } catch (\Exception $exception) {
             $this->systemLogger->log(sprintf('Could not remove storage data of resource %s (%s): %s.', $resource->getFilename(), $resource->getSha1(), $exception->getMessage()), LOG_WARNING);
             return FALSE;
         }
         if ($unpublishResource) {
             /** @var TargetInterface $target */
             $target = $this->collections[$collectionName]->getTarget();
             $target->unpublishResource($resource);
             $this->systemLogger->log(sprintf('Removed storage data and unpublished resource %s (%s) because it not used by any other Resource object.', $resource->getFilename(), $resource->getSha1()), LOG_DEBUG);
         } else {
             $this->systemLogger->log(sprintf('Removed storage data of resource %s (%s) because it not used by any other Resource object.', $resource->getFilename(), $resource->getSha1()), LOG_DEBUG);
         }
     }
     $resource->setDeleted();
     $this->resourceRepository->remove($resource);
     return TRUE;
 }
 /**
  * @return void
  */
 public function flush()
 {
     try {
         $this->documentManager->flush();
     } catch (\Exception $exception) {
         $this->systemLogger->log('Could not flush ODM unit of work, error: ' . $exception->getMessage());
     }
 }
 /**
  * Sends a mail and creates a system logger entry if sending failed
  *
  * @param Message $mail
  * @return boolean TRUE on success, otherwise FALSE
  */
 protected function sendMail(Message $mail)
 {
     $numberOfRecipients = 0;
     // ignore exceptions but log them
     $exceptionMessage = '';
     try {
         $numberOfRecipients = $mail->send();
     } catch (\Exception $e) {
         $this->systemLogger->logException($e);
         $exceptionMessage = $e->getMessage();
     }
     if ($numberOfRecipients < 1) {
         $this->systemLogger->log('Could not send notification email "' . $mail->getSubject() . '"', LOG_ERR, ['exception' => $exceptionMessage, 'message' => $mail->getSubject(), 'id' => (string) $mail->getHeaders()->get('Message-ID')]);
         return false;
     }
     return true;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against the configured CSRF pattern rules and
  * searches for invalid csrf tokens. If this returns TRUE, the request is invalid!
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws AuthenticationRequiredException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest || $request->getHttpRequest()->isMethodSafe()) {
         $this->systemLogger->log('CSRF: No token required, safe request', LOG_DEBUG);
         return false;
     }
     if ($this->authenticationManager->isAuthenticated() === false) {
         $this->systemLogger->log('CSRF: No token required, not authenticated', LOG_DEBUG);
         return false;
     }
     if ($this->securityContext->areAuthorizationChecksDisabled() === true) {
         $this->systemLogger->log('CSRF: No token required, authorization checks are disabled', LOG_DEBUG);
         return false;
     }
     $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName());
     $actionMethodName = $request->getControllerActionName() . 'Action';
     if (!$this->hasPolicyEntryForMethod($controllerClassName, $actionMethodName)) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is not restricted by a policy.', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     if ($this->reflectionService->isMethodTaggedWith($controllerClassName, $actionMethodName, 'skipcsrfprotection')) {
         $this->systemLogger->log(sprintf('CSRF: No token required, method %s::%s() is tagged with a "skipcsrfprotection" annotation', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return false;
     }
     $httpRequest = $request->getHttpRequest();
     if ($httpRequest->hasHeader('X-Flow-Csrftoken')) {
         $csrfToken = $httpRequest->getHeader('X-Flow-Csrftoken');
     } else {
         $internalArguments = $request->getMainRequest()->getInternalArguments();
         $csrfToken = isset($internalArguments['__csrfToken']) ? $internalArguments['__csrfToken'] : null;
     }
     if (empty($csrfToken)) {
         $this->systemLogger->log(sprintf('CSRF: token was empty but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     if (!$this->securityContext->hasCsrfProtectionTokens()) {
         throw new AuthenticationRequiredException(sprintf('CSRF: No CSRF tokens in security context, possible session timeout. A valid token is required for %s::%s()', $controllerClassName, $actionMethodName), 1317309673);
     }
     if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === false) {
         $this->systemLogger->log(sprintf('CSRF: token was invalid but a valid token is required for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
         return true;
     }
     $this->systemLogger->log(sprintf('CSRF: Successfully verified token for %s::%s()', $controllerClassName, $actionMethodName), LOG_DEBUG);
     return false;
 }
Exemple #23
0
 /**
  * Validates tokenClasses and CAS-client settings by given cas provider.
  * WARNING: Given provider must be of type RafaelKa\JasigPhpCas\Authentication\Provider\PhpCasAuthenticationProvider
  * validateConfigurationForCasProvider.
  *
  * @todo move validation to other class.
  *
  * @param string $providerName defined in Settings.yaml providers name
  *
  * @throws \RafaelKa\JasigPhpCas\Exception\InvalidArgumentException
  * @throws \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException
  *
  * @return bool
  */
 public function validateCASSettingsByProvider($providerName)
 {
     $provider = $this->configurationManager->getConfiguration(\TYPO3\Flow\Configuration\ConfigurationManager::CONFIGURATION_TYPE_SETTINGS, 'TYPO3.Flow.security.authentication.providers.' . $providerName);
     if (empty($provider)) {
         throw new \RafaelKa\JasigPhpCas\Exception\InvalidArgumentException(sprintf('"%s" - provider does not exists.', $providerName), 1371136764);
     }
     if ($provider['provider'] !== self::DEFAULT_CAS_PROVIDER) {
         throw new \RafaelKa\JasigPhpCas\Exception\InvalidArgumentException(sprintf('Bad parameter for $providerName given in "%s()". The "%s" is not "%s". Please make sure that TYPO3.Flow.security.authentication.providers.%s.provider is "%s" or don\'t validate this provider with "%s->%s()".', __FUNCTION__, $providerName, self::DEFAULT_CAS_PROVIDER, $providerName, self::DEFAULT_CAS_PROVIDER, __CLASS__, __FUNCTION__), 1370963205);
     }
     // tokenClasses can be ommitted but if is set, then properly ;)
     if (!empty($provider['tokenClasses']) && is_array($provider['tokenClasses'])) {
         foreach ($provider['tokenClasses'] as $tokenClassName) {
             if (!class_exists($tokenClassName)) {
                 throw new \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException(sprintf('Class "%s" configured in Settings.yaml at "TYPO3.Flow.security.authentication.providers.%s.tokenClasses" does not exists.', $tokenClassName, $providerName), 1370947266);
             }
             if (!$this->reflectionService->isClassImplementationOf($tokenClassName, 'TYPO3\\Flow\\Security\\Authentication\\TokenInterface')) {
                 throw new \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException(sprintf('Class "%s" configured in Settings.yaml at "TYPO3.Flow.security.authentication.providers.%s.tokenClasses" is not implementation of "\\TYPO3\\Flow\\Security\\Authentication\\TokenInterface". Please rediclare "%s" as "\\TYPO3\\Flow\\Security\\Authentication\\TokenInterface" adapter Class.', $tokenClassName, $providerName, $tokenClassName), 1370947266);
             }
         }
     } elseif (isset($provider['tokenClasses']) && !is_array($provider['tokenClasses'])) {
         throw new \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException(sprintf('The configuration setting for TYPO3.Flow.security.authentication.providers.%s.tokenClasses is set but empty or is not an array. This option can be ommited but if it is set, then must contain a list(yaml array with - ) of token class names, which this provider can authenticate.', $providerName), 1371140452);
     }
     // cas Client Settings : required
     if (empty($provider['providerOptions']['casClient'])) {
         throw new \TYPO3\Flow\Security\Exception\MissingConfigurationException(sprintf('The configuration setting for TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient is missing. Please specify it in your Settings.yaml file. Beware: This file must not be accessible by the public!', $providerName), 1370797663);
     }
     if (empty($provider['providerOptions']['casClient']['server_hostname'])) {
         throw new \TYPO3\Flow\Security\Exception\MissingConfigurationException(sprintf('The configuration setting for TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.server_hostname is missing. Please specify it in your Settings.yaml file. Beware: This file must not be accessible by the public!', $providerName), 1370797665);
     }
     if (empty($provider['providerOptions']['casClient']['server_uri'])) {
         throw new \TYPO3\Flow\Security\Exception\MissingConfigurationException(sprintf('The configuration setting for TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.server_uri is missing. Please specify it in your Settings.yaml file. Beware: This file must not be accessible by the public!', $providerName), 1370797667);
     }
     if (empty($provider['providerOptions']['casClient']['noCasServerValidation']) || $provider['providerOptions']['casClient']['noCasServerValidation'] === false) {
         if (empty($provider['providerOptions']['casClient']['casServerCACertificatePath'])) {
             throw new \TYPO3\Flow\Security\Exception\MissingConfigurationException(sprintf('The configuration setting for TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.casServerCACertificatePath is missing. Please specify it in your Settings.yaml file. Beware: This file must not be accessible by the public!', $providerName), 1370797668);
         } elseif (!is_readable($provider['providerOptions']['casClient']['casServerCACertificatePath'])) {
             throw new \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException(sprintf('Certificate "%s" difined in "TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.casServerCACertificatePath" does not exists or is not readable. Please specify it correctly in your Settings.yaml file or make it readable. Beware: This both files must not be accessible by the public!', $provider['providerOptions']['casClient']['casServerCACertificatePath'], $providerName), 1370775324);
         }
     } else {
         // @todo : LOG WARNING -> WARNING: Beware: sprintf('[Warning:] Set TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.noCasServerValidation to TRUE in your Settings.yaml file makes CAS-Provider insecure. Please set it to FALSE and TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.casServerCACertificatePath correctly.', $providerName, $providerName);
         $this->systemLogger->log(sprintf('[Warning:] Set TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.noCasServerValidation to TRUE in your Settings.yaml file makes CAS-Provider insecure. Please set it to FALSE and TYPO3.Flow.security.authentication.providers.%s.providerOptions.casClient.casServerCACertificatePath correctly.', $providerName, $providerName), LOG_NOTICE);
     }
     // Mapper class if set
     if (!empty($provider['providerOptions']['Mapping']['MapperClass'])) {
         $mapperClassName = $provider['providerOptions']['Mapping']['MapperClass'];
         if (!class_exists($mapperClassName)) {
             throw new \RafaelKa\JasigPhpCas\Exception\InvalidConfigurationException(sprintf('Class "%s" configured in Settings.yaml at "TYPO3.Flow.security.authentication.providers.%s.Mapping.MapperClass" does not exists.', $mapperClassName, $providerName), 1370983932);
         }
         if (!$this->reflectionService->isClassImplementationOf($mapperClassName, 'RafaelKa\\JasigPhpCas\\Service\\MapperInterface')) {
             throw new \RafaelKa\JasigPhpCas\Exception\InvalidClassDefinitionForMapperException(sprintf('Class "%s" configured in Settings.yaml at "TYPO3.Flow.security.authentication.providers.%s.MapperClass" is not implementation of "RafaelKa\\JasigPhpCas\\Service\\MapperInterface". Please rediclare "%s" as "\\TYPO3\\Flow\\Security\\Authentication\\TokenInterface" adapter Class. Don\'t forget to flush caches.', $mapperClassName, $providerName, $mapperClassName), 1370981664);
         }
         if ($this->reflectionService->getClassAnnotation($mapperClassName, 'TYPO3\\Flow\\Annotations\\Scope')->value !== 'singleton') {
             throw new \RafaelKa\JasigPhpCas\Exception\InvalidClassDefinitionForMapperException(sprintf('Class "%s" configured in Settings.yaml at "TYPO3.Flow.security.authentication.providers.%s.MapperClass" is not a singleton. Please declare "%s" as "@Flow\\Scope("singleton")" Class.', $mapperClassName, $providerName, $mapperClassName), 1371036890);
         }
     }
     return true;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against the configured CSRF pattern rules and
  * searches for invalid csrf tokens. If this returns TRUE, the request is invalid!
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws \TYPO3\Flow\Security\Exception\AuthenticationRequiredException
  */
 public function matchRequest(\TYPO3\Flow\Mvc\RequestInterface $request)
 {
     if (!$request instanceof ActionRequest || $request->getHttpRequest()->isMethodSafe()) {
         $this->systemLogger->log('No CSRF required, safe request', LOG_DEBUG);
         return FALSE;
     }
     if ($this->authenticationManager->isAuthenticated() === FALSE) {
         $this->systemLogger->log('No CSRF required, not authenticated', LOG_DEBUG);
         return FALSE;
     }
     if ($this->securityContext->areAuthorizationChecksDisabled() === TRUE) {
         $this->systemLogger->log('No CSRF required, authorization checks are disabled', LOG_DEBUG);
         return FALSE;
     }
     $controllerClassName = $this->objectManager->getClassNameByObjectName($request->getControllerObjectName());
     $actionName = $request->getControllerActionName() . 'Action';
     if (!$this->policyService->hasPolicyEntryForMethod($controllerClassName, $actionName)) {
         $this->systemLogger->log(sprintf('CSRF protection filter: allowed %s request without requiring CSRF token because action "%s" in controller "%s" is not restricted by a policy.', $request->getHttpRequest()->getMethod(), $actionName, $controllerClassName), LOG_NOTICE);
         return FALSE;
     }
     if ($this->reflectionService->isMethodTaggedWith($controllerClassName, $actionName, 'skipcsrfprotection')) {
         return FALSE;
     }
     $httpRequest = $request->getHttpRequest();
     if ($httpRequest->hasHeader('X-Flow-Csrftoken')) {
         $csrfToken = $httpRequest->getHeader('X-Flow-Csrftoken');
     } else {
         $internalArguments = $request->getMainRequest()->getInternalArguments();
         $csrfToken = isset($internalArguments['__csrfToken']) ? $internalArguments['__csrfToken'] : NULL;
     }
     if (empty($csrfToken)) {
         $this->systemLogger->log('CSRF token was empty', LOG_DEBUG);
         return TRUE;
     }
     if (!$this->securityContext->hasCsrfProtectionTokens()) {
         throw new \TYPO3\Flow\Security\Exception\AuthenticationRequiredException('No tokens in security context, possible session timeout', 1317309673);
     }
     if ($this->securityContext->isCsrfProtectionTokenValid($csrfToken) === FALSE) {
         $this->systemLogger->log('CSRF token was invalid', LOG_DEBUG);
         return TRUE;
     }
     // the CSRF token was necessary and is valid
     return FALSE;
 }
 /**
  * This function tries to find yet unmatched dependencies which need to be injected via "inject*" setter methods.
  *
  * @param array &$objectConfigurations
  * @return void
  * @throws \TYPO3\Flow\Object\Exception if an injected property is private
  */
 protected function autowireProperties(array &$objectConfigurations)
 {
     foreach ($objectConfigurations as $objectConfiguration) {
         $className = $objectConfiguration->getClassName();
         $properties = $objectConfiguration->getProperties();
         $classMethodNames = get_class_methods($className);
         if (!is_array($classMethodNames)) {
             if (!class_exists($className)) {
                 throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('The class "%s" defined in the object configuration for object "%s", defined in package: %s, does not exist.', $className, $objectConfiguration->getObjectName(), $objectConfiguration->getPackageKey()), 1352371371);
             } else {
                 throw new \TYPO3\Flow\Object\Exception\UnknownClassException(sprintf('Could not autowire properties of class "%s" because names of methods contained in that class could not be retrieved using get_class_methods().', $className), 1352386418);
             }
         }
         foreach ($classMethodNames as $methodName) {
             if (strlen($methodName) > 6 && substr($methodName, 0, 6) === 'inject' && $methodName[6] === strtoupper($methodName[6])) {
                 $propertyName = lcfirst(substr($methodName, 6));
                 $autowiringAnnotation = $this->reflectionService->getMethodAnnotation($className, $methodName, 'TYPO3\\Flow\\Annotations\\Autowiring');
                 if ($autowiringAnnotation !== NULL && $autowiringAnnotation->enabled === FALSE) {
                     continue;
                 }
                 if ($methodName === 'injectSettings') {
                     $packageKey = $objectConfiguration->getPackageKey();
                     if ($packageKey !== NULL) {
                         $properties[$propertyName] = new ConfigurationProperty($propertyName, $packageKey, ConfigurationProperty::PROPERTY_TYPES_SETTING);
                     }
                 } else {
                     if (array_key_exists($propertyName, $properties)) {
                         continue;
                     }
                     $methodParameters = $this->reflectionService->getMethodParameters($className, $methodName);
                     if (count($methodParameters) !== 1) {
                         $this->systemLogger->log(sprintf('Could not autowire property %s because %s() expects %s instead of exactly 1 parameter.', "{$className}::{$propertyName}", $methodName, count($methodParameters) ?: 'none'), LOG_DEBUG);
                         continue;
                     }
                     $methodParameter = array_pop($methodParameters);
                     if ($methodParameter['class'] === NULL) {
                         $this->systemLogger->log(sprintf('Could not autowire property %s because the method parameter in %s() contained no class type hint.', "{$className}::{$propertyName}", $methodName), LOG_DEBUG);
                         continue;
                     }
                     $properties[$propertyName] = new ConfigurationProperty($propertyName, $methodParameter['class'], ConfigurationProperty::PROPERTY_TYPES_OBJECT);
                 }
             }
         }
         foreach ($this->reflectionService->getPropertyNamesByAnnotation($className, 'TYPO3\\Flow\\Annotations\\Inject') as $propertyName) {
             if ($this->reflectionService->isPropertyPrivate($className, $propertyName)) {
                 $exceptionMessage = 'The property "' . $propertyName . '" in class "' . $className . '" must not be private when annotated for injection.';
                 throw new \TYPO3\Flow\Object\Exception($exceptionMessage, 1328109641);
             }
             if (!array_key_exists($propertyName, $properties)) {
                 $objectName = trim(implode('', $this->reflectionService->getPropertyTagValues($className, $propertyName, 'var')), ' \\');
                 $properties[$propertyName] = new ConfigurationProperty($propertyName, $objectName, ConfigurationProperty::PROPERTY_TYPES_OBJECT);
             }
         }
         $objectConfiguration->setProperties($properties);
     }
 }
 /**
  * Return the total number of hits for the query.
  *
  * @return integer
  */
 public function count()
 {
     $timeBefore = microtime(TRUE);
     $count = parent::count();
     $timeAfterwards = microtime(TRUE);
     if ($this->queryLogEnabled === TRUE) {
         $this->logger->log('Query Log (' . $this->logMessage . '): -- execution time: ' . ($timeAfterwards - $timeBefore) * 1000 . ' ms -- Total Results: ' . $count, LOG_DEBUG);
     }
     return $count;
 }
 /**
  * Flushes I18n caches if translation files have changed
  *
  * @param array $changedFiles A list of full paths to changed files
  * @return void
  * @see flushSystemCachesByChangedFiles()
  */
 protected function flushTranslationCachesByChangedFiles(array $changedFiles)
 {
     foreach ($changedFiles as $pathAndFilename => $status) {
         if (preg_match('/\\/Translations\\/.+\\.xlf/', $pathAndFilename) === 1) {
             $this->systemLogger->log('The localization files have changed, thus flushing the I18n XML model cache.', LOG_INFO);
             $this->getCache('Flow_I18n_XmlModelCache')->flush();
             break;
         }
     }
 }
 /**
  * Refreshes this asset after the Resource or any other parameters affecting thumbnails have been modified
  *
  * @return void
  */
 public function refresh()
 {
     $assetClassType = str_replace('TYPO3\\Media\\Domain\\Model\\', '', get_class($this));
     $this->systemLogger->log(sprintf('%s: refresh() called, clearing all thumbnails. Filename: %s. Resource SHA1: %s', $assetClassType, $this->getResource()->getFilename(), $this->getResource()->getSha1()), LOG_DEBUG);
     // whitelist objects so they can be deleted (even during safe requests)
     $this->persistenceManager->whitelistObject($this);
     foreach ($this->thumbnails as $thumbnail) {
         $this->persistenceManager->whitelistObject($thumbnail);
     }
     $this->thumbnails->clear();
 }
 /**
  * @param callable $callback a callback function to process every notification
  * @return void
  * @api
  */
 public function flush(callable $callback = null)
 {
     foreach ($this->messages as $message) {
         /** @var Message $message */
         $this->messages->detach($message);
         $this->systemLogger->log('ResourcePublishingMessage: ' . $message->getMessage(), $message->getSeverity());
         if ($callback !== null) {
             $callback($message);
         }
     }
 }
 /**
  * Logs calls of collectGarbage()
  *
  * @Flow\AfterReturning("within(TYPO3\Flow\Session\SessionInterface) && method(.*->collectGarbage())")
  * @param \TYPO3\Flow\Aop\JoinPointInterface $joinPoint The current joinpoint
  * @return void
  */
 public function logCollectGarbage(\TYPO3\Flow\Aop\JoinPointInterface $joinPoint)
 {
     $sessionRemovalCount = $joinPoint->getResult();
     if ($sessionRemovalCount > 0) {
         $this->systemLogger->log(sprintf('%s: Triggered garbage collection and removed %s expired sessions.', $this->getClassName($joinPoint), $sessionRemovalCount), LOG_INFO);
     } elseif ($sessionRemovalCount === 0) {
         $this->systemLogger->log(sprintf('%s: Triggered garbage collection but no sessions needed to be removed.', $this->getClassName($joinPoint)), LOG_INFO);
     } elseif ($sessionRemovalCount === false) {
         $this->systemLogger->log(sprintf('%s: Ommitting garbage collection because another process is already running. Consider lowering the GC propability if these messages appear a lot.', $this->getClassName($joinPoint)), LOG_WARNING);
     }
 }