Passed
Branch master (4b23d6)
by Tim
04:40
created

Store::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 4
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 1
1
<?php
2
3
namespace SimpleSAML\Module\Monitor\TestSuite;
4
5
use SimpleSAML\Logger;
6
use SimpleSAML\Module\Monitor\TestConfiguration;
7
use SimpleSAML\Module\Monitor\State;
8
use SimpleSAML\Module\Monitor\TestCase;
9
use SimpleSAML\Module\Monitor\TestData;
10
11
final class Store extends \SimpleSAML\Module\Monitor\TestSuiteFactory
12
{
13
    /** var string|null */
14
    private $store = null;
15
16
17
    /**
18
     * @param \SimpleSAML\Module\Monitor\TestConfiguration $configuration
19
     */
20
    public function __construct(TestConfiguration $configuration)
21
    {
22
        $globalConfig = $configuration->getGlobalConfig();
23
        $this->store = $globalConfig->getString('store.type', 'phpsession');
24
        $this->setCategory('Session store');
25
26
        parent::__construct($configuration);
27
    }
28
29
30
    /**
31
     * @return void
32
     */
33
    public function invokeTest(): void
34
    {
35
        $configuration = $this->getConfiguration();
36
37
        if ($this->store === 'phpsession') {
38
            $results = $this->testPhpSession($configuration);
39
        } else {
40
            $results = $this->testSspSession($configuration);
41
        }
42
43
        foreach ($results as $result) {
44
            $this->addTestResult($result);
45
        }
46
        $this->calculateState();
47
    }
48
49
50
    /**
51
     * @param \SimpleSAML\Module\Monitor\TestConfiguration $configuration
52
     *
53
     * @return array
54
     */
55
    private function testSspSession(TestConfiguration $configuration): array
56
    {
57
        $results = [];
58
59
        switch ($this->store) {
60
            case 'memcache':
61
                $test = new Store\Memcache($configuration);
62
                $results = $test->getTestResults();
63
                break;
64
//          case 'redis':
65
//          case 'redissentinel':
66
//              $test = new Store\Redis($configuration);
67
//              break;
68
            case 'sql':
69
                $test = new Store\Sql($configuration);
70
                $results = $test->getTestResults();
71
                break;
72
            default:
73
                Logger::warning("Not implemented;  $this->store - Skipping Store TestSuite.");
74
                break;
75
        }
76
        return $results;
77
    }
78
79
80
    /**
81
     * @param \SimpleSAML\Module\Monitor\TestConfiguration $configuration
82
     *
83
     * @return array
84
     */
85
    private function testPhpSession(TestConfiguration $configuration): array
86
    {
87
        $results = [];
88
        switch (ini_get('session.save_handler')) {
89
            case 'files':
90
                $input = [
91
                    'path' => session_save_path(),
92
                    'category' => 'Session storage'
93
                ];
94
                $testData = new TestData($input);
95
                $test = new TestCase\FileSystem\FreeSpace($testData);
96
                $results[] = $test->getTestResult();
97
                break;
98
            case 'memcache':
99
            case 'memcached':
100
                $tmp_configuration = \SimpleSAML\Configuration::getInstance();
101
                $tmp_configuration = $tmp_configuration->toArray();
102
                $tmp_configuration['memcache_store.servers'] = $this->parsePhpMemcachedConfiguration(
103
                    session_save_path()
104
                );
105
                $tmp_configuration = \SimpleSAML\Configuration::loadFromArray($tmp_configuration);
106
                \SimpleSAML\Configuration::setPreloadedConfig($tmp_configuration);
107
108
                $test = new Store\Memcache($configuration);
109
                $results = $test->getTestResults();
110
111
                \SimpleSAML\Configuration::setPreloadedConfig($configuration->getGlobalConfig());
112
                break;
113
//          case 'sqlite':
114
//          case 'mm':
115
            default:
116
                Logger::warning("Not implemented;  $this->store - Skipping Store TestSuite.");
117
                break;
118
        }
119
        return $results;
120
    }
121
122
123
    /**
124
     * @param string $spec
125
     *
126
     * @return array
127
     */
128
    private function parsePhpMemcachedConfiguration(string $spec): array
129
    {
130
        $servers = preg_split('/\s*,\s*/', $spec);
131
132
        $results = [];
133
        foreach ($servers as $server) {
134
            $result = [];
135
            @list($host, $params) = explode('?', $server);
136
            @list($hostname, $port) = explode(':', $host);
137
138
            // Strip protocol when possible (memcache)
139
            $prefix = 'tcp://';
140
            if (substr($hostname, 0, 6) === $prefix) {
141
                $hostname = substr($hostname, 6);
142
            }
143
144
            $result['hostname'] = $hostname;
145
            /** @psalm-suppress RedundantCondition  Remove for Psalm >= 3.6.3 */
146
            if (isset($port)) {
147
                $result['port'] = $port;
148
                unset($port);
149
            }
150
            parse_str($params, $tmp);
151
            $results[]  = array_merge($result, $tmp);
152
        }
153
154
        return [$results];
155
    }
156
}
157