Passed
Push — master ( a717b5...dd05c8 )
by Florian
03:07 queued 01:19
created

ExtensionAdapter::setErrorHandler()   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 0
1
<?php
2
declare(strict_types=1);
3
/**
4
 * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
5
 * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
6
 *
7
 * Licensed under The MIT License
8
 * For full copyright and license information, please see the LICENSE.txt
9
 * Redistributions of files must retain the above copyright notice.
10
 *
11
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
12
 * @link          https://cakephp.org CakePHP(tm) Project
13
 * @since         1.0.0
14
 * @license       https://opensource.org/licenses/mit-license.php MIT License
15
 */
16
namespace Phauthentic\Authentication\Identifier\Ldap;
17
18
use Phauthentic\Authentication\Identifier\Ldap\AdapterInterface;
19
use ErrorException;
20
use RuntimeException;
21
22
/**
23
 * Provides a very thin OOP wrapper around the ldap_* functions.
24
 *
25
 * We don't need and want a huge LDAP lib for our purpose.
26
 *
27
 * But this makes it easier to unit test code that is using LDAP because we can
28
 * mock it very easy. It also provides some convenience.
29
 */
30
class ExtensionAdapter implements AdapterInterface
31
{
32
33
    /**
34
     * LDAP Object
35
     *
36
     * @var resource|null
37
     */
38
    protected $connection;
39
40
    /**
41
     * Constructor
42
     *
43
     * @throws \RuntimeException
44
     */
45
    public function __construct()
46
    {
47
        if (!extension_loaded('ldap')) {
48
            throw new RuntimeException('You must enable the ldap extension to use the LDAP identifier.');
49
        }
50
51
        if (!defined('LDAP_OPT_DIAGNOSTIC_MESSAGE')) {
52
            define('LDAP_OPT_DIAGNOSTIC_MESSAGE', 0x0032);
53
        }
54
    }
55
56
    /**
57
     * Bind to LDAP directory
58
     *
59
     * @param string $bind Bind rdn
60
     * @param string $password Bind password
61
     * @return bool
62
     */
63
    public function bind($bind, $password)
64
    {
65
        $this->setErrorHandler();
66
        $result = ldap_bind($this->getConnection(), $bind, $password);
67
        $this->unsetErrorHandler();
68
69
        return $result;
70
    }
71
72
    /**
73
     * Get the LDAP connection
74
     *
75
     * @return mixed
76
     * @throws \RuntimeException If the connection is empty
77
     */
78
    public function getConnection()
79
    {
80
        if (empty($this->connection)) {
81
            throw new RuntimeException('You are not connected to a LDAP server.');
82
        }
83
84
        return $this->connection;
85
    }
86
87
    /**
88
     * Connect to an LDAP server
89
     *
90
     * @param string $host Hostname
91
     * @param int $port Port
92
     * @param array $options Additonal LDAP options
93
     * @return void
94
     */
95
    public function connect($host, $port, $options)
96
    {
97
        $this->setErrorHandler();
98
        $this->connection = ldap_connect($host, $port) ?: null;
99
        $this->unsetErrorHandler();
100
101
        if (is_array($options)) {
0 ignored issues
show
introduced by
The condition is_array($options) is always true.
Loading history...
102
            foreach ($options as $option => $value) {
103
                $this->setOption($option, $value);
104
            }
105
        }
106
    }
107
108
    /**
109
     *  Set the value of the given option
110
     *
111
     * @param int $option Option to set
112
     * @param mixed $value The new value for the specified option
113
     * @return void
114
     */
115
    public function setOption($option, $value)
116
    {
117
        $this->setErrorHandler();
118
        ldap_set_option($this->getConnection(), $option, $value);
119
        $this->unsetErrorHandler();
120
    }
121
122
    /**
123
     * Get the current value for given option
124
     *
125
     * @param int $option Option to get
126
     * @return mixed This will be set to the option value.
127
     */
128
    public function getOption($option)
129
    {
130
        $this->setErrorHandler();
131
        ldap_get_option($this->getConnection(), $option, $returnValue);
132
        $this->unsetErrorHandler();
133
134
        return $returnValue;
135
    }
136
137
    /**
138
     * Get the diagnostic message
139
     *
140
     * @return string|null
141
     */
142
    public function getDiagnosticMessage()
143
    {
144
        return $this->getOption(LDAP_OPT_DIAGNOSTIC_MESSAGE);
145
    }
146
147
    /**
148
     * Unbind from LDAP directory
149
     *
150
     * @return void
151
     */
152
    public function unbind()
153
    {
154
        $this->setErrorHandler();
155
        if ($this->connection) {
156
            ldap_unbind($this->connection);
157
        }
158
        $this->unsetErrorHandler();
159
160
        $this->connection = null;
161
    }
162
163
    /**
164
     * Set an error handler to turn LDAP errors into exceptions
165
     *
166
     * @return void
167
     * @throws \ErrorException
168
     */
169
    protected function setErrorHandler()
170
    {
171
        set_error_handler(
172
            function ($errorNumber, $errorText) {
173
                 throw new ErrorException($errorText);
174
            },
175
            E_ALL
176
        );
177
    }
178
179
    /**
180
     * Restore the error handler
181
     *
182
     * @return void
183
     */
184
    protected function unsetErrorHandler()
185
    {
186
        restore_error_handler();
187
    }
188
}
189