‪TYPO3CMS  ‪main
ModelService.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 
21 
28 {
29  private const ‪SOURCE_PARSING_PRIORITIES = [
30  HashProxy::class => 50,
31  HashValue::class => 50,
32  ];
33 
37  public function ‪__construct(private readonly ?‪FrontendInterface $cache = null) {}
38 
40  {
41  return new ‪MutationSuggestion(
42  $this->‪buildMutationCollectionFromArray($array['collection'] ?? []),
43  (string)($array['identifier'] ?? ''),
44  isset($array['priority']) ? (int)$array['priority'] : null,
45  $array['label'] ?? null
46  );
47  }
48 
50  {
51  $mutations = array_map(
52  [$this, 'buildMutationFromArray'],
53  $array['mutations'] ?? []
54  );
55  return new ‪MutationCollection(...$mutations);
56  }
57 
58  public function ‪buildMutationFromArray(array $array): ‪Mutation
59  {
60  return new ‪Mutation(
61  MutationMode::from($array['mode'] ?? ''),
62  Directive::from($array['directive'] ?? ''),
63  ...$this->‪buildSourcesFromItems(...($array['sources'] ?? []))
64  );
65  }
66 
67  public function ‪buildSourcesFromItems(string ...$items): array
68  {
69  $sources = [];
70  foreach ($items as $item) {
71  $source = $this->‪buildSourceFromString($item);
72  if ($source === null) {
73  throw new \InvalidArgumentException(
74  sprintf('Could not convert source item "%s"', $item),
75  1677261214
76  );
77  }
78  $sources[] = $source;
79  }
80  return $sources;
81  }
82 
83  public function ‪buildSourceFromString(string $string): ?‪SourceInterface
84  {
85  if (str_starts_with($string, "'nonce-") && $string[-1] === "'") {
86  // use a proxy instead of a real Nonce instance
87  return SourceKeyword::nonceProxy;
88  }
89  try {
90  if ($string[0] === "'" && $string[-1] === "'") {
91  return SourceKeyword::from(substr($string, 1, -1));
92  }
93  if ($string[-1] === ':') {
94  return SourceScheme::from(substr($string, 0, -1));
95  }
96  return new ‪UriValue($string);
97  } catch (\InvalidArgumentException|\ValueError) {
98  // no handling here
99  }
101  foreach ($this->‪resolvePrioritizedSourceInterfaces() as $sourceInterface) {
102  if ($sourceInterface::knows($string)) {
103  return $sourceInterface::parse($string);
104  }
105  }
106  return new ‪RawValue($string);
107  }
108 
109  // @todo use SourceCollection instead?
110  public function ‪serializeSources(‪SourceInterface ...$sources): array
111  {
112  $serialized = [];
113  foreach ($sources as $source) {
114  if ($source instanceof ‪SourceKeyword && $source->vetoes()) {
115  $serialized = [];
116  }
117  $serialized[] = $this->‪serializeSource($source);
118  }
119  return $serialized;
120  }
121 
122  public function ‪compileSources(‪ConsumableNonce $nonce, ‪SourceCollection $collection): array
123  {
124  $compiled = [];
125  foreach ($collection->sources as $source) {
126  if ($source instanceof ‪SourceKeyword && $source->vetoes()) {
127  $compiled = [];
128  }
129  if ($source instanceof ‪SourceValueInterface) {
130  $compiled[] = $source->compile($this->cache);
131  } else {
132  $compiled[] = $this->‪serializeSource($source, $nonce);
133  }
134  }
135  return array_filter($compiled);
136  }
137 
141  public function ‪serializeSource(‪SourceInterface $source, ?‪ConsumableNonce $nonce = null): string
142  {
143  if ($source === SourceKeyword::nonceProxy && $nonce !== null) {
144  return $nonce->count() > 0 ? "'nonce-" . $nonce->value . "'" : '';
145  }
146  if ($source instanceof ‪SourceKeyword) {
147  return "'" . $source->value . "'";
148  }
149  if ($source instanceof ‪SourceScheme) {
150  return $source->value . ':';
151  }
152  if ($source instanceof ‪SourceValueInterface) {
153  return $source->serialize();
154  }
155  if ($source instanceof \Stringable) {
156  return (string)$source;
157  }
158  return '';
159  }
160 
165  private function ‪resolvePrioritizedSourceInterfaces(): array
166  {
168  arsort($interfaces);
169  return array_keys($interfaces);
170  }
171 }
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\resolvePrioritizedSourceInterfaces
‪list< class-string< SourceValueInterface > > resolvePrioritizedSourceInterfaces()
Definition: ModelService.php:165
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\SOURCE_PARSING_PRIORITIES
‪const SOURCE_PARSING_PRIORITIES
Definition: ModelService.php:29
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceValueInterface
Definition: SourceValueInterface.php:31
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceCollection
Definition: SourceCollection.php:27
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\compileSources
‪compileSources(ConsumableNonce $nonce, SourceCollection $collection)
Definition: ModelService.php:122
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\RawValue
Definition: RawValue.php:27
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\buildMutationSuggestionFromArray
‪buildMutationSuggestionFromArray(array $array)
Definition: ModelService.php:39
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService
Definition: ModelService.php:28
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ConsumableNonce
Definition: ConsumableNonce.php:24
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\serializeSources
‪serializeSources(SourceInterface ... $sources)
Definition: ModelService.php:110
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\buildMutationCollectionFromArray
‪buildMutationCollectionFromArray(array $array)
Definition: ModelService.php:49
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceInterface
Definition: SourceInterface.php:27
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\buildSourcesFromItems
‪buildSourcesFromItems(string ... $items)
Definition: ModelService.php:67
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\buildSourceFromString
‪buildSourceFromString(string $string)
Definition: ModelService.php:83
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationSuggestion
Definition: MutationSuggestion.php:29
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy
Definition: ConsumableNonce.php:18
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\__construct
‪__construct(private readonly ?FrontendInterface $cache=null)
Definition: ModelService.php:37
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceKeyword
‪SourceKeyword
Definition: SourceKeyword.php:25
‪TYPO3\CMS\Core\Cache\Frontend\FrontendInterface
Definition: FrontendInterface.php:22
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\UriValue
Definition: UriValue.php:29
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\SourceScheme
‪SourceScheme
Definition: SourceScheme.php:25
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\Mutation
Definition: Mutation.php:26
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\MutationCollection
Definition: MutationCollection.php:24
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\buildMutationFromArray
‪buildMutationFromArray(array $array)
Definition: ModelService.php:58
‪TYPO3\CMS\Core\Security\ContentSecurityPolicy\ModelService\serializeSource
‪serializeSource(SourceInterface $source, ?ConsumableNonce $nonce=null)
Definition: ModelService.php:141