Issues (9)

src/UserRepository.php (5 issues)

Labels
Severity
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\ldapPasswordReset;
6
7
use SimpleSAML\Assert\Assert;
8
use SimpleSAML\{Configuration, Error, Logger};
9
use SimpleSAML\Module\ldap\Connector;
10
use Symfony\Component\Ldap\Entry;
11
use Symfony\Component\Ldap\Ldap;
12
use Symfony\Component\Ldap\Security\LdapUserProvider;
13
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
14
15
use function mb_convert_encoding;
16
17
/**
18
 * This class is a wrapper around the ldap-module
19
 *
20
 * @package simplesamlphp/simplesamlphp-module-ldapPasswordReset
21
 */
22
class UserRepository
23
{
24
    /** @var \SimpleSAML\Configuration */
25
    protected Configuration $config;
26
27
    /** @var \SimpleSAML\Configuration */
28
    protected Configuration $moduleConfig;
29
30
    /** @var \SimpleSAML\Module\ldap\Connector\Ldap */
31
    protected Connector\Ldap $connector;
32
33
34
    /**
35
     */
36
    public function __construct()
37
    {
38
        $this->moduleConfig = Configuration::getOptionalConfig('module_ldapPasswordReset.php');
39
40
        $encryption = $this->moduleConfig->getOptionalString('encryption', 'ssl');
41
        Assert::oneOf($encryption, ['none', 'ssl', 'tls']);
42
43
        $version = $this->moduleConfig->getOptionalInteger('version', 3);
44
        Assert::positiveInteger($version);
45
46
        $this->connector = new Connector\Ldap(
47
            $this->moduleConfig->getString('connection_string'),
48
            $encryption,
0 ignored issues
show
It seems like $encryption can also be of type null; however, parameter $encryption of SimpleSAML\Module\ldap\C...tor\Ldap::__construct() 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

48
            /** @scrutinizer ignore-type */ $encryption,
Loading history...
49
            $version,
0 ignored issues
show
It seems like $version can also be of type null; however, parameter $version of SimpleSAML\Module\ldap\C...tor\Ldap::__construct() does only seem to accept integer, 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

49
            /** @scrutinizer ignore-type */ $version,
Loading history...
50
            $this->moduleConfig->getOptionalString('extension', 'ext_ldap'),
0 ignored issues
show
It seems like $this->moduleConfig->get...extension', 'ext_ldap') can also be of type null; however, parameter $extension of SimpleSAML\Module\ldap\C...tor\Ldap::__construct() 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

50
            /** @scrutinizer ignore-type */ $this->moduleConfig->getOptionalString('extension', 'ext_ldap'),
Loading history...
51
            $this->moduleConfig->getOptionalBoolean('debug', false),
0 ignored issues
show
It seems like $this->moduleConfig->get...Boolean('debug', false) can also be of type null; however, parameter $debug of SimpleSAML\Module\ldap\C...tor\Ldap::__construct() does only seem to accept boolean, 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

51
            /** @scrutinizer ignore-type */ $this->moduleConfig->getOptionalBoolean('debug', false),
Loading history...
52
            $this->moduleConfig->getOptionalArray('options', []),
0 ignored issues
show
It seems like $this->moduleConfig->get...ray('options', array()) can also be of type null; however, parameter $options of SimpleSAML\Module\ldap\C...tor\Ldap::__construct() does only seem to accept array, 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

52
            /** @scrutinizer ignore-type */ $this->moduleConfig->getOptionalArray('options', []),
Loading history...
53
        );
54
    }
55
56
57
    /**
58
     * Find user in LDAP-store
59
     *
60
     * @param string $email
61
     * @return \Symfony\Component\Ldap\Entry|null
62
     */
63
    public function findUserByEmail(string $email): ?Entry
64
    {
65
        $searchBase = $this->moduleConfig->getString('search.base');
66
67
        $searchUsername = $this->moduleConfig->getString('search.username');
68
        Assert::notWhitespaceOnly($searchUsername);
69
70
        $searchPassword = $this->moduleConfig->getOptionalString('search.password', null);
71
        Assert::nullOrNotWhitespaceOnly($searchPassword);
72
73
        $ldap = new Ldap($this->connector->getAdapter());
74
        $ldapUserProvider = new LdapUserProvider($ldap, $searchBase, $searchUsername, $searchPassword, [], 'mail');
75
76
        try {
77
            return $ldapUserProvider->loadUserByIdentifier($email)->getEntry();
78
        } catch (UserNotFoundException $e) {
79
            // We haven't found the user
80
            return null;
81
        }
82
    }
83
84
85
    /**
86
     * Update user password in LDAP-store
87
     *
88
     * @param \Symfony\Component\Ldap\Entry $user
89
     * @param string $newPassword
90
     * @return bool
91
     */
92
    public function updatePassword(Entry $user, string $newPassword): bool
93
    {
94
        $searchUsername = $this->moduleConfig->getString('search.username');
95
        Assert::notWhitespaceOnly($searchUsername);
96
97
        $searchPassword = $this->moduleConfig->getOptionalString('search.password', null);
98
        Assert::nullOrNotWhitespaceOnly($searchPassword);
99
100
        try {
101
            $this->connector->bind($searchUsername, $searchPassword);
102
        } catch (Error\Error $e) {
103
            throw new Error\Exception("Unable to bind using the configured search.username and search.password.");
104
        }
105
106
        $userPassword = mb_convert_encoding('"' . $newPassword . '"', 'utf-16le');
107
        $newEntry = new Entry($user->getDn(), [
108
            'unicodePwd' => [$userPassword],
109
        ]);
110
111
        return $this->connector->updateEntry($newEntry);
112
    }
113
}
114