/**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set controller object name pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws InvalidRequestPatternException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!isset($this->options['controllerObjectNamePattern'])) {
         throw new InvalidRequestPatternException('Missing option "controllerObjectNamePattern" in the ControllerObjectName request pattern configuration', 1446224501);
     }
     return (bool) preg_match('/^' . str_replace('\\', '\\\\', $this->options['controllerObjectNamePattern']) . '$/', $request->getControllerObjectName());
 }
 /**
  * Matches the current request for an unverified signed request.
  *
  * This pattern will return TRUE if the request is not signed or
  * the signature of 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
  */
 public function matchRequest(\TYPO3\Flow\Mvc\RequestInterface $request)
 {
     /** @var \TYPO3\Flow\Http\Request $httpRequest */
     $httpRequest = $request->getHttpRequest();
     if ($httpRequest->hasHeader('X-Request-Signature')) {
         $identifierAndSignature = explode(':', $httpRequest->getHeader('X-Request-Signature'), 2);
         if (count($identifierAndSignature) !== 2) {
             throw new \TYPO3\Flow\Exception('Invalid signature header format, expected "identifier:base64(signature)"', 1354287886);
         }
         $identifier = $identifierAndSignature[0];
         $signature = base64_decode($identifierAndSignature[1]);
         $signData = $this->requestSigner->getSignatureContent($httpRequest);
         $publicKeyFingerprint = $this->publicKeyResolver->resolveFingerprintByIdentifier($identifier);
         if ($publicKeyFingerprint === NULL) {
             throw new \TYPO3\Flow\Exception('Cannot resolve identifier "' . $identifier . '"', 1354288898);
         }
         if ($this->rsaWalletService->verifySignature($signData, $signature, $publicKeyFingerprint)) {
             return FALSE;
         } else {
             $this->emitSignatureNotVerified($request, $identifier, $signData, $signature, $publicKeyFingerprint);
         }
     } else {
         $this->emitSignatureHeaderMissing($request);
     }
     return TRUE;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set host pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest) {
         return false;
     }
     $hostPattern = str_replace('\\*', '.*', preg_quote($this->hostPattern, '/'));
     return preg_match('/^' . $hostPattern . '$/', $request->getHttpRequest()->getUri()->getHost()) === 1;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest) {
         return FALSE;
     }
     $requestPath = $request->getHttpRequest()->getUri()->getPath();
     $requestPathMatchesBackend = substr($requestPath, 0, 5) === '/neos' || strpos($requestPath, '@') !== FALSE;
     return $this->shouldMatchBackend === $requestPathMatchesBackend;
 }
 /**
  * Handles a request. The result output is returned by altering the given response.
  *
  * @param \TYPO3\Flow\Mvc\ActionRequest $request The request object
  * @param \TYPO3\Flow\Http\Response $response The response, modified by this handler
  * @return void
  * @throws \TYPO3\Fluid\Core\Widget\Exception\WidgetContextNotFoundException
  * @api
  */
 public function processRequest(\TYPO3\Flow\Mvc\RequestInterface $request, \TYPO3\Flow\Mvc\ResponseInterface $response)
 {
     $widgetContext = $request->getInternalArgument('__widgetContext');
     if ($widgetContext === NULL) {
         throw new \TYPO3\Fluid\Core\Widget\Exception\WidgetContextNotFoundException('The widget context could not be found in the request.', 1307450180);
     }
     $this->widgetConfiguration = $widgetContext->getWidgetConfiguration();
     parent::processRequest($request, $response);
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against the set IP pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws InvalidRequestPatternException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!isset($this->options['cidrPattern'])) {
         throw new InvalidRequestPatternException('Missing option "cidrPattern" in the Ip request pattern configuration', 1446224520);
     }
     if (!$request instanceof ActionRequest) {
         return false;
     }
     return (bool) IpUtility::cidrMatch($request->getHttpRequest()->getClientIpAddress(), $this->options['cidrPattern']);
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(RequestInterface $request)
 {
     $shouldMatchBackend = $this->options['area'] === self::AREA_FRONTEND ? false : true;
     if (!$request instanceof ActionRequest) {
         return false;
     }
     $requestPath = $request->getHttpRequest()->getUri()->getPath();
     $requestPathMatchesBackend = substr($requestPath, 0, 5) === '/neos' || strpos($requestPath, '@') !== false;
     return $shouldMatchBackend === $requestPathMatchesBackend;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set URL pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws InvalidRequestPatternException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest) {
         return false;
     }
     if (!isset($this->options['uriPattern'])) {
         throw new InvalidRequestPatternException('Missing option "uriPattern" in the Uri request pattern configuration', 1446224530);
     }
     return (bool) preg_match('/^' . str_replace('/', '\\/', $this->options['uriPattern']) . '$/', $request->getHttpRequest()->getUri()->getPath());
 }
 /**
  * Handles a request. The result output is returned by altering the given response.
  *
  * @param RequestInterface $request The request object
  * @param ResponseInterface $response The response, modified by this handler
  * @return void
  * @throws WidgetContextNotFoundException
  * @api
  */
 public function processRequest(RequestInterface $request, ResponseInterface $response)
 {
     /** @var $request \TYPO3\Flow\Mvc\ActionRequest */
     /** @var $widgetContext WidgetContext */
     $widgetContext = $request->getInternalArgument('__widgetContext');
     if ($widgetContext === NULL) {
         throw new WidgetContextNotFoundException('The widget context could not be found in the request.', 1307450180);
     }
     $this->widgetConfiguration = $widgetContext->getWidgetConfiguration();
     parent::processRequest($request, $response);
 }
