Passed
Push — master ( 4541b1...3f3f73 )
by Tim
01:48
created

Ldap   A

Complexity

Total Complexity 13

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 13

3 Methods

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