Modules::addRequiredPhpModule()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\monitor\TestSuite;
6
7
use SimpleSAML\Module;
8
use SimpleSAML\Module\monitor\TestConfiguration;
9
use SimpleSAML\Module\monitor\State;
10
use SimpleSAML\Module\monitor\TestCase;
11
use SimpleSAML\Module\monitor\TestData;
12
use SimpleSAML\Module\monitor\TestResult;
13
use SimpleSAML\Utils;
14
15
use function array_key_exists;
16
use function function_exists;
17
use function in_array;
18
use function preg_match;
19
20
class Modules extends \SimpleSAML\Module\monitor\TestSuiteFactory
21
{
22
    /** @var array */
23
    private array $requiredApacheModules = [];
24
25
    // Important!!  Modules-names are handled case-sensitive!!
26
    /** @var array */
27
    private array $storeApacheDependencies = [];
28
29
    /** @var array */
30
    private array $moduleApacheDependencies = [
31
        'negotiateext' => 'mod_auth_kerb|mod_auth_gssapi'
32
    ];
33
34
    /** @var array */
35
    private array $requiredPhpModules = [];
36
37
    /** @var array */
38
    private array $storePhpDependencies = [
39
        'memcache' => 'memcached|memcache',
40
        'phpsession' => 'session',
41
        'sql' => 'PDO'
42
    ];
43
44
    /** @var array */
45
    private array $modulePhpDependencies = [
46
        'authfacebook' => ['curl', 'json'],
47
        'authYubiKey' => 'curl',
48
// TODO: consent only requires pdo when database backend is used..
49
//       Should probably add this to required-list when processing metadata
50
//        'consent' => 'PDO',
51
        'consentAdmin' => 'PDO',
52
        'ldap' => 'ldap',
53
        'memcacheMonitor' => 'memcached|memcache',
54
        'negotiate' => 'krb5',
55
        'radius' => 'radius',
56
        'sqlauth' => 'PDO'
57
    ];
58
59
60
    /**
61
     * @param \SimpleSAML\Module\monitor\TestData|null $testData
62
     *
63
     * @return void
64
     */
65
    protected function initialize(TestData $testData = null): void
66
    {
67
        $this->setRequiredApacheModules();
68
        $this->setRequiredPhpModules();
69
        $this->setRequiredSspModules();
70
        $this->setCategory('Modules');
71
72
        parent::initialize($testData);
73
    }
74
75
76
    /**
77
     * @param string $module
78
     *
79
     * @return void
80
     */
81
    private function addRequiredApacheModule(string $module): void
82
    {
83
        if (!in_array($module, $this->requiredApacheModules)) {
84
            $this->requiredApacheModules[] = $module;
85
        }
86
    }
87
88
89
    /**
90
     * @return void
91
     */
92
    private function setRequiredApacheModules(): void
93
    {
94
        // Apache Modules
95
        if (function_exists('apache_get_modules')) {
96
            $this->addRequiredApacheModule('mod_php|mod_php5|mod_php7');
97
        }
98
99
        $httpUtils = new Utils\HTTP();
100
        if ($httpUtils->isHTTPS()) {
101
            $this->addRequiredApacheModule('mod_ssl');
102
        }
103
104
        // Determine extra required modules
105
        $configuration = $this->getConfiguration();
106
        $globalConfig = $configuration->getGlobalConfig();
107
        $store = $globalConfig->getOptionalValue('store.type', 'phpsession');
108
        if (array_key_exists($store, $this->storeApacheDependencies)) {
109
            $this->addRequiredApacheModule($this->storeApacheDependencies[$store]);
110
        }
111
    }
112
113
114
    /**
115
     * @param string $module
116
     *
117
     * @return void
118
     */
119
    private function addRequiredPhpModule(string $module): void
120
    {
121
        if (!in_array($module, $this->requiredPhpModules)) {
122
            $this->requiredPhpModules[] = $module;
123
        }
124
    }
125
126
127
    /**
128
     * @return void
129
     */
130
    private function setRequiredPhpModules(): void
131
    {
132
        // PHP modules required
133
        $sysUtils = new Utils\System();
134
        $composerFile = $sysUtils->resolvePath('composer.json');
135
        $composerData = file_get_contents($composerFile);
136
        $composer = json_decode($composerData, true);
137
        $composerRequired = $composer['require'];
138
139
        foreach ($composerRequired as $ext => $ver) {
140
            if (preg_match('/^ext-/', $ext)) {
141
                $this->addRequiredPhpModule(substr($ext, 4));
142
            }
143
        }
144
145
        // Determine extra required modules
146
        $configuration = $this->getConfiguration();
147
        $globalConfig = $configuration->getGlobalConfig();
148
        $store = $globalConfig->getOptionalValue('store.type', 'phpsession');
149
        if (array_key_exists($store, $this->storePhpDependencies)) {
150
            $this->addRequiredPhpModule($this->storePhpDependencies[$store]);
151
        }
152
    }
153
154
155
    /**
156
     * @return void
157
     */
158
    private function setRequiredSspModules(): void
159
    {
160
        $arrayUtils = new Utils\Arrays();
161
162
        $modules = Module::getModules();
163
        foreach ($modules as $module) {
164
            if (Module::isModuleEnabled($module)) {
165
                if (array_key_exists($module, $this->moduleApacheDependencies)) {
166
                    $dependencies = $arrayUtils->arrayize($this->moduleApacheDependencies[$module]);
167
                    foreach ($dependencies as $dependency) {
168
                        $this->addRequiredApacheModule($dependency);
169
                    }
170
                }
171
                if (array_key_exists($module, $this->modulePhpDependencies)) {
172
                    $dependencies = $arrayUtils->arrayize($this->modulePhpDependencies[$module]);
173
                    foreach ($dependencies as $dependency) {
174
                        $this->addRequiredPhpModule($dependency);
175
                    }
176
                }
177
            }
178
        }
179
    }
180
181
182
    /**
183
     * @return array
184
     */
185
    public function getAvailableApacheModules(): array
186
    {
187
        $configuration = $this->getConfiguration();
188
        return $configuration->getAvailableApacheModules();
189
    }
190
191
192
    /**
193
     * @return array
194
     */
195
    public function getAvailablePhpModules(): array
196
    {
197
        $configuration = $this->getConfiguration();
198
        return $configuration->getAvailablePhpModules();
199
    }
200
201
202
    /**
203
     * @return array
204
     */
205
    private function getRequiredApacheModules(): array
206
    {
207
        return $this->requiredApacheModules;
208
    }
209
210
211
    /**
212
     * @return array
213
     */
214
    private function getRequiredPhpModules(): array
215
    {
216
        return $this->requiredPhpModules;
217
    }
218
219
220
    /**
221
     * @return void
222
     */
223
    public function invokeTest(): void
224
    {
225
        $configuration = $this->getConfiguration();
226
227
        // Test Apache modules
228
        $testData = new TestData([
229
            'available' => $configuration->getAvailableApacheModules(),
230
            'required' => $this->getRequiredApacheModules(),
231
            'dependencies' => $this->moduleApacheDependencies,
232
            'type' => 'Apache',
233
        ]);
234
        $apacheTest = new Modules\ModuleSet($configuration, $testData);
235
        $apacheTestResult = $apacheTest->getTestResult();
236
237
         // Test Php modules
238
        $testData = new TestData([
239
            'available' => $configuration->getAvailablePhpModules(),
240
            'required' => $this->getRequiredPhpModules(),
241
            'dependencies' => $this->modulePhpDependencies,
242
            'type' => 'Php',
243
        ]);
244
        $phpTest = new Modules\ModuleSet($configuration, $testData);
245
        $phpTestResult = $phpTest->getTestResult();
246
247
        $this->addTestResult($apacheTestResult);
248
        $this->addTestResult($phpTestResult);
249
250
        $testResult = new TestResult('Modules', '');
251
        $testResult->setState($this->calculateState());
252
253
        $this->setTestResult($testResult);
254
    }
255
}
256