Skip to content

Commit

Permalink
Merge pull request #34443 from nextcloud/feat/add-enabled-user-backend
Browse files Browse the repository at this point in the history
Add IProvideEnabledStateBackend interface
  • Loading branch information
come-nc authored Jul 3, 2023
2 parents 5d9d37e + 189ccc2 commit b2f01b7
Show file tree
Hide file tree
Showing 19 changed files with 355 additions and 179 deletions.
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');
}
}
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

0 comments on commit b2f01b7

Please sign in to comment.