‪TYPO3CMS  ‪main
MvcPropertyMappingConfigurationService.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 
30 
51 {
53 
55  {
56  $this->hashService = ‪$hashService;
57  }
58 
68  public function ‪generateTrustedPropertiesToken($formFieldNames, $fieldNamePrefix = '')
69  {
70  $formFieldArray = [];
71  foreach ($formFieldNames as $formField) {
72  $formFieldParts = explode('[', $formField);
73  $currentPosition = &$formFieldArray;
74  $formFieldPartsCount = count($formFieldParts);
75  for ($i = 0; $i < $formFieldPartsCount; $i++) {
76  $formFieldPart = $formFieldParts[$i];
77  $formFieldPart = rtrim($formFieldPart, ']');
78  if (!is_array($currentPosition)) {
79  throw new ‪InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is declared as array, but it collides with a previous form field of the same name which declared the field as string. This is an inconsistency you need to fix inside your Fluid form. (String overridden by Array)', 1255072196);
80  }
81  if ($i === $formFieldPartsCount - 1) {
82  if (isset($currentPosition[$formFieldPart]) && is_array($currentPosition[$formFieldPart])) {
83  throw new ‪InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is declared as string, but it collides with a previous form field of the same name which declared the field as array. This is an inconsistency you need to fix inside your Fluid form. (Array overridden by String)', 1255072587);
84  }
85  // Last iteration - add a string
86  if ($formFieldPart === '') {
87  $currentPosition[] = 1;
88  } else {
89  $currentPosition[$formFieldPart] = 1;
90  }
91  } else {
92  if ($formFieldPart === '') {
93  throw new ‪InvalidArgumentForHashGenerationException('The form field "' . $formField . '" is invalid. Reason: "[]" used not as last argument, but somewhere in the middle (like foo[][bar]).', 1255072832);
94  }
95  if (!isset($currentPosition[$formFieldPart])) {
96  $currentPosition[$formFieldPart] = [];
97  }
98  $currentPosition = &$currentPosition[$formFieldPart];
99  }
100  }
101  }
102  if ($fieldNamePrefix !== '') {
103  $formFieldArray = ($formFieldArray[$fieldNamePrefix] ?? []);
104  }
105  return $this->‪encodeAndHashFormFieldArray($formFieldArray);
106  }
107 
115  protected function ‪encodeAndHashFormFieldArray(array $formFieldArray)
116  {
117  $encodedFormFieldArray = json_encode($formFieldArray);
118  return $this->hashService->appendHmac($encodedFormFieldArray, HashScope::TrustedProperties->‪prefix());
119  }
120 
127  public function ‪initializePropertyMappingConfigurationFromRequest(‪Request $request, ‪Arguments $controllerArguments)
128  {
130  $extbaseRequestParameters = $request->‪getAttribute('extbase');
131  $trustedPropertiesToken = $extbaseRequestParameters->getInternalArgument('__trustedProperties');
132  if (!is_string($trustedPropertiesToken)) {
133  return;
134  }
135 
136  try {
137  $encodedTrustedProperties = $this->hashService->validateAndStripHmac($trustedPropertiesToken, HashScope::TrustedProperties->‪prefix());
138  } catch (‪InvalidHashStringException $e) {
139  throw new ‪BadRequestException('The HMAC of the form could not be validated.', 1581862822);
140  }
141  $trustedProperties = json_decode($encodedTrustedProperties, true);
142  if (!is_array($trustedProperties)) {
143  if (str_starts_with($encodedTrustedProperties, 'a:')) {
144  throw new ‪BadRequestException('Trusted properties used outdated serialization format instead json.', 1699604555);
145  }
146  throw new ‪BadRequestException('The HMAC of the form could not be utilized.', 1691267306);
147  }
148 
149  foreach ($trustedProperties as $propertyName => $propertyConfiguration) {
150  if (!$controllerArguments->‪hasArgument($propertyName)) {
151  continue;
152  }
153  $propertyMappingConfiguration = $controllerArguments->‪getArgument($propertyName)->‪getPropertyMappingConfiguration();
154  $this->‪modifyPropertyMappingConfiguration($propertyConfiguration, $propertyMappingConfiguration);
155  }
156  }
157 
168  protected function ‪modifyPropertyMappingConfiguration($propertyConfiguration, ‪PropertyMappingConfiguration $propertyMappingConfiguration)
169  {
170  if (!is_array($propertyConfiguration)) {
171  return;
172  }
173 
174  if (isset($propertyConfiguration['__identity'])) {
175  $propertyMappingConfiguration->‪setTypeConverterOption(PersistentObjectConverter::class, ‪PersistentObjectConverter::CONFIGURATION_MODIFICATION_ALLOWED, true);
176  unset($propertyConfiguration['__identity']);
177  } else {
178  $propertyMappingConfiguration->‪setTypeConverterOption(PersistentObjectConverter::class, ‪PersistentObjectConverter::CONFIGURATION_CREATION_ALLOWED, true);
179  }
180 
181  foreach ($propertyConfiguration as $innerKey => $innerValue) {
182  if (is_array($innerValue)) {
183  $this->‪modifyPropertyMappingConfiguration($innerValue, $propertyMappingConfiguration->‪forProperty($innerKey));
184  }
185  $propertyMappingConfiguration->‪allowProperties($innerKey);
186  }
187  }
188 }
‪TYPO3\CMS\Extbase\Mvc\Controller\Arguments\hasArgument
‪bool hasArgument($argumentName)
Definition: Arguments.php:172
‪TYPO3\CMS\Extbase\Mvc\Controller\Arguments\getArgument
‪Argument getArgument($argumentName)
Definition: Arguments.php:157
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration\setTypeConverterOption
‪TYPO3 CMS Extbase Property PropertyMappingConfiguration setTypeConverterOption($typeConverter, $optionKey, $optionValue)
Definition: PropertyMappingConfiguration.php:287
‪TYPO3\CMS\Extbase\Mvc\Controller\Arguments
Definition: Arguments.php:29
‪TYPO3\CMS\Extbase\Mvc\Controller\Argument\getPropertyMappingConfiguration
‪MvcPropertyMappingConfiguration getPropertyMappingConfiguration()
Definition: Argument.php:249
‪TYPO3\CMS\Extbase\Security\Exception\InvalidArgumentForHashGenerationException
Definition: InvalidArgumentForHashGenerationException.php:25
‪TYPO3\CMS\Core\Error\Http\BadRequestException
Definition: BadRequestException.php:24
‪TYPO3\CMS\Extbase\Mvc\Controller
Definition: ActionController.php:16
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration\forProperty
‪TYPO3 CMS Extbase Property PropertyMappingConfiguration forProperty($propertyPath)
Definition: PropertyMappingConfiguration.php:320
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\initializePropertyMappingConfigurationFromRequest
‪initializePropertyMappingConfigurationFromRequest(Request $request, Arguments $controllerArguments)
Definition: MvcPropertyMappingConfigurationService.php:127
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\CONFIGURATION_CREATION_ALLOWED
‪const CONFIGURATION_CREATION_ALLOWED
Definition: PersistentObjectConverter.php:53
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter
Definition: PersistentObjectConverter.php:44
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\injectHashService
‪injectHashService(HashService $hashService)
Definition: MvcPropertyMappingConfigurationService.php:54
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration
Definition: PropertyMappingConfiguration.php:22
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\encodeAndHashFormFieldArray
‪string encodeAndHashFormFieldArray(array $formFieldArray)
Definition: MvcPropertyMappingConfigurationService.php:115
‪TYPO3\CMS\Extbase\Property\TypeConverter\PersistentObjectConverter\CONFIGURATION_MODIFICATION_ALLOWED
‪const CONFIGURATION_MODIFICATION_ALLOWED
Definition: PersistentObjectConverter.php:48
‪TYPO3\CMS\Core\SingletonInterface
Definition: SingletonInterface.php:22
‪TYPO3\CMS\Extbase\Security\HashScope
‪HashScope
Definition: HashScope.php:25
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\generateTrustedPropertiesToken
‪string generateTrustedPropertiesToken($formFieldNames, $fieldNamePrefix='')
Definition: MvcPropertyMappingConfigurationService.php:68
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\modifyPropertyMappingConfiguration
‪modifyPropertyMappingConfiguration($propertyConfiguration, PropertyMappingConfiguration $propertyMappingConfiguration)
Definition: MvcPropertyMappingConfigurationService.php:168
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService
Definition: MvcPropertyMappingConfigurationService.php:51
‪TYPO3\CMS\Extbase\Mvc\Request\getAttribute
‪getAttribute($name, $default=null)
Definition: Request.php:271
‪TYPO3\CMS\Extbase\Mvc\ExtbaseRequestParameters
Definition: ExtbaseRequestParameters.php:35
‪TYPO3\CMS\Extbase\Mvc\Controller\MvcPropertyMappingConfigurationService\$hashService
‪HashService $hashService
Definition: MvcPropertyMappingConfigurationService.php:52
‪TYPO3\CMS\Extbase\Security\prefix
‪@ prefix
Definition: HashScope.php:30
‪TYPO3\CMS\Core\Exception\Crypto\InvalidHashStringException
Definition: InvalidHashStringException.php:25
‪TYPO3\CMS\Core\Crypto\HashService
Definition: HashService.php:28
‪TYPO3\CMS\Extbase\Mvc\Request
Definition: Request.php:35
‪TYPO3\CMS\Extbase\Property\PropertyMappingConfiguration\allowProperties
‪TYPO3 CMS Extbase Property PropertyMappingConfiguration allowProperties()
Definition: PropertyMappingConfiguration.php:141