Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add IProvideEnabledStateBackend interface #34443

Merged
merged 9 commits into from
Jul 3, 2023
13 changes: 13 additions & 0 deletions apps/user_ldap/js/wizard/wizardTabAdvanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,10 @@ OCA = OCA || {};
$element: $('#ldap_attributes_for_user_search'),
setMethod: 'setSearchAttributesUsers'
},
ldap_mark_remnants_as_disabled: {
$element: $('#ldap_mark_remnants_as_disabled'),
setMethod: 'setMarkRemnantsAsDisabled'
},
ldap_group_display_name: {
$element: $('#ldap_group_display_name'),
setMethod: 'setGroupDisplayName'
Expand Down Expand Up @@ -275,6 +279,15 @@ OCA = OCA || {};
this.setElementValue(this.managedItems.ldap_attributes_for_user_search.$element, attributes);
},

/**
* enables or disables marking remnants as disabled
*
* @param {string} markRemnantsAsDisabled contains an int
*/
setMarkRemnantsAsDisabled: function(markRemnantsAsDisabled) {
this.setElementValue(this.managedItems.ldap_mark_remnants_as_disabled.$element, markRemnantsAsDisabled);
},

/**
* sets the display name attribute for groups
*
Expand Down
3 changes: 3 additions & 0 deletions apps/user_ldap/lib/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class Configuration {
'ldapExpertUsernameAttr' => null,
'ldapExpertUUIDUserAttr' => null,
'ldapExpertUUIDGroupAttr' => null,
'markRemnantsAsDisabled' => false,
'lastJpegPhotoLookup' => null,
'ldapNestedGroups' => false,
'ldapPagingSize' => null,
Expand Down Expand Up @@ -468,6 +469,7 @@ public function getDefaults(): array {
'ldap_expert_uuid_group_attr' => '',
'has_memberof_filter_support' => 0,
'use_memberof_to_detect_membership' => 1,
'ldap_mark_remnants_as_disabled' => 0,
'last_jpegPhoto_lookup' => 0,
'ldap_nested_groups' => 0,
'ldap_paging_size' => 500,
Expand Down Expand Up @@ -543,6 +545,7 @@ public function getConfigTranslationArray(): array {
'ldap_expert_uuid_group_attr' => 'ldapExpertUUIDGroupAttr',
'has_memberof_filter_support' => 'hasMemberOfFilterSupport',
'use_memberof_to_detect_membership' => 'useMemberOfToDetectMembership',
'ldap_mark_remnants_as_disabled' => 'markRemnantsAsDisabled',
'last_jpegPhoto_lookup' => 'lastJpegPhotoLookup',
'ldap_nested_groups' => 'ldapNestedGroups',
'ldap_paging_size' => 'ldapPagingSize',
Expand Down
1 change: 1 addition & 0 deletions apps/user_ldap/lib/Connection.php
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
* @property string ldapEmailAttribute
* @property string ldapExtStorageHomeAttribute
* @property string homeFolderNamingRule
* @property bool|string markRemnantsAsDisabled
* @property bool|string ldapNestedGroups
* @property string[] ldapBaseGroups
* @property string ldapGroupFilter
Expand Down
51 changes: 22 additions & 29 deletions apps/user_ldap/lib/User/DeletedUsersIndex.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,43 +24,35 @@
namespace OCA\User_LDAP\User;

use OCA\User_LDAP\Mapping\UserMapping;
use OCP\IConfig;
use OCP\Share\IManager;

/**
* Class DeletedUsersIndex
* @package OCA\User_LDAP
*/
class DeletedUsersIndex {
/**
* @var \OCP\IConfig $config
*/
protected $config;

/**
* @var \OCA\User_LDAP\Mapping\UserMapping $mapping
*/
protected $mapping;
protected IConfig $config;
protected UserMapping $mapping;
protected ?array $deletedUsers = null;
private IManager $shareManager;

/**
* @var array $deletedUsers
*/
protected $deletedUsers;
/** @var IManager */
private $shareManager;

public function __construct(\OCP\IConfig $config, UserMapping $mapping, IManager $shareManager) {
public function __construct(
IConfig $config,
UserMapping $mapping,
IManager $shareManager
) {
$this->config = $config;
$this->mapping = $mapping;
$this->shareManager = $shareManager;
}

/**
* reads LDAP users marked as deleted from the database
* @return \OCA\User_LDAP\User\OfflineUser[]
* @return OfflineUser[]
*/
private function fetchDeletedUsers() {
$deletedUsers = $this->config->getUsersForUserValue(
'user_ldap', 'isDeleted', '1');
private function fetchDeletedUsers(): array {
$deletedUsers = $this->config->getUsersForUserValue('user_ldap', 'isDeleted', '1');

$userObjects = [];
foreach ($deletedUsers as $user) {
Expand All @@ -73,9 +65,9 @@ private function fetchDeletedUsers() {

/**
* returns all LDAP users that are marked as deleted
* @return \OCA\User_LDAP\User\OfflineUser[]
* @return OfflineUser[]
*/
public function getUsers() {
public function getUsers(): array {
if (is_array($this->deletedUsers)) {
return $this->deletedUsers;
}
Expand All @@ -84,9 +76,8 @@ public function getUsers() {

/**
* whether at least one user was detected as deleted
* @return bool
*/
public function hasUsers() {
public function hasUsers(): bool {
if (!is_array($this->deletedUsers)) {
$this->fetchDeletedUsers();
}
Expand All @@ -96,17 +87,19 @@ public function hasUsers() {
/**
* marks a user as deleted
*
* @param string $ocName
* @throws \OCP\PreConditionNotMetException
*/
public function markUser($ocName) {
$curValue = $this->config->getUserValue($ocName, 'user_ldap', 'isDeleted', '0');
if ($curValue === '1') {
public function markUser(string $ocName): void {
if ($this->isUserMarked($ocName)) {
// the user is already marked, do not write to DB again
return;
}
$this->config->setUserValue($ocName, 'user_ldap', 'isDeleted', '1');
$this->config->setUserValue($ocName, 'user_ldap', 'foundDeleted', (string)time());
$this->deletedUsers = null;
}

public function isUserMarked(string $ocName): bool {
return ($this->config->getUserValue($ocName, 'user_ldap', 'isDeleted', '0') === '1');
}
}
66 changes: 41 additions & 25 deletions apps/user_ldap/lib/User_LDAP.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@
use OC\User\Backend;
use OC\User\NoUserException;
use OCA\User_LDAP\Exceptions\NotOnLDAP;
use OCA\User_LDAP\User\DeletedUsersIndex;
use OCA\User_LDAP\User\OfflineUser;
use OCA\User_LDAP\User\User;
use OCP\IConfig;
Expand All @@ -50,34 +51,32 @@
use OCP\Notification\IManager as INotificationManager;
use OCP\User\Backend\ICountMappedUsersBackend;
use OCP\User\Backend\ICountUsersBackend;
use OCP\User\Backend\IProvideEnabledStateBackend;
use OCP\UserInterface;
use Psr\Log\LoggerInterface;

class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend {
/** @var \OCP\IConfig */
protected $ocConfig;

/** @var INotificationManager */
protected $notificationManager;

/** @var UserPluginManager */
protected $userPluginManager;

/** @var LoggerInterface */
protected $logger;

/**
* @param Access $access
* @param \OCP\IConfig $ocConfig
* @param \OCP\Notification\IManager $notificationManager
* @param IUserSession $userSession
*/
public function __construct(Access $access, IConfig $ocConfig, INotificationManager $notificationManager, IUserSession $userSession, UserPluginManager $userPluginManager) {
class User_LDAP extends BackendUtility implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
protected IConfig $ocConfig;
protected INotificationManager $notificationManager;
protected UserPluginManager $userPluginManager;
protected LoggerInterface $logger;
protected DeletedUsersIndex $deletedUsersIndex;

public function __construct(
Access $access,
IConfig $ocConfig,
INotificationManager $notificationManager,
IUserSession $userSession,
UserPluginManager $userPluginManager,
LoggerInterface $logger,
DeletedUsersIndex $deletedUsersIndex,
) {
parent::__construct($access);
$this->ocConfig = $ocConfig;
$this->notificationManager = $notificationManager;
$this->userPluginManager = $userPluginManager;
$this->logger = \OC::$server->get(LoggerInterface::class);
$this->logger = $logger;
$this->deletedUsersIndex = $deletedUsersIndex;
}

/**
Expand Down Expand Up @@ -392,21 +391,21 @@ public function deleteUser($uid) {
}
}

$marked = (int)$this->ocConfig->getUserValue($uid, 'user_ldap', 'isDeleted', 0);
if ($marked === 0) {
$marked = $this->deletedUsersIndex->isUserMarked($uid);
if (!$marked) {
try {
$user = $this->access->userManager->get($uid);
if (($user instanceof User) && !$this->userExistsOnLDAP($uid, true)) {
$user->markUser();
$marked = 1;
$marked = true;
}
} catch (\Exception $e) {
$this->logger->debug(
$e->getMessage(),
['app' => 'user_ldap', 'exception' => $e]
);
}
if ($marked === 0) {
if (!$marked) {
$this->logger->notice(
'User '.$uid . ' is not marked as deleted, not cleaning up.',
['app' => 'user_ldap']
Expand Down Expand Up @@ -669,4 +668,21 @@ public function createUser($username, $password) {
}
return false;
}

public function isUserEnabled(string $uid, callable $queryDatabaseValue): bool {
if ($this->deletedUsersIndex->isUserMarked($uid) && ((int)$this->access->connection->markRemnantsAsDisabled === 1)) {
return false;
} else {
return $queryDatabaseValue();
}
}

public function setUserEnabled(string $uid, bool $enabled, callable $queryDatabaseValue, callable $setDatabaseValue): bool {
$setDatabaseValue($enabled);
return $enabled;
}

public function getDisabledUserList(int $offset = 0, ?int $limit = null): array {
throw new \Exception('This is implemented directly in User_Proxy');
}
nfebe marked this conversation as resolved.
Show resolved Hide resolved
}
53 changes: 44 additions & 9 deletions apps/user_ldap/lib/User_Proxy.php
Original file line number Diff line number Diff line change
Expand Up @@ -31,27 +31,32 @@
*/
namespace OCA\User_LDAP;

use OCA\User_LDAP\User\DeletedUsersIndex;
use OCA\User_LDAP\User\OfflineUser;
use OCA\User_LDAP\User\User;
use OCP\IConfig;
use OCP\IUserBackend;
use OCP\IUserSession;
use OCP\Notification\IManager as INotificationManager;
use OCP\UserInterface;
use OCP\User\Backend\ICountMappedUsersBackend;
use OCP\User\Backend\ICountUsersBackend;
use OCP\UserInterface;
use OCP\User\Backend\IProvideEnabledStateBackend;
use Psr\Log\LoggerInterface;

class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend {
/** @var array<string,User_LDAP> */
private $backends = [];
/** @var ?User_LDAP */
private $refBackend = null;
class User_Proxy extends Proxy implements IUserBackend, UserInterface, IUserLDAP, ICountUsersBackend, ICountMappedUsersBackend, IProvideEnabledStateBackend {
/** @var User_LDAP[] */
private array $backends = [];
private ?User_LDAP $refBackend = null;

private bool $isSetUp = false;
private Helper $helper;
private IConfig $ocConfig;
private INotificationManager $notificationManager;
private IUserSession $userSession;
private UserPluginManager $userPluginManager;
private LoggerInterface $logger;
private DeletedUsersIndex $deletedUsersIndex;

public function __construct(
Helper $helper,
Expand All @@ -60,14 +65,18 @@ public function __construct(
IConfig $ocConfig,
INotificationManager $notificationManager,
IUserSession $userSession,
UserPluginManager $userPluginManager
UserPluginManager $userPluginManager,
LoggerInterface $logger,
DeletedUsersIndex $deletedUsersIndex,
) {
parent::__construct($ldap, $accessFactory);
$this->helper = $helper;
$this->ocConfig = $ocConfig;
$this->notificationManager = $notificationManager;
$this->userSession = $userSession;
$this->userPluginManager = $userPluginManager;
$this->logger = $logger;
$this->deletedUsersIndex = $deletedUsersIndex;
}

protected function setup(): void {
Expand All @@ -77,8 +86,15 @@ protected function setup(): void {

$serverConfigPrefixes = $this->helper->getServerConfigurationPrefixes(true);
foreach ($serverConfigPrefixes as $configPrefix) {
$this->backends[$configPrefix] =
new User_LDAP($this->getAccess($configPrefix), $this->ocConfig, $this->notificationManager, $this->userSession, $this->userPluginManager);
$this->backends[$configPrefix] = new User_LDAP(
$this->getAccess($configPrefix),
$this->ocConfig,
$this->notificationManager,
$this->userSession,
$this->userPluginManager,
$this->logger,
$this->deletedUsersIndex,
);

if (is_null($this->refBackend)) {
$this->refBackend = &$this->backends[$configPrefix];
Expand Down Expand Up @@ -438,4 +454,23 @@ public function getNewLDAPConnection($uid) {
public function createUser($username, $password) {
return $this->handleRequest($username, 'createUser', [$username, $password]);
}

public function isUserEnabled(string $uid, callable $queryDatabaseValue): bool {
return $this->handleRequest($uid, 'isUserEnabled', [$uid, $queryDatabaseValue]);
}

public function setUserEnabled(string $uid, bool $enabled, callable $queryDatabaseValue, callable $setDatabaseValue): bool {
return $this->handleRequest($uid, 'setUserEnabled', [$uid, $enabled, $queryDatabaseValue, $setDatabaseValue]);
}

public function getDisabledUserList(int $offset = 0, ?int $limit = null): array {
return array_map(
fn (OfflineUser $user) => $user->getOCName(),
array_slice(
$this->deletedUsersIndex->getUsers(),
$offset,
$limit
)
);
}
}
Loading