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

Ldap::invokeTest()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 72
Code Lines 43

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 43
dl 0
loc 72
rs 8.2986
c 0
b 0
f 0
cc 7
nc 4
nop 0

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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