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
Bug
introduced
by
![]() |
|||||
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
![]() |
|||||
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
![]() |
|||||
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
![]() |
|||||
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
![]() |
|||||
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 |