Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 20 additions & 5 deletions lib/Controller/LoginController.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,7 @@
use OCP\IURLGenerator;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\LDAP\Exceptions\MultipleUsersReturnedException;
use OCP\Security\ICrypto;
use OCP\Security\ISecureRandom;
use OCP\Session\Exceptions\SessionNotAvailableException;
Expand Down Expand Up @@ -634,14 +635,28 @@
$softAutoProvisionAllowed = (!isset($oidcSystemConfig['soft_auto_provision']) || $oidcSystemConfig['soft_auto_provision']);

$shouldDoUserLookup = !$autoProvisionAllowed || ($softAutoProvisionAllowed && !$this->provisioningService->hasOidcUserProvisitioned($userId));
$existingUser = null;
if ($shouldDoUserLookup && $this->ldapService->isLDAPEnabled()) {
// in case user is provisioned by user_ldap, userManager->search() triggers an ldap search which syncs the results
// so new users will be directly available even if they were not synced before this login attempt
$this->userManager->search($userId, 1, 0);
$this->ldapService->syncUser($userId);
$ldapMappingAttribute = $this->providerService->getSetting($providerId, ProviderService::SETTING_LDAP_MAPPING_ATTRIBUTE);
if ($ldapMappingAttribute !== '') {
// Find a user in LDAP with a custom attribute equal to the user id given in OIDC
try {
$existingUser = $this->ldapService->findUserByAttribute($ldapMappingAttribute, $userId);
} catch (MultipleUsersReturnedException $e) {

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 645 in lib/Controller/LoginController.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedClass

lib/Controller/LoginController.php:645:14: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)
$message = $this->l10n->t('The configured LDAP mapping attribute returned more than one users. Please contact an administrator.');
return $this->build403TemplateResponse($message, Http::STATUS_FORBIDDEN);
}
} else {
// in case user is provisioned by user_ldap, userManager->search() triggers an ldap search which syncs the results
// so new users will be directly available even if they were not synced before this login attempt
$this->userManager->search($userId, 1, 0);
$this->ldapService->syncUser($userId);
}
}

$existingUser = $this->userManager->get($userId);
if ($existingUser === null) {
$existingUser = $this->userManager->get($userId);
}
if ($existingUser !== null && $this->ldapService->isLdapDeletedUser($existingUser)) {
$existingUser = null;
}
Expand Down
13 changes: 13 additions & 0 deletions lib/Service/LdapService.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,9 @@
namespace OCA\UserOIDC\Service;

use OCP\App\IAppManager;
use OCP\IConfig;
use OCP\IUser;
use OCP\LDAP\Exceptions\MultipleUsersReturnedException;
use OCP\Server;
use Psr\Container\ContainerExceptionInterface;
use Psr\Log\LoggerInterface;
Expand Down Expand Up @@ -79,4 +81,15 @@
$this->logger->debug('\OCA\User_LDAP\User_Proxy class not found');
}
}

