Passed
Branch master (022a1c)
by Darwin
03:39
created

LdapManager   A

Complexity

Total Complexity 23

Size/Duplication

Total Lines 142
Duplicated Lines 21.13 %

Test Coverage

Coverage 77.78%

Importance

Changes 0
Metric Value
dl 30
loc 142
ccs 56
cts 72
cp 0.7778
rs 10
c 0
b 0
f 0
wmc 23

6 Methods

Rating   Name   Duplication   Size   Complexity  
B findUserByUsername() 13 17 5
C findUserBy() 13 28 7
A __construct() 0 5 1
A setLdapAttr() 0 13 3
A bind() 0 18 4
A buildFilter() 0 12 3

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
namespace DoL\LdapBundle\Ldap;
4
5
use DoL\LdapBundle\Driver\LdapDriverInterface;
6
use Symfony\Component\Security\Core\User\UserInterface;
7
use DoL\LdapBundle\Hydrator\HydratorInterface;
8
9
/**
10
 * Ldap manager for multi-domains.
11
 *
12
 * @author DarwinOnLine
13
 * @author Maks3w
14
 *
15
 * @see https://github.com/DarwinOnLine/DoLLdapBundle
16
 */
17
class LdapManager implements LdapManagerInterface
18
{
19
    protected $driver;
20
    protected $paramSets = [];
21
22
    protected $params = [];
23
    protected $ldapAttributes = [];
24
    protected $ldapUsernameAttr;
25
26
    /**
27
     * @var HydratorInterface
28
     */
29
    protected $hydrator;
30
31 4
    public function __construct(LdapDriverInterface $driver, HydratorInterface $hydrator, array $paramSets)
32
    {
33 4
        $this->driver = $driver;
34 4
        $this->hydrator = $hydrator;
35 4
        $this->paramSets = $paramSets;
36 4
    }
37
38
    /**
39
     * {@inheritdoc}
40
     */
41 1
    public function bind(UserInterface $user, $password)
42
    {
43 1
        if (!empty($this->params)) {
44
            return $this->driver->bind($user, $password);
45
        } else {
46 1
            foreach ($this->paramSets as $paramSet) {
47 1
                $this->driver->init($paramSet['driver']);
48
49 1
                if (false !== $this->driver->bind($user, $password)) {
50 1
                    $this->params = $paramSet['user'];
51 1
                    $this->setLdapAttr();
52
53 1
                    return true;
54
                }
55
            }
56
        }
57
58
        return false;
59
    }
60
61
    /**
62
     * {@inheritdoc}
63
     */
64 1
    public function findUserByUsername($username)
65
    {
66 1
        if (!empty($this->params)) {
67
            return $this->findUserBy([$this->ldapUsernameAttr => $username]);
68 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
69 1
            foreach ($this->paramSets as $paramSet) {
70 1
                $this->driver->init($paramSet['driver']);
71 1
                $this->params = $paramSet['user'];
72 1
                $this->setLdapAttr();
73
74 1
                $user = $this->findUserBy([$this->ldapUsernameAttr => $username]);
75 1
                if (false !== $user && $user instanceof UserInterface) {
76 1
                    return $user;
77
                }
78
79
                $this->params = [];
80
                $this->setLdapAttr();
81
            }
82
        }
83
    }
84
85
    /**
86
     * {@inheritdoc}
87
     */
88 2
    public function findUserBy(array $criteria)
89
    {
90 2
        if (!empty($this->params)) {
91 2
            $filter = $this->buildFilter($criteria);
92 2
            $entries = $this->driver->search($this->params['baseDn'], $filter);
93 2
            if ($entries['count'] > 1) {
94
                throw new \Exception('This search can only return a single user');
95
            }
96
97 2
            if (0 == $entries['count']) {
98
                return null;
99
            }
100 2
            $user = $this->hydrator->hydrate($entries[0]);
101
102 2
            return $user;
103 View Code Duplication
        } else {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
104 1
            foreach ($this->paramSets as $paramSet) {
105 1
                $this->driver->init($paramSet['driver']);
106 1
                $this->params = $paramSet['user'];
107 1
                $this->setLdapAttr();
108
109 1
                $user = $this->findUserBy($criteria);
110 1
                if (false !== $user && $user instanceof UserInterface) {
111 1
                    return $user;
112
                }
113
114
                $this->params = [];
115
                $this->setLdapAttr();
116
            }
117
        }
118
    }
119
120
    /**
121
     * Sets temp Ldap attributes.
122
     */
123 3
    private function setLdapAttr()
124
    {
125 3
        if (isset($this->params['attributes'])) {
126 3
            $this->hydrator->setAttributeMap($this->params['attributes']);
127
128 3
            foreach ($this->params['attributes'] as $attr) {
129 3
                $this->ldapAttributes[] = $attr['ldap_attr'];
130 3
            }
131
132 3
            $this->ldapUsernameAttr = $this->ldapAttributes[0];
133 3
        } else {
134
            $this->ldapAttributes = [];
135
            $this->ldapUsernameAttr = null;
136
        }
137 3
    }
138
139
    /**
140
     * Build Ldap filter.
141
     *
142
     * @param array  $criteria
143
     * @param string $condition
144
     *
145
     * @return string
146
     */
147 3
    protected function buildFilter(array $criteria, $condition = '&')
148
    {
149 3
        $filters = [];
150 3
        if (isset($this->params['filter'])) {
151 3
            $filters[] = $this->params['filter'];
152 3
        }
153 3
        foreach ($criteria as $key => $value) {
154 3
            $value = ldap_escape($value, '', LDAP_ESCAPE_FILTER);
155 3
            $filters[] = sprintf('(%s=%s)', $key, $value);
156 3
        }
157
158 3
        return sprintf('(%s%s)', $condition, implode($filters));
0 ignored issues
show
Bug introduced by
The call to implode() has too few arguments starting with pieces. ( Ignorable by Annotation )

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

158
        return sprintf('(%s%s)', $condition, /** @scrutinizer ignore-call */ implode($filters));

This check compares calls to functions or methods with their respective definitions. If the call has less arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
Bug introduced by
$filters of type array is incompatible with the type string expected by parameter $glue of implode(). ( Ignorable by Annotation )

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

158
        return sprintf('(%s%s)', $condition, implode(/** @scrutinizer ignore-type */ $filters));
Loading history...
159
    }
160
}
161