Exemple #10
0
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set controller object name pattern rules
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest) {
         return FALSE;
     }
     foreach ($this->getPattern() as $method) {
         if ($request->getHttpRequest()->getMethod() === $method) {
             return TRUE;
         }
     }
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set host pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  * @throws InvalidRequestPatternException
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!isset($this->options['hostPattern'])) {
         throw new InvalidRequestPatternException('Missing option "hostPattern" in the Host request pattern configuration', 1446224510);
     }
     if (!$request instanceof ActionRequest) {
         return false;
     }
     $hostPattern = str_replace('\\*', '.*', preg_quote($this->options['hostPattern'], '/'));
     return preg_match('/^' . $hostPattern . '$/', $request->getHttpRequest()->getUri()->getHost()) === 1;
 }
Exemple #12
0
 /**
  * Returns the locale item for the current request
  *
  * @param \Aimeos\MShop\Context\Item\Iface $context Context object
  * @param \TYPO3\Flow\Mvc\RequestInterface $request Request object
  * @return \Aimeos\MShop\Locale\Item\Iface Locale item object
  */
 public function get(\Aimeos\MShop\Context\Item\Iface $context, \TYPO3\Flow\Mvc\RequestInterface $request)
 {
     if ($this->locale === null) {
         $params = $request->getArguments();
         $site = isset($params['site']) ? $params['site'] : 'default';
         $lang = isset($params['locale']) ? $params['locale'] : '';
         $currency = isset($params['currency']) ? $params['currency'] : '';
         $disableSites = (bool) (isset($this->settings['flow']['disableSites']) ? $this->settings['flow']['disableSites'] : true);
         $localeManager = \Aimeos\MShop\Locale\Manager\Factory::createManager($context);
         $this->locale = $localeManager->bootstrap($site, $lang, $currency, $disableSites);
     }
     return $this->locale;
 }
