ZendLdapDriver::bind()   A
last analyzed

Complexity

Conditions 4
Paths 6

Size

Total Lines 21
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 13
c 1
b 0
f 0
nc 6
nop 2
dl 0
loc 21
ccs 14
cts 14
cp 1
crap 4
rs 9.8333
1
<?php
2
3
namespace DoL\LdapBundle\Driver;
4
5
use Zend\Ldap\Ldap;
6
use Zend\Ldap\Exception\LdapException as ZendLdapException;
7
use DoL\LdapBundle\Model\LdapUserInterface;
8
use Psr\Log\LoggerInterface;
9
use Symfony\Component\Security\Core\User\UserInterface;
10
11
/**
12
 * This class adapt ldap calls to Zend Framework Ldap library functions.
13
 * Also prevent information disclosure catching Zend Ldap Exceptions and passing
14
 * them to the logger.
15
 *
16
 * @since v2.0.0
17
 *
18
 * @author DarwinOnLine
19
 * @author Maks3w
20
 *
21
 * @see https://github.com/DarwinOnLine/DoLLdapBundle
22
 */
23
class ZendLdapDriver implements LdapDriverInterface
24
{
25
    /**
26
     * @var Ldap
27
     */
28
    private $driver;
29
30
    /**
31
     * @var LoggerInterface
32
     */
33
    private $logger;
34
35
    /**
36
     * @param Ldap            $driver Initialized Zend::Ldap Object
37
     * @param LoggerInterface $logger optional logger for write debug messages
38
     */
39 8
    public function __construct(Ldap $driver, LoggerInterface $logger = null)
40
    {
41 8
        $this->driver = $driver;
42 8
        $this->logger = $logger;
43 8
    }
44
45
    /**
46
     * {@inheritdoc}
47
     */
48
    public function init(array $options)
49
    {
50
        $this->driver->disconnect()->setOptions($options);
51
    }
52
53
    /**
54
     * {@inheritdoc}
55
     */
56 1
    public function search($baseDn, $filter, array $attributes = array())
57
    {
58 1
        $this->logDebug('{action}({base_dn}, {filter}, {attributes})', [
59 1
            'action' => 'ldap_search',
60 1
            'base_dn' => $baseDn,
61 1
            'filter' => $filter,
62 1
            'attributes' => $attributes,
63 1
        ]);
64
65
        try {
66 1
            $entries = $this->driver->searchEntries($filter, $baseDn, Ldap::SEARCH_SCOPE_SUB, $attributes);
67
            // searchEntries don't return 'count' key as specified by php native
68
            // function ldap_get_entries()
69 1
            $entries['count'] = count($entries);
70 1
        } catch (ZendLdapException $exception) {
71
            $this->zendExceptionHandler($exception);
72
73
            throw new LdapDriverException('An error occur with the search operation.');
74
        }
75
76 1
        return $entries;
77
    }
78
79
    /**
80
     * {@inheritdoc}
81
     */
82 6
    public function bind(UserInterface $user, $password)
83
    {
84 6
        if ($user instanceof LdapUserInterface && $user->getDn()) {
85 3
            $bind_rdn = $user->getDn();
86 3
        } else {
87 3
            $bind_rdn = $user->getUsername();
88
        }
89
90
        try {
91 6
            $this->logDebug('{action}({bind_rdn}, ****)', [
92 6
                'action' => 'ldap_bind',
93 6
                'bind_rdn' => $bind_rdn,
94 6
            ]);
95 6
            $bind = $this->driver->bind($bind_rdn, $password);
96
97 2
            return $bind instanceof Ldap;
98 4
        } catch (ZendLdapException $exception) {
99 4
            $this->zendExceptionHandler($exception);
100
        }
101
102 4
        return false;
103
    }
104
105
    /**
106
     * Treat a Zend Ldap Exception.
107
     *
108
     * @param ZendLdapException $exception
109
     */
110 4
    protected function zendExceptionHandler(ZendLdapException $exception)
111
    {
112 4
        switch ($exception->getCode()) {
113
            // Error level codes
114 4
            case ZendLdapException::LDAP_SERVER_DOWN:
115
                if ($this->logger) {
116
                    $this->logger->error('{exception}', ['exception' => $exception]);
117
                }
118
                break;
119
120
            // Other level codes
121 4
            default:
122 4
                $this->logDebug('{exception}', ['exception' => $exception]);
123 4
                break;
124 4
        }
125 4
    }
126
127
    /**
128
     * Log debug messages if the logger is set.
129
     *
130
     * @param string $message
131
     * @param array  $context
132
     */
133 7
    private function logDebug($message, array $context = [])
134
    {
135 7
        if ($this->logger) {
136 7
            $this->logger->debug($message, $context);
137 7
        }
138 7
    }
139
}
140