|
9 | 9 | namespace OCA\User_SAML; |
10 | 10 |
|
11 | 11 | use OCA\User_SAML\Exceptions\NoUserFoundException; |
| 12 | +use OCP\IConfig; |
12 | 13 | use OCP\IUser; |
13 | 14 | use OCP\IUserManager; |
| 15 | +use OCP\LDAP\Exceptions\MultipleUsersReturnedException; |
| 16 | +use OCP\LDAP\ILDAPProviderFactory; |
| 17 | +use OCP\Server; |
14 | 18 |
|
15 | 19 | class UserResolver { |
16 | 20 | public function __construct( |
17 | | - private IUserManager $userManager, |
| 21 | + private readonly IUserManager $userManager, |
| 22 | + private readonly ILDAPProviderFactory $ldapProviderFactory, |
| 23 | + private readonly IConfig $config, |
18 | 24 | ) { |
19 | 25 | } |
20 | 26 |
|
21 | 27 | /** |
22 | 28 | * @throws NoUserFoundException |
23 | 29 | */ |
24 | | - public function findExistingUserId(string $rawUidCandidate, bool $force = false, bool $isActiveDirectory = false): string { |
| 30 | + public function findExistingUserId(string $rawUidCandidate, ?array $idpSettings = null, bool $force = false, bool $isActiveDirectory = false): string { |
| 31 | + // If configured, find the user based on a different LDAP attribute. |
| 32 | + if ($idpSettings !== null |
| 33 | + && version_compare($this->config->getSystemValueString('version', '0.0.0'), '34.0.0', '>=') |
| 34 | + && $this->ldapProviderFactory->isAvailable() |
| 35 | + && isset($idpSettings['saml-attribute-mapping-user_id_ldap_mapping']) |
| 36 | + && $idpSettings['saml-attribute-mapping-user_id_ldap_mapping'] !== null |
| 37 | + && $idpSettings['saml-attribute-mapping-user_id_ldap_mapping'] !== '') { |
| 38 | + $userIdLdapMapping = $idpSettings['saml-attribute-mapping-user_id_ldap_mapping']; |
| 39 | + try { |
| 40 | + if ($isActiveDirectory) { |
| 41 | + /** @psalm-suppress UndefinedInterfaceMethod only in NC 34 or above */ |
| 42 | + $user = $this->ldapProviderFactory->getLDAPProvider()->findOneUserByAttributeValue($userIdLdapMapping, $this->formatGuid2ForFilterUser($rawUidCandidate)); |
| 43 | + } else { |
| 44 | + /** @psalm-suppress UndefinedInterfaceMethod only in NC 34 or above */ |
| 45 | + $user = $this->ldapProviderFactory->getLDAPProvider()->findOneUserByAttributeValue($userIdLdapMapping, $rawUidCandidate); |
| 46 | + } |
| 47 | + /** @psalm-suppress UndefinedClass only in NC 34 or above */ |
| 48 | + } catch (MultipleUsersReturnedException $e) { |
| 49 | + return ''; |
| 50 | + } |
| 51 | + if ($user !== null) { |
| 52 | + return $user->getUID(); |
| 53 | + } |
| 54 | + |
| 55 | + // continue normal workflow |
| 56 | + } |
| 57 | + |
25 | 58 | if ($force) { |
26 | 59 | if ($isActiveDirectory) { |
27 | 60 | $this->ensureUser($this->formatGuid2ForFilterUser($rawUidCandidate)); |
@@ -86,14 +119,14 @@ public function findExistingUser(string $rawUidCandidate): IUser { |
86 | 119 | $uid = $this->findExistingUserId($rawUidCandidate); |
87 | 120 | $user = $this->userManager->get($uid); |
88 | 121 | if ($user === null) { |
89 | | - throw new NoUserFoundException('User' . $rawUidCandidate . ' not valid or not found'); |
| 122 | + throw new NoUserFoundException('User ' . $rawUidCandidate . ' not valid or not found.'); |
90 | 123 | } |
91 | 124 | return $user; |
92 | 125 | } |
93 | 126 |
|
94 | | - public function userExists(string $uid, bool $force = false): bool { |
| 127 | + public function userExists(string $uid, array $idpSettings, bool $force = false): bool { |
95 | 128 | try { |
96 | | - $this->findExistingUserId($uid, $force); |
| 129 | + $this->findExistingUserId($uid, $idpSettings, $force); |
97 | 130 | return true; |
98 | 131 | } catch (NoUserFoundException) { |
99 | 132 | return false; |
|
0 commit comments