Passed
Push — master ( 1c7137...b5ef5e )
by Pieter van der
03:26 queued 14s
created

Tiqr_UserStorage_Ldap::_getDNForUserId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 1
c 1
b 0
f 0
dl 0
loc 3
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * This file is part of the tiqr project.
4
 * 
5
 * The tiqr project aims to provide an open implementation for 
6
 * authentication using mobile devices. It was initiated by 
7
 * SURFnet and developed by Egeniq.
8
 *
9
 * More information: http://www.tiqr.org
10
 *
11
 * @author Ivo Jansch <[email protected]>
12
 * 
13
 * @package tiqr
14
 *
15
 * @license New BSD License - See LICENSE file for details.
16
 *
17
 * @copyright (C) 2010-2012 SURFnet BV
18
 */
19
20
require_once 'Zend/Ldap.php';
21
require_once 'Zend/Ldap/Attribute.php';
22
require_once 'Zend/Ldap/Dn.php';
23
24
require_once 'Tiqr/UserStorage/Abstract.php';
25
26
/**
27
 * LDAP Tiqr storage driver.
28
 */
29
class Tiqr_UserStorage_Ldap extends Tiqr_UserStorage_Abstract
30
{    
31
    /**
32
     * LDAP object.
33
     * 
34
     * @var Zend_Ldap
35
     */
36
    protected $_ldap;
37
    
38
    /**
39
     * User class.
40
     * 
41
     * @var string
42
     */
43
    protected $_userClass;
44
    
45
    /**
46
     * DN pattern. Can contain a single %s variable.
47
     * 
48
     * @var string
49
     */
50
    protected $_dnPattern;    
51
    
52
    /**
53
     * User identifier LDAP attribute.
54
     * 
55
     * @var string
56
     */
57
    protected $_idAttr;
58
59
    /**
60
     * User display name LDAP attribute.
61
     * 
62
     * @var string
63
     */
64
    protected $_displayNameAttr;
65
66
    /**
67
     * Tiqr user secret LDAP attribute.
68
     * 
69
     * @var string
70
     */
71
    protected $_secretAttr;
72
73
    /**
74
     * Device notification type LDAP attribute.
75
     * 
76
     * @var string
77
     */
78
    protected $_notificationTypeAttr;
79
80
    /**
81
     * Device notification address LDAP attribute.
82
     * 
83
     * @var string
84
     */
85
    protected $_notificationAddressAttr;
86
    
87
    /**
88
     * Is account blocked LDAP attribute.
89
     * 
90
     * @var string
91
     */
92
    protected $_isBlockedAttr;
93
94
    /**
95
     * Login attempts LDAP attribute.
96
     * 
97
     * @var string
98
     */
99
    protected $_loginAttemptsAttr;
100
    
101
    /**
102
     * Temporary block attempts LDAP attribute
103
     * 
104
     * @var string
105
     */
106
    protected $_temporaryBlockAttemptsAttr;
107
    
108
    /**
109
     * Temporary block timestamp LDAP attribute
110
     * 
111
     * @var string
112
     */
113
    protected $_temporaryBlockTimestampAttr;
114
115
    /**
116
     * LDAP attributes that need to be retrieved.
117
     *
118
     * Use null for everything.
119
     *
120
     * @param array
121
     */
122
    protected $_attributes;
123
    
124
    /**
125
     * Create an instance
126
     * @param $config
127
     */
128
    public function __construct($config, $secretconfig = array())
129
    {
130
	    parent::__construct($config, $secretconfig);
131
132
        $this->_userClass = isset($config['userClass']) ? $config['userClass'] : "tiqrPerson";
133
        $this->_dnPattern = isset($config['dnPattern']) ? $config['dnPattern'] : "%s";        
134
        $this->_idAttr = isset($config['idAttr']) ? $config['idAttr'] : 'dn';
135
        $this->_displayNameAttr = isset($config['displayNameAttr']) ? $config['displayNameAttr'] : 'sn';
136
        $this->_secretAttr = isset($config['secretAttr']) ? $config['secretAttr'] : 'tiqrSecret';
137
        $this->_notificationTypeAttr = isset($config['notificationTypeAttr']) ? $config['notificationTypeAttr'] : 'tiqrNotificationType';        
138
        $this->_notificationAddressAttr = isset($config['notificationAddressAttr']) ? $config['notificationAddressAttr'] : 'tiqrNotificationAddress';        
139
        $this->_isBlockedAttr = isset($config['isBlockedAttr']) ? $config['isBlockedAttr'] : 'tiqrIsBlocked';                
140
        $this->_loginAttemptsAttr = isset($config['loginAttemptsAttr']) ? $config['loginAttemptsAttr'] : 'tiqrLoginAttempts';  
141
        $this->_temporaryBlockAttemptAttr = isset($config['temporaryBlockAttemptsAttr']) ? $config['temporaryBlockAttemptsAttr'] : 'tiqrTemporaryBlockAttempts';
0 ignored issues
show
Bug Best Practice introduced by
The property _temporaryBlockAttemptAttr does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
142
        $this->_temporaryBlockTimestampAttr = isset($config['temporaryBlockTimestampAttr']) ? $config['temporaryBlockTimestampAttr'] : 'tiqrTemporaryBlockTimestamp';
143
        $this->_attributes = isset($config['attributes']) ? $config['attributes'] : null;
144
        
145
        $ldapOptions = array(
146
            "host" => $config['host'],
147
            "username" => $config['username'],
148
            "password" => $config['password'],
149
            "bindRequiresDn" => $config['bindRequiresDn'],
150
            "accountDomainName" => $config['accountDomainName'],
151
            "baseDn" => $config['baseDn'],
152
        );
153
        
154
        $this->_ldap = new Zend_Ldap($ldapOptions);
155
    }
156
   
157
    /**
158
     * Returns the value for the given LDAP attribute.
159
     * 
160
     * @param array  $entry      LDAP entry
161
     * @param string $attribName Attribute name.
162
     * 
163
     * @return mixed LDAP attribute value
164
     */
165
    protected function _getLDAPAttribute($entry, $attribName, $index=0)
166
    {
167
        $attribName = strtolower($attribName);
168
        
169
        if (!isset($entry[$attribName])) {
170
            return null;
171
        } else if (is_array($entry[$attribName])) {
172
            return Zend_Ldap_Attribute::getAttribute($entry, $attribName, $index);
173
        } else {
174
            return $entry[$attribName];
175
        }
176
    }
177
    
178
    /**
179
     * Sets the value for the given LDAP attribute.
180
     * 
181
     * @param array  $entry      LDAP entry
182
     * @param string $attribName Attribute name.
183
     * @param mixed  $value      Value.
184
     */
185
    protected function _setLDAPAttribute(&$entry, $attribName, $value)
186
    {
187
        $attribName = strtolower($attribName);
188
        Zend_Ldap_Attribute::setAttribute($entry, $attribName, $value);        
189
    }    
190
    
191
    /**
192
     * Returns the dn for the given user identifier.
193
     * 
194
     * @param string $userId user identifier
195
     * 
196
     * @return string LDAP dn
197
     */
198
    protected function _getDNForUserId($userId)
199
    {
200
        return sprintf($this->_dnPattern, $userId);
201
    }
202
    
203
    /**
204
     * This function takes care of actually saving the user data into LDAP
205
     * @param String $userId
206
     * @param array $data
207
     */
208
    protected function _saveUser($userId, $data)
209
    {
210
        if ($this->userExists($userId)) { 
211
            $this->_ldap->update($this->_getDNForUserId($userId), $data);
212
        } else { 
213
            $this->_ldap->add($this->_getDNForUserId($userId), $data);
214
        }
215
        return true;
216
    }
217
    
218
    /**
219
     * (non-PHPdoc)
220
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::createUser()
221
     */
222
    public function createUser($userId, $displayName) 
223
    {
224
        $user = array();
225
        $this->_setLDAPAttribute($user, "objectClass", $this->_userClass);
226
        $this->_setLDAPAttribute($user, $this->_idAttr, $userId);        
227
        $this->_setLDAPAttribute($user, $this->_displayNameAttr, $displayName);
228
229
        return $this->_saveUser($this->_getDNForUserId($userId), $user);
230
    }
231
    
232
    /**
233
     * (non-PHPdoc)
234
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::userExists()
235
     */
236
    public function userExists($userId)
237
    {
238
        $user = $this->_loadUser($userId);
239
        return (is_array($user) || is_object($user)); 
240
    }
241
242
    /**
243
     * This function takes care of loading the user from LDAP
244
     * @param String $userId
245
     * @return false if the data is not present, or an array containing the data.
246
     */
247
    protected function _loadUser($userId)
248
    {
249
        $user = $this->_ldap->getEntry($this->_getDNForUserId($userId));
250
        return $user;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $user returns the type array which is incompatible with the documented return type false.
Loading history...
251
    }
252
253
    /**
254
     * (non-PHPdoc)
255
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::getDisplayName()
256
     */
257
    public function getDisplayName($userId) 
258
    {
259
        if ($user = $this->_loadUser($userId)) {
260
            return $this->_getLDAPAttribute($user, $this->_displayNameAttr);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_getLDAPAt...this->_displayNameAttr) also could return the type array which is incompatible with the return type mandated by Tiqr_UserStorage_Interface::getDisplayName() of string.
Loading history...
261
        }
262
        return NULL;
263
    }
