Passed
Push — master ( 8d1c07...b7565e )
by Tim
01:44
created

Ldap   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 152
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
dl 0
loc 152
rs 10
c 0
b 0
f 0
wmc 14

3 Methods

Rating   Name   Duplication   Size   Complexity  
B invokeTest() 0 70 6
B prepareConnection() 0 26 6
A __construct() 0 16 2
1
<?php
2
3
namespace SimpleSAML\Module\monitor\TestSuite\AuthSource;
4
5
use \SimpleSAML\Module\monitor\State as State;
6
use \SimpleSAML\Module\monitor\TestConfiguration as TestConfiguration;
7
use \SimpleSAML\Module\monitor\TestCase as TestCase;
8
use \SimpleSAML\Module\monitor\TestData as TestData;
9
use \SimpleSAML\Module\monitor\TestResult as TestResult;
10
11
final class Ldap extends \SimpleSAML\Module\monitor\TestSuiteFactory
12
{
13
    /**
14
     * @var array
15
     */
16
    private $authSourceData;
17
18
    /**
19
     * @var array|null
20
     */
21
    private $authSourceSpecifics;
22
23
    /**
24
     * @var string[]
25
     */
26
    private $hosts;
27
28
    /**
29
     * @param integer|null;
30
     */
31
    private $certExpirationWarning = null;
32
33
    /**
34
     * @param TestConfiguration $configuration
35
     * @param TestData $testData
36
     */
37
    public function __construct($configuration, $testData)
38
    {
39
        $moduleConfig = $configuration->getModuleConfig();
40
        $authSourceData = $testData->getInputItem('authSourceData');
41
        $authSourceSpecifics = $testData->getInputItem('authSourceSpecifics');
42
43
        assert(is_array($authSourceData));
44
        assert(is_array($authSourceSpecifics) || is_null($authSourceSpecifics));
45
46
        $this->hosts = explode(' ', $authSourceData['hostname']);
47
        $this->authSourceData = $authSourceData;
48
        $this->authSourceSpecifics = $authSourceSpecifics;
49
        $this->certExpirationWarning = $moduleConfig->getValue('certExpirationWarning', 28);
50
        $this->setCategory('LDAP authentication source');
51
52
        parent::__construct($configuration);
53
    }
54
55
    /**
56
     * @return void
57
     */
58
    public function invokeTest()
59
    {
60
        // Test LDAP configuration
61
        $confTest = new TestCase\AuthSource\Ldap\Configuration(
62
            new TestData(['authSourceData' => $this->authSourceData])
63
        );
64
        $confTestResult = $confTest->getTestResult();
65
        $this->addTestResult($confTestResult);
66
67
        if ($confTestResult->getState() === State::OK) {
68
            $connection = $confTestResult->getOutput('connection');
69
70
            // Test connection for each configured LDAP-server
71
            foreach ($this->hosts as $hostname) {
72
                $preparedTestData = $this->prepareConnection($hostname, $this->authSourceData, $this->authSourceSpecifics);
73
                $connTest = new TestCase\Network\ConnectUri(
74
                    new TestData($preparedTestData)
75
                );
76
                $connTestResult = $connTest->getTestResult();
77
                $this->addTestResult($connTestResult);
78
79
                if ($connTestResult->getState() === State::OK) {
80
                    $certData = $connTestResult->getOutput('certData');
81
82
                    // Test certificate when available
83
                    if ($certData !== null) {
84
                        $certTest = new TestCase\Cert(
85
                            new TestData([
86
                                'certData' => $certData,
87
                                'category' => 'LDAP Server Certificate',
88
                                'certExpirationWarning' => $this->certExpirationWarning,
89
                            ])
90
                        );
91
                        $certTestResult = $certTest->getTestResult();
92
                        $this->addTestResult($certTestResult);
93
                    }
94
                }
95
            }
96
97
            // Test bind
98
            $testData = new TestData([
99
                'authSourceData' => $this->authSourceData,
100
                'connection' => $connection
101
            ]);
102
            $bindTest = new TestCase\AuthSource\Ldap\Bind(
103
                $testData
104
            );
105
            $bindTestResult = $bindTest->getTestResult();
106
            $this->addTestResult($bindTestResult);
107
108
            if ($bindTestResult->getState() === State::OK) {
109
                // Test search
110
                $testData = new TestData([
111
                    'authSourceData' => $this->authSourceData,
112
                    'connection' => $connection
113
                ]);
114
115
                $searchTest = new TestCase\AuthSource\Ldap\Search(
116
                    $testData
117
                );
118
                $searchTestResult = $searchTest->getTestResult();
119
                $this->addTestResult($searchTestResult);
120
            }
121
        }
122
123
        $state = $this->calculateState();
124
125
        $testResult = new TestResult('LDAP Authentication');
126
        $testResult->setState($state);
127
        $this->setTestResult($testResult);
128
    }
129
130
    /**
131
     * @param string $connectString
132
     * @param array $authSourceData
133
     * @param array|null $authSourceSpecifics
134
     *
135
     * @return array
136
     */
137
    private function prepareConnection($connectString, $authSourceData, $authSourceSpecifics)
138
    {
139
        $hostname = parse_url($connectString, PHP_URL_HOST);
140
141
        if (preg_match('/^(ldaps:\/\/(.*))$/', $connectString, $matches)) {
142
            // The default context
143
            $sslContext = ['capture_peer_cert' => true, 'verify_peer' => true];
144
145
            // The non-default context, if configured ...
146
            if (!is_null($authSourceSpecifics) && array_key_exists('ssl', $authSourceSpecifics)) {
147
                $sslContext = array_replace($sslContext, $authSourceSpecifics['ssl']);
148
            }
149
150
            $port = parse_url($connectString, PHP_URL_PORT);
151
            $port = $port ?: $authSourceData['port'];
152
153
            $uri = 'ssl://' .  $hostname . ':' . $port;
154
            $context = stream_context_create(['ssl' => $sslContext]);
155
        } else {
156
            $port = $authSourceData['port'];
157
            $uri = 'tcp://' . $hostname . ':' . $port;
158
            $context = stream_context_create();
159
        }
160
161
        $timeout = isSet($authSourceData['timeout']) ? $authSourceData['timeout'] : null;
162
        return ['uri' => $uri, 'context' => $context, 'timeout' => $timeout];
163
    }
164
}
165