Passed
Push — master ( 428a99...6f7ef8 )
by
unknown
19:55
created

initializeMfaConfiguration()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 25
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 14
c 1
b 0
f 0
dl 0
loc 25
rs 8.8333
cc 7
nc 7
nop 0
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
18
namespace TYPO3\CMS\Backend\Controller;
19
20
use Psr\Http\Message\ResponseInterface;
21
use Psr\Http\Message\ServerRequestInterface;
22
use TYPO3\CMS\Backend\Routing\UriBuilder;
23
use TYPO3\CMS\Backend\Template\ModuleTemplate;
24
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;
25
use TYPO3\CMS\Core\Authentication\Mfa\MfaProviderRegistry;
26
use TYPO3\CMS\Core\Localization\LanguageService;
27
use TYPO3\CMS\Core\Utility\GeneralUtility;
28
29
/**
30
 * Abstract class for mfa controllers (configuration and authentication)
31
 *
32
 * @internal This class is a specific Backend controller implementation and is not considered part of the Public TYPO3 API.
33
 */
34
abstract class AbstractMfaController
35
{
36
    protected ModuleTemplate $moduleTemplate;
37
    protected UriBuilder $uriBuilder;
38
    protected MfaProviderRegistry $mfaProviderRegistry;
39
    protected array $mfaTsConfig;
40
    protected bool $mfaRequired;
41
    protected array $allowedProviders;
42
    protected array $allowedActions = [];
43
44
    public function __construct(
45
        ModuleTemplate $moduleTemplate,
46
        UriBuilder $uriBuilder,
47
        MfaProviderRegistry $mfaProviderRegistry
48
    ) {
49
        $this->moduleTemplate = $moduleTemplate;
50
        $this->uriBuilder = $uriBuilder;
51
        $this->mfaProviderRegistry = $mfaProviderRegistry;
52
        $this->initializeMfaConfiguration();
53
    }
54
55
    /**
56
     * Main action for handling the request and returning the response
57
     *
58
     * @param ServerRequestInterface $request
59
     * @return ResponseInterface
60
     */
61
    abstract public function handleRequest(ServerRequestInterface $request): ResponseInterface;
62
63
    protected function isActionAllowed(string $action): bool
64
    {
65
        return in_array($action, $this->allowedActions, true);
66
    }
67
68
    protected function isProviderAllowed(string $identifier): bool
69
    {
70
        return isset($this->allowedProviders[$identifier]);
71
    }
72
73
    protected function isValidIdentifier(string $identifier): bool
74
    {
75
        return $identifier !== ''
76
            && $this->isProviderAllowed($identifier)
77
            && $this->mfaProviderRegistry->hasProvider($identifier);
78
    }
79
80
    /**
81
     * Initialize MFA configuration based on TSconfig and global configuration
82
     */
83
    protected function initializeMfaConfiguration(): void
84
    {
85
        $this->mfaTsConfig = $this->getBackendUser()->getTSConfig()['auth.']['mfa.'] ?? [];
86
87
        // Set up required state based on user TSconfig and global configuration
88
        if (isset($this->mfaTsConfig['required'])) {
89
            // user TSconfig overrules global configuration
90
            $this->mfaRequired = (bool)($this->mfaTsConfig['required'] ?? false);
91
        } else {
92
            $globalConfig = (int)($GLOBALS['TYPO3_CONF_VARS']['BE']['requireMfa'] ?? 0);
93
            if ($globalConfig <= 1) {
94
                // 0 and 1 can directly be used by type-casting to boolean
95
                $this->mfaRequired = (bool)$globalConfig;
96
            } else {
97
                // check the admin / non-admin options
98
                $isAdmin = $this->getBackendUser()->isAdmin();
99
                $this->mfaRequired = ($globalConfig === 2 && !$isAdmin) || ($globalConfig === 3 && $isAdmin);
100
            }
101
        }
102
103
        // Set up allowed providers based on user TSconfig and user groupData
104
        $this->allowedProviders = array_filter($this->mfaProviderRegistry->getProviders(), function ($identifier) {
105
            return $this->getBackendUser()->check('mfa_providers', $identifier)
106
                && !GeneralUtility::inList(($this->mfaTsConfig['disableProviders'] ?? ''), $identifier);
107
        }, ARRAY_FILTER_USE_KEY);
108
    }
109
110
    protected function getBackendUser(): BackendUserAuthentication
111
    {
112
        return $GLOBALS['BE_USER'];
113
    }
114
115
    protected function getLanguageService(): LanguageService
116
    {
117
        return $GLOBALS['LANG'];
118
    }
119
}
120