264
    
265
    /**
266
     * (non-PHPdoc)
267
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::getNotificationType()
268
     */
269
    public function getNotificationType($userId)
270
    {
271
        if ($user = $this->_loadUser($userId)) {
272
            return $this->_getLDAPAttribute($user, $this->_notificationTypeAttr);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_getLDAPAt...>_notificationTypeAttr) also could return the type array which is incompatible with the return type mandated by Tiqr_UserStorage_Interface::getNotificationType() of string.
Loading history...
273
        }
274
        return NULL;
275
    }
276
277
    /**
278
     * (non-PHPdoc)
279
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::setNotificationType()
280
     */
281
    public function setNotificationType($userId, $type)
282
    {
283
        $user = $this->_loadUser($userId);
284
        $this->_setLDAPAttribute($user, $this->_notificationTypeAttr, $type);
0 ignored issues
show
Bug introduced by
$user of type false is incompatible with the type array expected by parameter $entry of Tiqr_UserStorage_Ldap::_setLDAPAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

284
        $this->_setLDAPAttribute(/** @scrutinizer ignore-type */ $user, $this->_notificationTypeAttr, $type);
Loading history...
285
        $this->_saveUser($userId, $user);
286
    }    
287
    
288
    /**
289
     * (non-PHPdoc)
290
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::getNotificationAddress()
291
     */
