Completed
Pull Request — master (#489)
by Richard
10:39
created

Ldap   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 230
Duplicated Lines 1.3 %

Coupling/Cohesion

Components 1
Dependencies 3

Test Coverage

Coverage 0%
Metric Value
wmc 17
lcom 1
cbo 3
dl 3
loc 230
rs 10
ccs 0
cts 91
cp 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 15 3
B authenticate() 3 32 6
B getUserDN() 0 32 4
A getFilter() 0 10 2
A loadXoopsUser() 0 14 2

How to fix   Duplicated Code   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

1
<?php
2
/*
3
 You may not change or alter any portion of this comment or credits
4
 of supporting developers from this source code or any supporting source code
5
 which is considered copyrighted (c) material of the original comment or credit authors.
6
7
 This program is distributed in the hope that it will be useful,
8
 but WITHOUT ANY WARRANTY; without even the implied warranty of
9
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
10
*/
11
12
namespace Xoops\Auth;
13
14
use Xoops\Core\Database\Connection;
15
16
/**
17
 * Authentication class for standard LDAP Server V3
18
 *
19
 * @category  Xoops\Auth
20
 * @package   Ldap
21
 * @author    Pierre-Eric MENUET <[email protected]>
22
 * @copyright 2000-2014 XOOPS Project (http://xoops.org)
23
 * @license   GNU GPL 2 or later (http://www.gnu.org/licenses/gpl-2.0.html)
24
 * @link      http://xoops.org
25
 * @since     2.0
26
 */
27
class Ldap extends AuthAbstract
28
{
29
30
    /**
31
     * @var
32
     */
33
    public $ldap_server;
34
35
    /**
36
     * @var string
37
     */
38
39
    public $ldap_port = '389';
40
    /**
41
     * @var string
42
     */
43
    public $ldap_version = '3';
44
45
    /**
46
     * @var
47
     */
48
    public $ldap_base_dn;
49
50
    /**
51
     * @var
52
     */
53
    public $ldap_loginname_asdn;
54
55
    /**
56
     * @var
57
     */
58
    public $ldap_loginldap_attr;
59
60
    /**
61
     * @var
62
     */
63
    public $ldap_mail_attr;
64
65
    /**
66
     * @var
67
     */
68
    public $ldap_name_attr;
69
70
    /**
71
     * @var
72
     */
73
    public $ldap_surname_attr;
74
75
    /**
76
     * @var
77
     */
78
    public $ldap_givenname_attr;
79
80
    /**
81
     * @var
82
     */
83
    public $ldap_manager_dn;
84
85
    /**
86
     * @var
87
     */
88
    public $ldap_manager_pass;
89
90
    /**
91
     * @var
92
     */
93
    public $ds;
94
95
    /**
96
     * @var
97
     */
98
    public $ldap_use_TLS;
99
100
    /**
101
     * @var
102
     */
103
    public $ldap_domain_name;
104
105
    /**
106
     * @var
107
     */
108
    public $ldap_filter_person;
109
110
    /**
111
     * Authentication Service constructor
112
     *
113
     * @param Connection|null $dao databse
114
     */
115
    public function __construct(Connection $dao = null)
116
    {
117
        if (!extension_loaded('ldap')) {
118
            trigger_error(sprintf(\XoopsLocale::F_EXTENSION_PHP_NOT_LOADED, 'LDAP'), E_USER_ERROR);
119
            return;
120
        }
121
122
        $xoops = \Xoops::getInstance();
123
        $this->dao = $dao;
124
        //Configuration options that are stored in the database
125
        $configs = $xoops->getConfigs();
126
        foreach ($configs as $key => $val) {
127
            $this->$key = $val;
128
        }
129
    }
130
131
    /**
132
     * Authenticate  user again LDAP directory (Bind)
133
     *               2 options :
134
     *         Authenticate directly with uname in the DN
135
     *         Authenticate with manager, search the dn
136
     *
137
     * @param string $uname Username
138
     * @param string $pwd   Password
139
     *
140
     * @return bool
141
     */
142
    public function authenticate($uname, $pwd = null)
143
    {
144
        $authenticated = false;
145
        $this->ds = ldap_connect($this->ldap_server, $this->ldap_port);
146
        if ($this->ds) {
147
            ldap_set_option($this->ds, LDAP_OPT_PROTOCOL_VERSION, $this->ldap_version);
148
            if ($this->ldap_use_TLS) { // We use TLS secure connection
149
                if (!ldap_start_tls($this->ds)) {
150
                    $this->setErrors(0, \XoopsLocale::E_TLS_CONNECTION_NOT_OPENED);
151
                }
152
            }
153
            // If the uid is not in the DN we proceed to a search
154
            // The uid is not always in the dn
155
            $userDN = $this->getUserDN($uname);
156
            if (!(is_string($userDN))) {
157
                return false;
158
            }
159
            // We bind as user to test the credentials
160
            $authenticated = ldap_bind($this->ds, $userDN, stripslashes($pwd));
161
            if ($authenticated) {
162
                // We load the Xoops User database
163
                return $this->loadXoopsUser($userDN, $uname, $pwd);
164 View Code Duplication
            } else {
165
                $this->setErrors(ldap_errno($this->ds), ldap_err2str(ldap_errno($this->ds)) . '(' . $userDN . ')');
166
            }
167
        } else {
168
            $this->setErrors(0, \XoopsLocale::E_CANNOT_CONNECT_TO_SERVER);
169
        }
170
        @ldap_close($this->ds);
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
171
172
        return $authenticated;
173
    }
174
175
    /**
176
     * Compose the user DN with the configuration.
177
     *
178
     * @param string $uname username
179
     *
180
     * @return bool|string userDN or false
181
     */
182
    public function getUserDN($uname)
183
    {
184
        $userDN = false;
185
        if (!$this->ldap_loginname_asdn) {
186
            // Bind with the manager
187
            if (!ldap_bind($this->ds, $this->ldap_manager_dn, stripslashes($this->ldap_manager_pass))) {
188
                $this->setErrors(
189
                    ldap_errno($this->ds),
190
                    ldap_err2str(ldap_errno($this->ds)) . '(' . $this->ldap_manager_dn . ')'
191
                );
192
193
                return false;
194
            }
195
            $filter = $this->getFilter($uname);
196
            $sr = ldap_search($this->ds, $this->ldap_base_dn, $filter);
197
            $info = ldap_get_entries($this->ds, $sr);
198
            if ($info['count'] > 0) {
199
                $userDN = $info[0]['dn'];
200
            } else {
201
                $this->setErrors(0, sprintf(
202
                    \XoopsLocale::EF_USER_NOT_FOUND_IN_DIRECTORY_SERVER,
203
                    $uname,
204
                    $filter,
205
                    $this->ldap_base_dn
206
                ));
207
            }
208
        } else {
209
            $userDN = $this->ldap_loginldap_attr . '=' . $uname . ',' . $this->ldap_base_dn;
210
        }
211
212
        return $userDN;
213
    }
214
215
    /**
216
     * Load user from XOOPS Database
217
     *
218
     * @param string $uname username
219
     *
220
     * @return mixed|string
221
     */
222
    public function getFilter($uname)
223
    {
224
        if ($this->ldap_filter_person != '') {
225
            $filter = str_replace('@@loginname@@', $uname, $this->ldap_filter_person);
226
        } else {
227
            $filter = $this->ldap_loginldap_attr . '=' . $uname;
228
        }
229
230
        return $filter;
231
    }
232
233
    /**
234
     * loadXoopsUser
235
     *
236
     * @param string $userdn base DN for the directory
237
     * @param string $uname  username
238
     * @param string $pwd    pasword
239
     *
240
     * @return bool|XoopsUser
241
     */
242
    public function loadXoopsUser($userdn, $uname, $pwd = null)
243
    {
244
        $xoopsUser = false;
245
        $provisHandler = Provisioning::getInstance($this);
246
        $sr = ldap_read($this->ds, $userdn, '(objectclass=*)');
247
        $entries = ldap_get_entries($this->ds, $sr);
248
        if ($entries['count'] > 0) {
249
            $xoopsUser = $provisHandler->sync($entries[0], $uname, $pwd);
250
        } else {
251
            $this->setErrors(0, sprintf('loadXoopsUser - ' . \XoopsLocale::EF_ENTRY_NOT_READ, $userdn));
252
        }
253
254
        return $xoopsUser;
255
    }
256
}
257