‪TYPO3CMS  ‪main
MfaProviderPropertyManager.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\Log\LoggerAwareInterface;
21 use Psr\Log\LoggerAwareTrait;
27 
32 class ‪MfaProviderPropertyManager implements LoggerAwareInterface
33 {
34  use LoggerAwareTrait;
35 
36  protected array ‪$mfa;
37  protected array ‪$providerProperties;
38  protected const ‪DATABASE_FIELD_NAME = 'mfa';
39 
40  public function ‪__construct(protected readonly ‪AbstractUserAuthentication $user, protected readonly string $providerIdentifier)
41  {
42  $this->mfa = json_decode($user->user[self::DATABASE_FIELD_NAME] ?? '', true) ?? [];
43  $this->providerProperties = $this->mfa[$this->providerIdentifier] ?? [];
44  }
45 
49  public function ‪hasProviderEntry(): bool
50  {
51  return isset($this->mfa[$this->providerIdentifier]);
52  }
53 
57  public function ‪hasProperty(string $key): bool
58  {
59  return isset($this->providerProperties[$key]);
60  }
61 
66  public function ‪getProperty(string $key, mixed $default = null): mixed
67  {
68  return $this->providerProperties[$key] ?? $default;
69  }
70 
74  public function ‪getProperties(): array
75  {
77  }
78 
84  public function ‪updateProperties(array $properties): bool
85  {
86  // This is to prevent provider data inconsistency
87  if (!$this->‪hasProviderEntry()) {
88  throw new \InvalidArgumentException(
89  'No entry for provider ' . $this->providerIdentifier . ' exists yet. Use createProviderEntry() instead.',
90  1613993188
91  );
92  }
93 
94  if (!isset($properties['updated'])) {
95  $properties['updated'] = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');
96  }
97 
98  $this->providerProperties = array_replace($this->providerProperties, $properties);
99  $this->mfa[$this->providerIdentifier] = ‪$this->providerProperties;
100  return $this->‪storeProperties();
101  }
102 
108  public function ‪createProviderEntry(array $properties): bool
109  {
110  // This is to prevent unintentional overwriting of provider entries
111  if ($this->‪hasProviderEntry()) {
112  throw new \InvalidArgumentException(
113  'A entry for provider ' . $this->providerIdentifier . ' already exists. Use updateProperties() instead.',
114  1612781782
115  );
116  }
117 
118  if (!isset($properties['created'])) {
119  $properties['created'] = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');
120  }
121 
122  if (!isset($properties['updated'])) {
123  $properties['updated'] = GeneralUtility::makeInstance(Context::class)->getPropertyFromAspect('date', 'timestamp');
124  }
125 
126  $this->providerProperties = $properties;
127  $this->mfa[$this->providerIdentifier] = ‪$this->providerProperties;
128  return $this->‪storeProperties();
129  }
130 
136  public function ‪deleteProviderEntry(): bool
137  {
138  $this->providerProperties = [];
139  unset($this->mfa[$this->providerIdentifier]);
140  return $this->‪storeProperties();
141  }
142 
148  protected function ‪storeProperties(): bool
149  {
150  // encode the mfa properties to store them in the database and the user array
151  ‪$mfa = json_encode($this->mfa, JSON_THROW_ON_ERROR) ?: '';
152 
153  // Write back the updated mfa properties to the user array
154  $this->user->user[‪self::DATABASE_FIELD_NAME] = ‪$mfa;
155 
156  // Log MFA update
157  $this->logger->debug('MFA properties updated', [
158  'provider' => $this->providerIdentifier,
159  'user' => [
160  'uid' => $this->user->getUserId(),
161  'username' => $this->user->getUserName(),
162  ],
163  ]);
164 
165  // Store updated mfa properties in the database
166  return (bool)GeneralUtility::makeInstance(ConnectionPool::class)->getConnectionForTable($this->user->user_table)->update(
167  $this->user->user_table,
168  [self::DATABASE_FIELD_NAME => ‪$mfa],
169  [$this->user->userid_column => (int)$this->user->getUserId()],
170  [self::DATABASE_FIELD_NAME => ‪Connection::PARAM_LOB]
171  );
172  }
173 
178  {
179  return $this->user;
180  }
181 
185  public function ‪getIdentifier(): string
186  {
187  return $this->providerIdentifier;
188  }
189 
193  public static function ‪create(‪MfaProviderManifestInterface $provider, ‪AbstractUserAuthentication $user): self
194  {
195  return GeneralUtility::makeInstance(self::class, $user, $provider->‪getIdentifier());
196  }
197 }
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\DATABASE_FIELD_NAME
‪const DATABASE_FIELD_NAME
Definition: MfaProviderPropertyManager.php:38
‪TYPO3\CMS\Core\Authentication\Mfa
Definition: MfaProviderInterface.php:18
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\hasProperty
‪hasProperty(string $key)
Definition: MfaProviderPropertyManager.php:57
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\$mfa
‪array $mfa
Definition: MfaProviderPropertyManager.php:36
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\__construct
‪__construct(protected readonly AbstractUserAuthentication $user, protected readonly string $providerIdentifier)
Definition: MfaProviderPropertyManager.php:40
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifestInterface
Definition: MfaProviderManifestInterface.php:26
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\getProperty
‪getProperty(string $key, mixed $default=null)
Definition: MfaProviderPropertyManager.php:66
‪TYPO3\CMS\Core\Context\Context
Definition: Context.php:54
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\$providerProperties
‪array $providerProperties
Definition: MfaProviderPropertyManager.php:37
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\getIdentifier
‪getIdentifier()
Definition: MfaProviderPropertyManager.php:185
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\deleteProviderEntry
‪deleteProviderEntry()
Definition: MfaProviderPropertyManager.php:136
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\getUser
‪getUser()
Definition: MfaProviderPropertyManager.php:177
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\create
‪static create(MfaProviderManifestInterface $provider, AbstractUserAuthentication $user)
Definition: MfaProviderPropertyManager.php:193
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\createProviderEntry
‪createProviderEntry(array $properties)
Definition: MfaProviderPropertyManager.php:108
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager
Definition: MfaProviderPropertyManager.php:33
‪TYPO3\CMS\Core\Database\Connection
Definition: Connection.php:41
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\hasProviderEntry
‪hasProviderEntry()
Definition: MfaProviderPropertyManager.php:49
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderManifestInterface\getIdentifier
‪getIdentifier()
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\updateProperties
‪updateProperties(array $properties)
Definition: MfaProviderPropertyManager.php:84
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\storeProperties
‪storeProperties()
Definition: MfaProviderPropertyManager.php:148
‪TYPO3\CMS\Core\Database\ConnectionPool
Definition: ConnectionPool.php:46
‪TYPO3\CMS\Core\Utility\GeneralUtility
Definition: GeneralUtility.php:52
‪TYPO3\CMS\Core\Authentication\AbstractUserAuthentication
Definition: AbstractUserAuthentication.php:65
‪TYPO3\CMS\Core\Authentication\Mfa\MfaProviderPropertyManager\getProperties
‪getProperties()
Definition: MfaProviderPropertyManager.php:74
‪TYPO3\CMS\Core\Database\Connection\PARAM_LOB
‪const PARAM_LOB
Definition: Connection.php:62