292
    public function getNotificationAddress($userId)
293
    {
294
        if ($user = $this->_loadUser($userId)) {
295
            return $this->_getLDAPAttribute($user, $this->_notificationAddressAttr);
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->_getLDAPAt...otificationAddressAttr) also could return the type array which is incompatible with the return type mandated by Tiqr_UserStorage_Interfa...etNotificationAddress() of string.
Loading history...
296
        }
297
        return NULL;
298
    }
299
300
    /**
301
     * (non-PHPdoc)
302
     * @see simplesamlphp/modules/authTiqr/lib/User/sspmod_authTiqr_User_Interface::setNotificationAddress()
303
     */
304
    public function setNotificationAddress($userId, $address)
305
    {
306
        $user = $this->_loadUser($userId);
307
        $this->_setLDAPAttribute($user, $this->_notificationAddressAttr, $address);
0 ignored issues
show
Bug introduced by
$user of type false is incompatible with the type array expected by parameter $entry of Tiqr_UserStorage_Ldap::_setLDAPAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

307
        $this->_setLDAPAttribute(/** @scrutinizer ignore-type */ $user, $this->_notificationAddressAttr, $address);
Loading history...
308
        $this->_saveUser($userId, $user);
309
    } 
310
311
    /**
312
     * (non-PHPdoc)
313
     * @see simplesamlphp-module/authTiqr/lib/User/sspmod_authTiqr_User_Interface::getFailedLoginAttempts()
314
     */
315
    public function getLoginAttempts($userId)
316
    {
317
        if ($user = $this->_loadUser($userId)) {
318
            return $this->_getLDAPAttribute($user, $this->_loginAttemptsAttr);
319
        }
320
        return 0;
321
    }
322
    
323
    /**
324
     * (non-PHPdoc)
325
     * @see simplesamlphp-module/authTiqr/lib/User/sspmod_authTiqr_User_Interface::setFailedLoginAttempts()
326
     */
327
    public function setLoginAttempts($userId, $amount)
328
    {
329
        $user = $this->_loadUser($userId);
330
        $this->_setLDAPAttribute($user, $this->_loginAttemptsAttr, $amount);
0 ignored issues
show
Bug introduced by
$user of type false is incompatible with the type array expected by parameter $entry of Tiqr_UserStorage_Ldap::_setLDAPAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

330
        $this->_setLDAPAttribute(/** @scrutinizer ignore-type */ $user, $this->_loginAttemptsAttr, $amount);
Loading history...
331
        $this->_saveUser($userId, $user);
332
    }
333
    
334
    /**
335
     * (non-PHPdoc)
336
     * @see simplesamlphp-module/authTiqr/lib/User/sspmod_authTiqr_User_Interface::isBlocked()
337
     */
338
    public function isBlocked($userId, $duration)
