‪TYPO3CMS  ‪main
FormProtectionFactory.php
Go to the documentation of this file.
1 <?php
2 
3 declare(strict_types=1);
4 
5 /*
6  * This file is part of the TYPO3 CMS project.
7  *
8  * It is free software; you can redistribute it and/or modify it under
9  * the terms of the GNU General Public License, either version 2
10  * of the License, or any later version.
11  *
12  * For the full copyright and license information, please read the
13  * LICENSE.txt file that was distributed with this source code.
14  *
15  * The TYPO3 project - inspiring people to share!
16  */
17 
19 
20 use Psr\Http\Message\ServerRequestInterface;
33 
43 {
44  public function ‪__construct(
45  protected readonly ‪FlashMessageService $flashMessageService,
46  protected readonly ‪LanguageServiceFactory $languageServiceFactory,
47  protected readonly ‪Registry $registry,
48  protected readonly ‪FrontendInterface $runtimeCache
49  ) {}
50 
56  public function ‪createForType(string $type): ‪AbstractFormProtection
57  {
58  if (!in_array($type, ['installtool', 'frontend', 'backend', 'disabled'], true)) {
59  $type = 'disabled';
60  }
62  if ($this->runtimeCache->has(‪$identifier)) {
63  return $this->runtimeCache->get(‪$identifier);
64  }
65  $classNameAndConstructorArguments = $this->‪getClassNameAndConstructorArguments($type, ‪$GLOBALS['TYPO3_REQUEST'] ?? null);
66  $this->runtimeCache->set(‪$identifier, $this->‪createInstance(...$classNameAndConstructorArguments));
67  return $this->runtimeCache->get(‪$identifier);
68  }
69 
73  public function ‪createFromRequest(ServerRequestInterface $request): ‪AbstractFormProtection
74  {
75  $type = $this->‪determineTypeFromRequest($request);
77  if ($this->runtimeCache->has(‪$identifier)) {
78  return $this->runtimeCache->get(‪$identifier);
79  }
80  $classNameAndConstructorArguments = $this->‪getClassNameAndConstructorArguments($type, $request);
81  $this->runtimeCache->set(‪$identifier, $this->‪createInstance(...$classNameAndConstructorArguments));
82  return $this->runtimeCache->get(‪$identifier);
83  }
84 
88  protected function ‪determineTypeFromRequest(ServerRequestInterface $request): string
89  {
90  if ($this->‪isInstallToolSession($request)) {
91  return 'installtool';
92  }
93  if ($this->‪isFrontendSession($request)) {
94  return 'frontend';
95  }
96  if ($this->‪isBackendSession()) {
97  return 'backend';
98  }
99  return 'disabled';
100  }
101 
110  protected function ‪getClassNameAndConstructorArguments(string $type, ?ServerRequestInterface $request): array
111  {
112  if ($type === 'installtool') {
113  return [
114  InstallToolFormProtection::class,
115  ];
116  }
117  if ($type === 'frontend') {
118  $user = $request?->getAttribute('frontend.user');
119  if ($user && isset($user->user['uid'])) {
120  return [
121  FrontendFormProtection::class,
122  $user,
123  ];
124  }
125  }
126  if ($type === 'backend') {
127  $user = ‪$GLOBALS['BE_USER'] ?? null;
128  $isAjaxCall = (bool)($request ? $request->getAttribute('route')?->getOption('ajax') : false);
129  if ($user && isset($user->user['uid'])) {
130  return [
131  BackendFormProtection::class,
132  $user,
133  $this->registry,
134  $this->‪getMessageClosure(
135  $this->languageServiceFactory->createFromUserPreferences($user),
136  $this->flashMessageService->getMessageQueueByIdentifier(),
137  $isAjaxCall
138  ),
139  ];
140  }
141  }
142  // failed to use preferred type, disable form protection
143  return [
144  DisabledFormProtection::class,
145  ];
146  }
147 
151  protected function ‪getIdentifierForType(string $type): string
152  {
153  return 'formprotection-instance-' . hash('xxh3', $type);
154  }
155 
159  protected function ‪isInstallToolSession(ServerRequestInterface $request): bool
160  {
161  return (bool)((int)$request->getAttribute('applicationType') & ‪SystemEnvironmentBuilder::REQUESTTYPE_INSTALL);
162  }
163 
167  protected function ‪isBackendSession(): bool
168  {
169  $user = ‪$GLOBALS['BE_USER'] ?? null;
170  return $user instanceof ‪BackendUserAuthentication && isset($user->user['uid']);
171  }
172 
176  protected function ‪isFrontendSession(ServerRequestInterface $request): bool
177  {
178  $user = $request->getAttribute('frontend.user');
179  return $user instanceof ‪FrontendUserAuthentication && isset($user->user['uid']);
180  }
181 
182  protected function ‪getMessageClosure(‪LanguageService $languageService, ‪FlashMessageQueue $messageQueue, bool $isAjaxCall): \Closure
183  {
184  return static function () use ($languageService, $messageQueue, $isAjaxCall) {
185  $flashMessage = GeneralUtility::makeInstance(
186  FlashMessage::class,
187  $languageService->‪sL('LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:error.formProtection.tokenInvalid'),
188  '',
189  ContextualFeedbackSeverity::ERROR,
190  !$isAjaxCall
191  );
192  $messageQueue->‪enqueue($flashMessage);
193  };
194  }
195 
204  protected function ‪createInstance(string $className, ...$constructorArguments): ‪AbstractFormProtection
205  {
206  if (!class_exists($className)) {
207  throw new \InvalidArgumentException('$className must be the name of an existing class, but actually was "' . $className . '".', 1285352962);
208  }
209  $instance = GeneralUtility::makeInstance($className, ...$constructorArguments);
210  if (!$instance instanceof ‪AbstractFormProtection) {
211  throw new \InvalidArgumentException('$className must be a subclass of ' . AbstractFormProtection::class . ', but actually was "' . $className . '".', 1285353026);
212  }
213  return $instance;
214  }
215 }
‪TYPO3\CMS\Core\Localization\LanguageServiceFactory
Definition: LanguageServiceFactory.php:25
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\isBackendSession
‪isBackendSession()
Definition: FormProtectionFactory.php:167
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\getMessageClosure
‪getMessageClosure(LanguageService $languageService, FlashMessageQueue $messageQueue, bool $isAjaxCall)
Definition: FormProtectionFactory.php:182
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\isFrontendSession
‪isFrontendSession(ServerRequestInterface $request)
Definition: FormProtectionFactory.php:176
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\getClassNameAndConstructorArguments
‪array getClassNameAndConstructorArguments(string $type, ?ServerRequestInterface $request)
Definition: FormProtectionFactory.php:110
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\getIdentifierForType
‪getIdentifierForType(string $type)
Definition: FormProtectionFactory.php:151
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\__construct
‪__construct(protected readonly FlashMessageService $flashMessageService, protected readonly LanguageServiceFactory $languageServiceFactory, protected readonly Registry $registry, protected readonly FrontendInterface $runtimeCache)
Definition: FormProtectionFactory.php:44
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder
Definition: SystemEnvironmentBuilder.php:41
‪TYPO3\CMS\Core\Registry
Definition: Registry.php:33
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\determineTypeFromRequest
‪determineTypeFromRequest(ServerRequestInterface $request)
Definition: FormProtectionFactory.php:88
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\createFromRequest
‪createFromRequest(ServerRequestInterface $request)
Definition: FormProtectionFactory.php:73
‪TYPO3\CMS\Core\Type\ContextualFeedbackSeverity
‪ContextualFeedbackSeverity
Definition: ContextualFeedbackSeverity.php:25
‪TYPO3\CMS\Core\FormProtection
Definition: AbstractFormProtection.php:16
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\createInstance
‪createInstance(string $className,... $constructorArguments)
Definition: FormProtectionFactory.php:204
‪TYPO3\CMS\Core\Localization\LanguageService\sL
‪sL($input)
Definition: LanguageService.php:131
‪TYPO3\CMS\Core\Authentication\BackendUserAuthentication
Definition: BackendUserAuthentication.php:62
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\isInstallToolSession
‪isInstallToolSession(ServerRequestInterface $request)
Definition: FormProtectionFactory.php:159
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\FormProtection\AbstractFormProtection
Definition: AbstractFormProtection.php:31
‪TYPO3\CMS\Core\Messaging\FlashMessage
Definition: FlashMessage.php:27
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory
Definition: FormProtectionFactory.php:43
‪$GLOBALS
‪$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['adminpanel']['modules']
Definition: ext_localconf.php:25
‪TYPO3\CMS\Core\FormProtection\FormProtectionFactory\createForType
‪createForType(string $type)
Definition: FormProtectionFactory.php:56
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue\enqueue
‪enqueue($message)
Definition: FlashMessageQueue.php:62
‪TYPO3\CMS\Core\Localization\LanguageService
Definition: LanguageService.php:46
‪TYPO3\CMS\Frontend\Authentication\FrontendUserAuthentication
Definition: FrontendUserAuthentication.php:33
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Core\SystemEnvironmentBuilder\REQUESTTYPE_INSTALL
‪const REQUESTTYPE_INSTALL
Definition: SystemEnvironmentBuilder.php:51
‪TYPO3\CMS\Core\Messaging\FlashMessageQueue
Definition: FlashMessageQueue.php:29
‪TYPO3\CMS\Core\Messaging\FlashMessageService
Definition: FlashMessageService.php:27
‪TYPO3\CMS\Webhooks\Message\$identifier
‪identifier readonly string $identifier
Definition: FileAddedMessage.php:37