LdapAuthenticationTrait::getBindUsername()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 13
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 3
nop 2
1
<?php
2
/**
3
 * This file is part of the LdapToolsBundle package.
4
 *
5
 * (c) Chad Sikorra <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace LdapTools\Bundle\LdapToolsBundle\Security;
12
13
use LdapTools\Bundle\LdapToolsBundle\Security\User\LdapUserProvider;
14
use LdapTools\Exception\Exception;
15
use LdapTools\LdapManager;
16
use LdapTools\Object\LdapObject;
17
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
18
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
19
use Symfony\Component\Security\Core\User\UserInterface;
20
use Symfony\Component\Security\Core\User\UserProviderInterface;
21
22
/**
23
 * Common methods between the Guard and Authentication Provider.
24
 *
25
 * @author Chad Sikorra <[email protected]>
26
 */
27
trait LdapAuthenticationTrait
28
{
29
    /**
30
     * @var LdapManager
31
     */
32
    protected $ldap;
33
34
    /**
35
     * @var LdapUserProvider
36
     */
37
    protected $ldapUserProvider;
38
39
    /**
40
     * The logic for determining the username/DN to bind with is as follows:
41
     *
42
     * 1. Always prefer a DN from a default user from the LDAP user provider, or LdapObject instance from LdapTools
43
     * 2. If it wasn't a LdapObject and no attribute was explicitly set to query LDAP for, use the UserInterface username
44
     * 3. Query LDAP using a specific attribute for a user with the specified username, return the DN.
45
     *
46
     * @param UserInterface $user
47
     * @param string|null $queryAttribute
48
     * @return string
49
     */
50
    protected function getBindUsername(UserInterface $user, $queryAttribute)
51
    {
52
        if ($user instanceof LdapObject && $user->has('dn')) {
53
            return $user->get('dn');
54
        }
55
        if ($queryAttribute === null) {
56
            return $user->getUsername();
57
        }
58
59
        return $this->ldapUserProvider
60
            ->getLdapUser($queryAttribute, $user->getUsername())
61
            ->get('dn');
62
    }
63
64
    /**
65
     * If no LDAP credentials are in the config then attempt to use the user supplied credentials from the login. But
66
     * only if we are using the LdapUserProvider.
67
     *
68
     * @param string $username
69
     * @param string $password
70
     * @param UserProviderInterface $userProvider
71
     */
72
    protected function setLdapCredentialsIfNeeded($username, $password, UserProviderInterface $userProvider)
73
    {
74
        // Only care about this in the context of the LDAP user provider...
75
        if (!$userProvider instanceof LdapUserProvider) {
76
            return;
77
        }
78
79
        // Only if the username/password are not defined in the config....
80
        $config = $this->ldap->getConnection()->getConfig();
81
        if (!(empty($config->getUsername()) && (empty($config->getPassword() && $config->getPassword() !== '0')))) {
82
            return;
83
        }
84
85
        $config->setUsername($username);
86
        $config->setPassword($password);
87
    }
88
89
    /**
90
     * If the domain needs to a different context for the request, then switch it.
91
     *
92
     * @param string|null $domain
93
     */
94
    protected function switchDomainIfNeeded($domain)
95
    {
96
        if (!empty($domain) && $this->ldap->getDomainContext() !== $domain) {
97
            $this->ldap->switchDomain($domain);
98
        }
99
    }
100
101
    /**
102
     * If the passed domain is not the current context, then switch back to it.
103
     *
104
     * @param string $domain
105
     */
106
    protected function switchDomainBackIfNeeded($domain)
107
    {
108
        if ($domain !== $this->ldap->getDomainContext()) {
109
            $this->ldap->switchDomain($domain);
110
        }
111
    }
112
113
    /**
114
     * Determine whether or not the exception should be masked with a BadCredentials or not.
115
     *
116
     * @param \Exception $e
117
     * @param bool $hideUserNotFoundExceptions
118
     * @throws \Exception
119
     */
120
    protected function hideOrThrow(\Exception $e, $hideUserNotFoundExceptions)
121
    {
122
        if ($hideUserNotFoundExceptions) {
123
            throw new BadCredentialsException('Bad credentials.', 0, $e);
124
        }
125
126
        // Specifically show LdapTools related exceptions, ignore others.
127
        // Custom auth exception messages don't exist until Symfony 2.8, 2.7 is still under support...
128
        if (!$hideUserNotFoundExceptions && $e instanceof Exception && class_exists('Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException')) {
129
            throw new CustomUserMessageAuthenticationException($e->getMessage(), [], $e->getCode());
130
        }
131
132
        throw $e;
133
    }
134
}
135