/**
* @throws MultipleUsersReturnedException

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 86 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedDocblockClass

lib/Service/LdapService.php:86:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)
*/
public function findUserByAttribute(string $attribute, string $searchTerm): ?IUser {
if (version_compare(Server::get(IConfig::class)->getSystemValueString('version', '0.0.0'), '34.0.0', '>=')) {
$ldapUserProxy = Server::get(\OCA\User_LDAP\User_Proxy::class);
return $ldapUserProxy->getUserFromCustomAttribute($attribute, $searchTerm);

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)

Check failure on line 91 in lib/Service/LdapService.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedMethod

lib/Service/LdapService.php:91:27: UndefinedMethod: Method OCA\User_LDAP\User_Proxy::getUserFromCustomAttribute does not exist (see https://psalm.dev/022)
}
return null;
}
}
1 change: 1 addition & 0 deletions lib/Service/ProviderService.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ class ProviderService {
public const SETTING_RESTRICT_LOGIN_TO_GROUPS = 'restrictLoginToGroups';
public const SETTING_AZURE_GROUP_NAMES = 'azureGroupNames';
public const SETTING_RESOLVE_NESTED_AND_FALLBACK_CLAIMS_MAPPING = 'nestedAndFallbackClaims';
public const SETTING_LDAP_MAPPING_ATTRIBUTE = 'mappingAttribute';

public const BOOLEAN_SETTINGS_DEFAULT_VALUES = [
self::SETTING_GROUP_PROVISIONING => false,
Expand Down
56 changes: 38 additions & 18 deletions lib/User/Backend.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use OCA\UserOIDC\User\Validator\SelfEncodedValidator;
use OCA\UserOIDC\User\Validator\UserInfoValidator;
use OCP\AppFramework\Db\DoesNotExistException;
use OCP\AppFramework\Http;
use OCP\AppFramework\Utility\ITimeFactory;
use OCP\Authentication\IApacheBackend;
use OCP\DB\Exception;
Expand All @@ -38,6 +39,7 @@
use OCP\IUser;
use OCP\IUserManager;
use OCP\IUserSession;
use OCP\LDAP\Exceptions\MultipleUsersReturnedException;
use OCP\Server;
use OCP\User\Backend\ABackend;
use OCP\User\Backend\ICountUsersBackend;
Expand Down Expand Up @@ -334,13 +336,11 @@

if ($autoProvisionAllowed) {
// look for user in other backends
if (!$this->userManager->userExists($tokenUserId)) {
$this->userManager->search($tokenUserId);
$this->ldapService->syncUser($tokenUserId);
}
$existingUser = $this->userManager->get($tokenUserId);
if ($existingUser !== null && $this->ldapService->isLdapDeletedUser($existingUser)) {
$existingUser = null;
try {
$existingUser = $this->lookupUserInLDAP($provider, $tokenUserId);
} catch (MultipleUsersReturnedException $e) {

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 341 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedClass

lib/User/Backend.php:341:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)
$this->logger->debug('The configured LDAP mapping attribute returned more than one users');
return '';
}

$softAutoProvisionAllowed = (!isset($oidcSystemConfig['soft_auto_provision']) || $oidcSystemConfig['soft_auto_provision']);
Expand Down Expand Up @@ -378,18 +378,13 @@
// check if the user exists locally
// if not, this potentially triggers a user_ldap search
// to get the user if it has not been synced yet
if (!$this->userManager->userExists($tokenUserId)) {
$this->userManager->search($tokenUserId);
$this->ldapService->syncUser($tokenUserId);

// return nothing, if the user was not found after the user_ldap search
if (!$this->userManager->userExists($tokenUserId)) {
return '';
}
try {
$existingUser = $this->lookupUserInLDAP($provider, $tokenUserId);
} catch (MultipleUsersReturnedException $e) {

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)

Check failure on line 383 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedClass

lib/User/Backend.php:383:17: UndefinedClass: Class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/019)
$this->logger->debug('The configured LDAP mapping attribute returned more than one users');
return '';
}

$user = $this->userManager->get($tokenUserId);
if ($user === null || $this->ldapService->isLdapDeletedUser($user)) {
if ($existingUser === null) {
return '';
}
$this->checkFirstLogin($tokenUserId);
Expand All @@ -406,6 +401,31 @@
return '';
}

/**
* @throws MultipleUsersReturnedException

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-master

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable29

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable33

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable31

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable32

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)

Check failure on line 405 in lib/User/Backend.php

View workflow job for this annotation

GitHub Actions / static-psalm-analysis dev-stable30

UndefinedDocblockClass

lib/User/Backend.php:405:13: UndefinedDocblockClass: Docblock-defined class, interface or enum named OCP\LDAP\Exceptions\MultipleUsersReturnedException does not exist (see https://psalm.dev/200)
*/
private function lookupUserInLDAP(Provider $provider, string $tokenUserId): ?IUser {
$existingUser = null;
if ($this->ldapService->isLDAPEnabled()) {
$ldapMappingAttribute = $this->providerService->getSetting($provider->getId(), ProviderService::SETTING_LDAP_MAPPING_ATTRIBUTE);
if ($ldapMappingAttribute !== '') {
// Find a user in LDAP with a custom attribute equal to the user id given in OIDC
$existingUser = $this->ldapService->findUserByAttribute($ldapMappingAttribute, $tokenUserId);
} else if (!$this->userManager->userExists($tokenUserId)) {
$this->userManager->search($tokenUserId);
$this->ldapService->syncUser($tokenUserId);
}

if ($existingUser === null) {
$existingUser = $this->userManager->get($tokenUserId);
}
if ($existingUser !== null && $this->ldapService->isLdapDeletedUser($existingUser)) {
$existingUser = null;
}
}
return $existingUser;
}

/**
* Returns true only if $userId is a non-empty, non-whitespace-only string.
* Used as a lightweight sanity check on user IDs returned by token validators
Expand Down
Loading