Exemple #13
0
 /**
  * Returns the fixed parameters that should be included in every URL
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request Request object
  * @return array Associative list of site, language and currency if available
  */
 protected function getFixedParams(\TYPO3\Flow\Mvc\RequestInterface $request)
 {
     $fixed = array();
     $params = $request->getArguments();
     if (isset($params['site'])) {
         $fixed['site'] = $params['site'];
     }
     if (isset($params['locale'])) {
         $fixed['locale'] = $params['locale'];
     }
     if (isset($params['currency'])) {
         $fixed['currency'] = $params['currency'];
     }
     return $fixed;
 }
 /**
  * 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;
 }
 /**
  * @test
  * @expectedException \TYPO3\Flow\Mvc\Exception\InfiniteLoopException
  */
 public function dispatchThrowsAnInfiniteLoopExceptionIfTheRequestCouldNotBeDispachedAfter99Iterations()
 {
     $requestCallCounter = 0;
     $requestCallBack = function () use(&$requestCallCounter) {
         return $requestCallCounter++ < 101 ? FALSE : TRUE;
     };
     $this->mockRequest->expects($this->any())->method('isDispatched')->will($this->returnCallBack($requestCallBack, '__invoke'));
     $this->dispatcher->dispatch($this->mockRequest, $this->mockResponse);
 }
 /**
  * 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;
 }
 /**
  * Dispatches a request to a controller
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request The request to dispatch
  * @param \TYPO3\Flow\Mvc\ResponseInterface $response The response, to be modified by the controller
  * @return void
  * @throws \TYPO3\Flow\Mvc\Exception\InfiniteLoopException
  * @api
  */
 public function dispatch(RequestInterface $request, ResponseInterface $response)
 {
     $dispatchLoopCount = 0;
     while (!$request->isDispatched()) {
         if ($dispatchLoopCount++ > 99) {
             throw new \TYPO3\Flow\Mvc\Exception\InfiniteLoopException('Could not ultimately dispatch the request after ' . $dispatchLoopCount . ' iterations.', 1217839467);
         }
         $controller = $this->resolveController($request);
         try {
             $this->emitBeforeControllerInvocation($request, $response, $controller);
             $controller->processRequest($request, $response);
             $this->emitAfterControllerInvocation($request, $response, $controller);
         } catch (StopActionException $exception) {
             $this->emitAfterControllerInvocation($request, $response, $controller);
             if ($exception instanceof ForwardException) {
                 $request = $exception->getNextRequest();
             } elseif ($request->isMainRequest() === FALSE) {
                 $request = $request->getParentRequest();
             }
         }
     }
 }