339
    {
340
        if ($user = $this->_loadUser($userId)) {
341
            $isBlocked = $this->_getLDAPAttribute($user, $this->_isBlockedAttr);
342
            $timestamp = $this->getTemporaryBlockTimestamp($userId);
343
            if (false === (bool) $isBlocked || (false !== $timestamp && false != $duration && (strtotime($timestamp) + duration * 60) < time())) {
0 ignored issues
show
Bug introduced by
It seems like $timestamp can also be of type array; however, parameter $datetime of strtotime() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

343
            if (false === (bool) $isBlocked || (false !== $timestamp && false != $duration && (strtotime(/** @scrutinizer ignore-type */ $timestamp) + duration * 60) < time())) {
Loading history...
Bug introduced by
The constant duration was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
344
                return false;
345
            }
346
        }
347
        return true;
348
    }
349
    
350
    /**
351
     * (non-PHPdoc)
352
     * @see simplesamlphp-module/authTiqr/lib/User/sspmod_authTiqr_User_Interface::block()
353
     */
354
    public function setBlocked($userId, $blocked) 
355
    {
356
        $user = $this->_loadUser($userId);
357
        $this->_setLDAPAttribute($user, $this->_isBlockedAttr, $blocked);
0 ignored issues
show
Bug introduced by
$user of type false is incompatible with the type array expected by parameter $entry of Tiqr_UserStorage_Ldap::_setLDAPAttribute(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

357
        $this->_setLDAPAttribute(/** @scrutinizer ignore-type */ $user, $this->_isBlockedAttr, $blocked);
Loading history...
358
        $this->_saveUser($userId, $user);
359
    }
360
    
361
    /**
362
     * (non-PHPdoc)
363
     * @see libTiqr/library/tiqr/Tiqr/UserStorage/Tiqr_UserStorage_Interface::setTemporaryBlockAttempts()
364
     */
365
    public function setTemporaryBlockAttempts($userId, $amount) {
366
        $data = $this->_loadUser($userId);
367
        $this->_setLDAPAttribute($user, $this->_temporaryBlockAttemptsAttr, $amount);
368
        $this->_saveUser($userId, $data);
0 ignored issues
show
Bug introduced by
$data of type false is incompatible with the type array expected by parameter $data of Tiqr_UserStorage_Ldap::_saveUser(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

368
        $this->_saveUser($userId, /** @scrutinizer ignore-type */ $data);
Loading history...
369
    }
370
    
371
    /**
372
     * (non-PHPdoc)
373
     * @see libTiqr/library/tiqr/Tiqr/UserStorage/Tiqr_UserStorage_Interface::getTemporaryBlockAttempts()
374
     */
375
    public function getTemporaryBlockAttempts($userId) {
376
        if ($user = $this->_loadUser($userId)) {
377
            return $this->_getLDAPAttribute($user, $this->_temporaryBlockAttemptsAttr);
378
        }
379
        return 0;
380
    }
381
    
382
    /**
383
     * (non-PHPdoc)
384
     * @see libTiqr/library/tiqr/Tiqr/UserStorage/Tiqr_UserStorage_Interface::setTemporaryBlockTimestamp()
385
     */
386
    public function setTemporaryBlockTimestamp($userId, $timestamp) {
387
        $data = $this->_loadUser($userId);
388
        $this->_setLDAPAttribute($user, $this->_temporaryBlockTimestampAttr, $timestamp);
389
        $this->_saveUser($userId, $data);
0 ignored issues
show
Bug introduced by
$data of type false is incompatible with the type array expected by parameter $data of Tiqr_UserStorage_Ldap::_saveUser(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

389
        $this->_saveUser($userId, /** @scrutinizer ignore-type */ $data);
Loading history...
390
    }
391
    
392
    /**
393
     * (non-PHPdoc)
394
     * @see libTiqr/library/tiqr/Tiqr/UserStorage/Tiqr_UserStorage_Interface::getTemporaryBlockTimestamp()
395
     */
396
    public function getTemporaryBlockTimestamp($userId) {
397
        if ($data = $this->_loadUser($userId)) {
0 ignored issues
show
Unused Code introduced by
The assignment to $data is dead and can be removed.
Loading history...
398
            $timestamp = $this->_getLDAPAttribute($user, $this->_temporaryBlockTimestampAttr);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The variable $user does not exist. Did you maybe mean $userId?
Loading history...
399
            if (null !== $timestamp) {
400
                return $timestamp;
401
            } 
402
        }
403
        return false;
404
    }
405
406
    /**
407
     * Returns additional attributes for the given user.
408
     *
409
     * @param string $userId User identifier.
410
     * 
411
     * @return array additional user attributes
412
     */
413
    public function getAdditionalAttributes($userId) 
414
    {
415
        $user = $this->_loadUser($userId);
416
        if ($user == null) {
417
            return array();
418
        } else if (!is_array($this->_attributes)) {
419
            return $user;
420
        } else {
421
            $result = array();
422
            foreach ($this->_attributes as $name) {
423
                $name = strtolower($name);
424
                if (isset($user[$name])) {
425
                    $result[$name] = $user[$name];
426
                }
427
            }
428
429
            return $result;
430
        } 
431
    }
432
}
433