TYPO3 CMS  TYPO3_8-7
FormDefinitionValidationService.php
Go to the documentation of this file.
1 <?php
2 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 
29 
34 {
35 
40 
132  array $currentFormElement,
133  string $prototypeName,
134  string $sessionToken
135  ) {
136  $renderables = $currentFormElement['renderables'] ?? [];
137  $propertyCollectionElements = $currentFormElement['finishers'] ?? $currentFormElement['validators'] ?? [];
138  $propertyCollectionName = $currentFormElement['type'] === 'Form' ? 'finishers' : 'validators';
139  unset($currentFormElement['renderables'], $currentFormElement['finishers'], $currentFormElement['validators']);
140 
141  $validationDto = GeneralUtility::makeInstance(
142  ValidationDto::class,
143  $prototypeName,
144  $currentFormElement['type'],
145  $currentFormElement['identifier'],
146  null,
147  $propertyCollectionName
148  );
149 
150  if ($this->getConfigurationService()->isFormElementTypeCreatableByFormEditor($validationDto)) {
152  $currentFormElement,
153  $sessionToken,
154  $validationDto
155  );
156 
157  foreach ($propertyCollectionElements as $propertyCollectionElement) {
158  $validationDto = $validationDto->withPropertyCollectionElementIdentifier(
159  $propertyCollectionElement['identifier']
160  );
161 
162  if ($this->getConfigurationService()->isPropertyCollectionElementIdentifierCreatableByFormEditor($validationDto)) {
164  $propertyCollectionElement,
165  $sessionToken,
166  $validationDto
167  );
168  } else {
170  $propertyCollectionElement,
171  $sessionToken,
172  $validationDto
173  );
174  }
175  }
176  } else {
177  $this->validateAllFormElementPropertyValuesByHmac($currentFormElement, $sessionToken, $validationDto);
178 
179  foreach ($propertyCollectionElements as $propertyCollectionElement) {
181  $propertyCollectionElement,
182  $sessionToken,
183  $validationDto
184  );
185  }
186  }
187 
188  foreach ($renderables as $renderable) {
189  $this->validateFormDefinitionProperties($renderable, $prototypeName, $sessionToken);
190  }
191  }
192 
213  array $hmacContent,
214  $propertyValue,
215  array $hmacData,
216  string $sessionToken
217  ): bool {
218  $this->checkHmacDataIntegrity($hmacData, $hmacContent, $sessionToken);
219  $hmacContent[] = $propertyValue;
220 
221  $expectedHash = GeneralUtility::hmac(serialize($hmacContent), $sessionToken);
222  return hash_equals($expectedHash, $hmacData['hmac']);
223  }
224 
235  protected function checkHmacDataIntegrity(array $hmacData, array $hmacContent, string $sessionToken)
236  {
237  $hmac = $hmacData['hmac'] ?? null;
238  if (empty($hmac)) {
239  throw new PropertyException('Hmac must not be empty. #1528538222', 1528538222);
240  }
241 
242  $hmacContent[] = $hmacData['value'] ?? '';
243  $expectedHash = GeneralUtility::hmac(serialize($hmacContent), $sessionToken);
244 
245  if (!hash_equals($expectedHash, $hmac)) {
246  throw new PropertyException('Unauthorized modification of historical data. #1528538252', 1528538252);
247  }
248  }
249 
259  array $currentElement,
260  $sessionToken,
261  ValidationDto $validationDto
262  ) {
263  GeneralUtility::makeInstance(ArrayProcessor::class, $currentElement)->forEach(
265  ArrayProcessing::class,
266  'validateProperties',
267  '^(?!(_orig_.*|.*\._orig_.*)$).*',
269  FormElementHmacDataValidator::class,
270  $currentElement,
271  $sessionToken,
272  $validationDto
273  )
274  )
275  );
276  }
277 
287  array $currentElement,
288  $sessionToken,
289  ValidationDto $validationDto
290  ) {
291  GeneralUtility::makeInstance(ArrayProcessor::class, $currentElement)->forEach(
293  ArrayProcessing::class,
294  'validateProperties',
295  '^(?!(_orig_.*|.*\._orig_.*)$).*',
297  PropertyCollectionElementHmacDataValidator::class,
298  $currentElement,
299  $sessionToken,
300  $validationDto
301  )
302  )
303  );
304  }
305 
318  array $currentElement,
319  $sessionToken,
320  ValidationDto $validationDto
321  ) {
322  GeneralUtility::makeInstance(ArrayProcessor::class, $currentElement)->forEach(
324  ArrayProcessing::class,
325  'validateProperties',
326  '^(?!(_orig_.*|.*\._orig_.*|type|identifier)$).*',
328  CreatableFormElementPropertiesValidator::class,
329  $currentElement,
330  $sessionToken,
331  $validationDto
332  )
333  )
334  );
335  }
336 
349  array $currentElement,
350  $sessionToken,
351  ValidationDto $validationDto
352  ) {
353  GeneralUtility::makeInstance(ArrayProcessor::class, $currentElement)->forEach(
355  ArrayProcessing::class,
356  'validateProperties',
357  '^(?!(_orig_.*|.*\._orig_.*|identifier)$).*',
359  CreatablePropertyCollectionElementPropertiesValidator::class,
360  $currentElement,
361  $sessionToken,
362  $validationDto
363  )
364  )
365  );
366  }
367 
372  {
373  if (!($this->configurationService instanceof ConfigurationService)) {
374  $this->configurationService = $this->getObjectManager()->get(ConfigurationService::class);
375  }
377  }
378 
382  protected function getObjectManager(): ObjectManager
383  {
384  return GeneralUtility::makeInstance(ObjectManager::class);
385  }
386 }
validateAllPropertyCollectionElementValuesByHmac(array $currentElement, $sessionToken, ValidationDto $validationDto)
isPropertyValueEqualToHistoricalValue(array $hmacContent, $propertyValue, array $hmacData, string $sessionToken)
validateAllPropertyValuesFromCreatableFormElement(array $currentElement, $sessionToken, ValidationDto $validationDto)
validateAllPropertyValuesFromCreatablePropertyCollectionElement(array $currentElement, $sessionToken, ValidationDto $validationDto)
static hmac($input, $additionalSecret='')
static makeInstance($className,... $constructorArguments)
validateFormDefinitionProperties(array $currentFormElement, string $prototypeName, string $sessionToken)
checkHmacDataIntegrity(array $hmacData, array $hmacContent, string $sessionToken)
validateAllFormElementPropertyValuesByHmac(array $currentElement, $sessionToken, ValidationDto $validationDto)