Exemple #18
0
 /**
  * Returns the locale item for the current request
  *
  * @param \MShop_Context_Item_Interface $context Context object
  * @param \TYPO3\Flow\Mvc\RequestInterface $request Request object
  * @return \MShop_Locale_Item_Interface Locale item object
  */
 protected function getLocale(\MShop_Context_Item_Interface $context, \TYPO3\Flow\Mvc\RequestInterface $request)
 {
     if ($this->locale === null) {
         $params = $request->getArguments();
         $site = isset($params['site']) ? $params['site'] : 'default';
         $lang = isset($params['locale']) ? $params['locale'] : '';
         $currency = isset($params['currency']) ? $params['currency'] : '';
         $disableSites = (bool) (isset($this->settings['flow']['disableSites']) ? $this->settings['flow']['disableSites'] : false);
         $localeManager = \MShop_Locale_Manager_Factory::createManager($context);
         $this->locale = $localeManager->bootstrap($site, $lang, $currency, $disableSites);
     }
     return $this->locale;
 }
 /**
  * Create a complete cache identifier for the given
  * request that conforms to cache identifier syntax
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request
  * @return string
  */
 protected function createCacheIdentifier($request)
 {
     $cacheIdentifiersParts = array();
     do {
         $cacheIdentifiersParts[] = $request->getControllerPackageKey();
         $cacheIdentifiersParts[] = $request->getControllerSubpackageKey();
         $cacheIdentifiersParts[] = $request->getControllerName();
         $cacheIdentifiersParts[] = $request->getControllerActionName();
         $cacheIdentifiersParts[] = $request->getFormat();
         $request = $request->getParentRequest();
     } while ($request instanceof ActionRequest);
     return md5(implode('-', $cacheIdentifiersParts));
 }
 /**
  * Adds the argument namespace of the current request to the specified arguments.
  * This happens recursively iterating through the nested requests in case of a subrequest.
  * For example if this is executed inside a widget sub request in a plugin sub request, the result would be:
  * array(
  *   'pluginRequestNamespace' => array(
  *     'widgetRequestNamespace => $arguments
  *    )
  * )
  *
  * @param array $arguments arguments
  * @param \TYPO3\Flow\Mvc\RequestInterface $currentRequest
  * @return array arguments with namespace
  */
 protected function addNamespaceToArguments(array $arguments, \TYPO3\Flow\Mvc\RequestInterface $currentRequest)
 {
     while (!$currentRequest->isMainRequest()) {
         $argumentNamespace = $currentRequest->getArgumentNamespace();
         if ($argumentNamespace !== '') {
             $arguments = array($argumentNamespace => $arguments);
         }
         $currentRequest = $currentRequest->getParentRequest();
     }
     return $arguments;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set controller object name pattern rules
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(\TYPO3\Flow\Mvc\RequestInterface $request)
 {
     return (bool) preg_match('/^' . str_replace('\\', '\\\\', $this->controllerObjectNamePattern) . '$/', $request->getControllerObjectName());
 }
 /**
  * Finds and instantiates a controller that matches the current request.
  * If no controller can be found, an instance of NotFoundControllerInterface is returned.
  *
  * @param RequestInterface $request The request to dispatch
  * @return ControllerInterface
  * @throws NoSuchOptionException
  * @throws Controller\Exception\InvalidControllerException
  */
 protected function resolveController(RequestInterface $request)
 {
     /** @var ActionRequest $request */
     $controllerObjectName = $request->getControllerObjectName();
     if ($controllerObjectName === '') {
         if (isset($this->settings['mvc']['notFoundController'])) {
             throw new NoSuchOptionException('The configuration option TYPO3.Flow:mvc:notFoundController is deprecated since Flow 2.0. Use the "renderingGroups" option of the production exception handler instead in order to render custom error messages.', 1346949795);
         }
         $exceptionMessage = 'No controller could be resolved which would match your request';
         if ($request instanceof ActionRequest) {
             $exceptionMessage .= sprintf('. Package key: "%s", controller name: "%s"', $request->getControllerPackageKey(), $request->getControllerName());
             if ($request->getControllerSubpackageKey() !== null) {
                 $exceptionMessage .= sprintf(', SubPackage key: "%s"', $request->getControllerSubpackageKey());
             }
             $exceptionMessage .= sprintf('. (%s %s)', $request->getHttpRequest()->getMethod(), $request->getHttpRequest()->getUri());
         }
         throw new Controller\Exception\InvalidControllerException($exceptionMessage, 1303209195, null, $request);
     }
     $controller = $this->objectManager->get($controllerObjectName);
     if (!$controller instanceof ControllerInterface) {
         throw new Controller\Exception\InvalidControllerException('Invalid controller "' . $request->getControllerObjectName() . '". The controller must be a valid request handling controller, ' . (is_object($controller) ? get_class($controller) : gettype($controller)) . ' given.', 1202921619, null, $request);
     }
     return $controller;
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against the set IP pattern rules
  *
  * @param RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(RequestInterface $request)
 {
     if (!$request instanceof ActionRequest) {
         return false;
     }
     return (bool) $this->cidrMatch($request->getHttpRequest()->getClientIpAddress(), $this->ipPattern);
 }
 /**
  * Matches a \TYPO3\Flow\Mvc\RequestInterface against its set URL pattern rules
  *
  * @param \TYPO3\Flow\Mvc\RequestInterface $request The request that should be matched
  * @return boolean TRUE if the pattern matched, FALSE otherwise
  */
 public function matchRequest(\TYPO3\Flow\Mvc\RequestInterface $request)
 {
     return (bool) preg_match('/^' . $this->uriPattern . '$/', $request->getHttpRequest()->getUri()->getPath());
 }
Exemple #25
0
 /**
  * Adds the "url" helper to the view object
  *
  * @param \Aimeos\MW\View\Iface $view View object
  * @param \TYPO3\Flow\Mvc\Routing\UriBuilder $uriBuilder URL builder object
  * @param \TYPO3\Flow\Mvc\RequestInterface|null $request Request object
  * @return \Aimeos\MW\View\Iface Modified view object
  */
 protected function addUrl(\Aimeos\MW\View\Iface $view, \TYPO3\Flow\Mvc\Routing\UriBuilder $uriBuilder, \TYPO3\Flow\Mvc\RequestInterface $request = null)
 {
     $fixed = array();
     if ($request !== null) {
         $params = $request->getArguments();
         if (isset($params['site'])) {
             $fixed['site'] = $params['site'];
         }
         if (isset($params['locale'])) {
             $fixed['locale'] = $params['locale'];
         }
         if (isset($params['currency'])) {
             $fixed['currency'] = $params['currency'];
         }
     }
     $helper = new \Aimeos\MW\View\Helper\Url\Flow($view, $uriBuilder, $fixed);
     $view->addHelper('url', $helper);
     return $view;
 }