Passed
Pull Request — master (#28)
by Tim
02:23
created

Ldap   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 120
Duplicated Lines 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
wmc 12
eloc 44
c 1
b 0
f 0
dl 0
loc 120
rs 10

3 Methods

Rating   Name   Duplication   Size   Complexity  
A create() 0 22 2
B search() 0 49 7
A bind() 0 12 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\ldap\Utils;
6
7
use SimpleSAML\Assert\Assert;
8
use SimpleSAML\Error;
9
use SimpleSAML\Logger;
10
use Symfony\Component\Ldap\Entry;
11
use Symfony\Component\Ldap\Exception\ConnectionException;
12
use Symfony\Component\Ldap\Ldap as LdapObject;
13
14
use function array_pop;
15
use function count;
16
use function is_array;
17
use function sprintf;
18
use function strval;
19
20
/**
21
 * LDAP utilities
22
 *
23
 * @package simplesamlphp/simplesamlphp-module-ldap
24
 */
25
26
class Ldap
27
{
28
    /**
29
     * Create Ldap resource objects
30
     *
31
     * @param array $connection_strings
32
     * @param string $encryption
33
     * @param int $version
34
     * @param string $extension
35
     * @return \Symfony\Component\Ldap\Ldap[]
36
     */
37
    public function create(
38
        array $connection_strings,
39
        string $encryption = 'ssl',
40
        int $version = 3,
41
        string $extension = 'ext_ldap')
42
    : array {
43
        $ldapServers = [];
44
45
        foreach ($connection_strings as $connection_string) {
46
            Assert::regex($connection_string, '#^ldap[s]?:\/\/#');
47
48
            $ldapServers[] = LdapObject::create(
49
                $extension,
50
                [
51
                    'connection_string' => $connection_string,
52
                    'encryption' => $encryption,
53
                    'version' => $version,
54
                ]
55
            );
56
        }
57
58
        return $ldapServers;
59
    }
60
61
62
    /**
63
     * Bind to an LDAP-server
64
     *
65
     * @param \Symfony\Component\Ldap\Ldap[] $ldapServers
66
     * @param string $username
67
     * @param string|null $password  Null for passwordless logon
68
     * @throws \SimpleSAML\Error\Exception if none of the LDAP-servers could be contacted
69
     */
70
    public function bind(array $ldapServers, string $username, ?string $password): LdapObject
71
    {
72
        foreach ($ldapServers as $ldap) {
73
            try {
74
                $ldap->bind($username, strval($password));
75
                return $ldap;
76
            } catch (ConnectionException $e) {
77
                // Try next server
78
            }
79
        }
80
81
        throw new Error\Exception("Unable to bind to any of the configured LDAP servers.");
82
    }
83
84
85
    /**
86
     * Search the LDAP-directory for a specific DN
87
     *
88
     * @param \Symfony\Component\Ldap\Ldap $ldap
89
     * @param array $searchBase
90
     * @param string $filter
91
     * @param array $options
92
     * @param boolean $allowMissing
93
     * @return \Symfony\Component\Ldap\Entry|null The result of the search or null if none found
94
     * @throws \SimpleSAML\Error\Exception if more than one entry was found
95
     * @throws \SimpleSAML\Error\Exception if the object cannot be found using the given search base and filter
96
     */
97
    public function search(
98
        LdapObject $ldap,
99
        array $searchBase,
100
        string $filter,
101
        array $options,
102
        bool $allowMissing
103
    ): ?Entry {
104
        $entry = null;
105
106
        foreach ($searchBase as $base) {
107
            $query = $ldap->query($base, $filter, $options);
108
            $result = $query->execute();
109
            $result = is_array($result) ? $result : $result->toArray();
110
111
            if (count($result) > 1) {
112
                throw new Error\Exception(
113
                    sprintf(
114
                        "Library - LDAP search(): Found %d entries searching base '%s' for '%s'",
115
                        count($result),
116
                        $base,
117
                        $filter,
118
                    )
119
                );
120
            } elseif (count($result) === 1) {
121
                $entry = array_pop($result);
122
                break;
123
            } else {
124
                Logger::debug(
125
                    sprintf(
126
                        "Library - LDAP search(): Found no entries searching base '%s' for '%s'",
127
                        count($result),
128
                        $base,
129
                        $filter,
130
                    )
131
                );
132
            }
133
        }
134
135
        if ($entry === null && $allowMissing === false) {
136
            throw new Error\Exception(
137
                sprintf(
138
                    "Object not found using search base [%s] and filter '%s'",
139
                    implode(', ', $searchBase),
140
                    $filter
141
                )
142
            );
143
        }
144
145
        return $entry;
146
    }
147
}
148
149