From 5154cb0a95e7d9d5073443833fd34b525aaa9881 Mon Sep 17 00:00:00 2001 From: Akhil Date: Wed, 18 May 2022 12:44:59 +0530 Subject: [PATCH 01/16] Check if user exists using LDAP backend method --- lib/Service/UserService.php | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-) diff --git a/lib/Service/UserService.php b/lib/Service/UserService.php index 0b8610a1..f32a1256 100644 --- a/lib/Service/UserService.php +++ b/lib/Service/UserService.php @@ -40,7 +40,22 @@ class UserService public function userExists(string $uid): bool { - return $this->userManager->userExists($uid); + $exists = $this->userManager->userExists($uid); + if ($exists) { + return $exists; + } + + $backends = $this->userManager->getBackends(); + foreach ($backends as $backend) { + if ($backend->getBackendName() === 'LDAP') { + $access = $backend->getLDAPAccess($uid); + $users = $access->fetchUsersByLoginName($uid) ; + if (count($users) > 0) { + $exists = true; + } + } + } + return $exists; } public function getUser(string $uid): ?IUser @@ -75,8 +90,8 @@ class UserService try { $this->config->setUserValue($uid, 'hide-my-email', 'email-aliases', $aliases); return true; - } catch(UnexpectedValueException $e) { + } catch (UnexpectedValueException $e) { return false; - } + } } } -- GitLab From b7584a1a9f556cc6000596f2b528ac8f93d658be Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 19 May 2022 15:53:48 +0530 Subject: [PATCH 02/16] Remove mailbox mapper and user changed listener --- appinfo/info.xml | 2 +- lib/Db/MailboxMapper.php | 61 --------------------------- lib/Listeners/UserChangedListener.php | 47 --------------------- 3 files changed, 1 insertion(+), 109 deletions(-) delete mode 100644 lib/Db/MailboxMapper.php delete mode 100644 lib/Listeners/UserChangedListener.php diff --git a/appinfo/info.xml b/appinfo/info.xml index e9d62deb..2803cce9 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -10,7 +10,7 @@ - 1.2.0 + 2.0.0 agpl Akhil Potukuchi EcloudAccounts diff --git a/lib/Db/MailboxMapper.php b/lib/Db/MailboxMapper.php deleted file mode 100644 index fb21bc77..00000000 --- a/lib/Db/MailboxMapper.php +++ /dev/null @@ -1,61 +0,0 @@ -config = $config; - $this->logger = $logger; - $params = $this->getConnectionParams(); - $this->conn = DriverManager::getConnection($params); - } - - - private function getConnectionParams() - { - $config = $this->config->getSystemValue('user_backend_sql_raw'); - - if (!$config) { - throw new DbConnectionParamsException('Database connection params for mailbox not available in config.php!'); - } - - $params = [ - 'dbname' => $config['db_name'], - 'charset' => $config['mariadb_charset'], - 'user' => $config['db_user'], - 'password' => $config['db_password'], - 'host' => $config['db_host'], - 'port' => $config['db_port'], - 'driver' => 'pdo_mysql' - ]; - return $params; - } - - public function updateMailboxQuota(string $username, int $quotaInMb) - { - try { - $qb = $this->conn->createQueryBuilder(); - $qb->update('mailbox', 'm') - ->set('m.quota', $quotaInMb) - ->where('m.username = :username') - ->setParameter('username', $username); - - $qb->execute(); - } catch (Exception $e) { - $this->logger->error('Error setting mailbox quota of user ' . $username . ' to ' . strval($quotaInMb) . ': ' . $e->getMessage()); - } - } -} diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php deleted file mode 100644 index c62e2541..00000000 --- a/lib/Listeners/UserChangedListener.php +++ /dev/null @@ -1,47 +0,0 @@ -util = $util; - $this->mailboxMapper = $mailboxMapper; - } - - public function handle(Event $event): void - { - if (!($event instanceof UserChangedEvent)) { - return; - } - - $feature = $event->getFeature(); - - if ($feature !== self::QUOTA_FEATURE) { - return; - } - - $user = $event->getUser(); - $username = $user->getUID(); - $updatedQuota = $event->getValue(); - - $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); - $this->mailboxMapper->updateMailboxQuota($username, $quotaInBytes); - } -} -- GitLab From 773b2a14bfb407250e7f45ab8d4041690d65aae5 Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 19 May 2022 17:06:21 +0530 Subject: [PATCH 03/16] Delete aliases during user deletion --- lib/Listeners/UserDeletedListener.php | 87 +++++++++++++++++++++++++-- 1 file changed, 82 insertions(+), 5 deletions(-) diff --git a/lib/Listeners/UserDeletedListener.php b/lib/Listeners/UserDeletedListener.php index 25e98359..539d0c7d 100644 --- a/lib/Listeners/UserDeletedListener.php +++ b/lib/Listeners/UserDeletedListener.php @@ -5,34 +5,47 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Listeners; use Curl; +use Exception; use OCA\EcloudAccounts\AppInfo\Application; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\IConfig; use OCP\ILogger; +use OCP\IUserManager; use OCP\User\Events\UserDeletedEvent; require_once 'curl.class.php'; class UserDeletedListener implements IEventListener { - private $logger; private $config; - public function __construct(ILogger $logger, IConfig $config) + public function __construct(ILogger $logger, IConfig $config, IUserManager $userManager) { $this->logger = $logger; $this->config = $config; } + public function handle(Event $event): void { if (!($event instanceof UserDeletedEvent)) { return; } - $uid = $event->getUser()->getUID(); + $user = $event->getUser(); + $email = $user->getEMailAddress(); + $uid = $user->getUID(); + + try { + $conn = $this->getLDAPConnection($uid); + $this->deleteAliasEntries($conn, $email); + } + catch (Exception $e) { + $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); + } + $this->logger->info("PostDelete user {user}", array('user' => $uid)); $this->ecloudDelete( $uid, @@ -53,7 +66,6 @@ class UserDeletedListener implements IEventListener */ public function ecloudDelete(string $userID, string $welcomeDomain, string $welcomeSecret) { - $postDeleteUrl = "https://" . $welcomeDomain . "/postDelete.php"; $curl = new Curl(); @@ -62,7 +74,6 @@ class UserDeletedListener implements IEventListener * Handling the non NC part of deletion process */ try { - $headers = array( 'Content-Type: application/json' ); @@ -81,4 +92,70 @@ class UserDeletedListener implements IEventListener return null; } + + private function deleteAliasEntries($conn, string $email) + { + $aliasBaseDn = getenv('LDAP_ALIASES_BASE_DN'); + $aliasDns = $this->getAliasEntries($conn, $aliasBaseDn, $email); + foreach($aliasDns as $aliasDn) { + $deleted = ldap_delete($conn, $aliasDn); + if(!$deleted) { + $this->logger->error('Deleting alias ' . $aliasDn . ' for email ' . $email . ' failed'); + } + } + } + + private function getAliasEntries($conn, string $aliasBaseDn, string $email) : array + { + $filter = "(mailAddress=$email)"; + $aliasEntries = ldap_search($conn, $aliasBaseDn, $filter); + if (!$aliasEntries) { + return []; + } + + $aliasEntries = ldap_get_entries($conn, $aliasEntries); + $aliasEntries = array_filter($aliasEntries, fn($entry) => is_array($entry)); + $aliasEntries = array_map( + fn ($entry) => $entry['dn'], + $aliasEntries + ); + + return $aliasEntries; + } + + private function getLDAPConnection(string $uid) + { + $backends = $this->userManager->getBackends(); + $conn = null; + foreach ($backends as $backend) { + if ($backend->getBackendName() === 'LDAP') { + $access = $backend->getLDAPAccess($uid); + $connection = $access->getConnection(); + $configuration = $connection->getConfiguration(); + + if (!$configuration->ldapConfigurationActive) { + continue; + } + + $adminDn = $configuration->ldapAgentName; + $adminPassword = $configuration->ldapAgentPassword; + $host = $configuration->ldapHost; + $port = $configuration->ldapPort; + + $conn = ldap_connect($host, $port); + ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_bind($conn, $adminDn, $adminPassword); + + if (!$conn) { + continue; + } + + return $conn; + } + } + + if (!$conn) { + throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); + } + } } -- GitLab From b7dfd7a578426c57b51bf33d3b101d40e6325256 Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 19 May 2022 18:15:09 +0530 Subject: [PATCH 04/16] Added fix for connection to ldap --- lib/Listeners/UserDeletedListener.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/lib/Listeners/UserDeletedListener.php b/lib/Listeners/UserDeletedListener.php index 539d0c7d..fb9f13fd 100644 --- a/lib/Listeners/UserDeletedListener.php +++ b/lib/Listeners/UserDeletedListener.php @@ -20,11 +20,13 @@ class UserDeletedListener implements IEventListener { private $logger; private $config; + private $userManager; public function __construct(ILogger $logger, IConfig $config, IUserManager $userManager) { $this->logger = $logger; $this->config = $config; + $this->userManager = $userManager; } @@ -41,6 +43,7 @@ class UserDeletedListener implements IEventListener try { $conn = $this->getLDAPConnection($uid); $this->deleteAliasEntries($conn, $email); + ldap_close($conn); } catch (Exception $e) { $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); @@ -133,14 +136,14 @@ class UserDeletedListener implements IEventListener $connection = $access->getConnection(); $configuration = $connection->getConfiguration(); - if (!$configuration->ldapConfigurationActive) { + if (!$configuration['ldap_configuration_active']) { continue; } - $adminDn = $configuration->ldapAgentName; - $adminPassword = $configuration->ldapAgentPassword; - $host = $configuration->ldapHost; - $port = $configuration->ldapPort; + $adminDn = $configuration['ldap_dn']; + $adminPassword = $configuration['ldap_agent_password']; + $host = $configuration['ldap_host']; + $port = intval($configuration['ldap_port']); $conn = ldap_connect($host, $port); ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); -- GitLab From eca414ad74a8b766955a86013b825d8cdd6a6ca4 Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 19 May 2022 21:16:10 +0530 Subject: [PATCH 05/16] Added before user deleted listener to delete aliases --- lib/AppInfo/Application.php | 7 +- lib/Listeners/BeforeUserDeletedListener.php | 115 ++++++++++++++++++++ lib/Listeners/UserDeletedListener.php | 79 +------------- 3 files changed, 120 insertions(+), 81 deletions(-) create mode 100644 lib/Listeners/BeforeUserDeletedListener.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index 799c6b78..f4a5ec51 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -32,9 +32,10 @@ use OCP\AppFramework\Bootstrap\IBootstrap; use OCP\AppFramework\Bootstrap\IRegistrationContext; use OCP\AppFramework\Bootstrap\IBootContext; use OCP\User\Events\UserDeletedEvent; -use OCP\User\Events\UserChangedEvent; use OCA\EcloudAccounts\Listeners\UserDeletedListener; -use OCA\EcloudAccounts\Listeners\UserChangedListener; +use OCA\EcloudAccounts\Listeners\BeforeUserDeletedListener; +use OCP\User\Events\BeforeUserDeletedEvent; + class Application extends App implements IBootstrap { @@ -49,7 +50,7 @@ class Application extends App implements IBootstrap public function register(IRegistrationContext $context): void { $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); - $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); + $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); } public function boot(IBootContext $context): void diff --git a/lib/Listeners/BeforeUserDeletedListener.php b/lib/Listeners/BeforeUserDeletedListener.php new file mode 100644 index 00000000..68adb425 --- /dev/null +++ b/lib/Listeners/BeforeUserDeletedListener.php @@ -0,0 +1,115 @@ +logger = $logger; + $this->config = $config; + $this->userManager = $userManager; + } + + + public function handle(Event $event): void + { + if (!($event instanceof BeforeUserDeletedEvent)) { + return; + } + + $user = $event->getUser(); + $email = $user->getEMailAddress(); + $uid = $user->getUID(); + + try { + $conn = $this->getLDAPConnection($uid); + $this->deleteAliasEntries($conn, $email); + ldap_close($conn); + } + catch (Exception $e) { + $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); + } + + } + + private function deleteAliasEntries($conn, string $email) + { + $aliasBaseDn = getenv('LDAP_ALIASES_BASE_DN'); + $aliasDns = $this->getAliasEntries($conn, $aliasBaseDn, $email); + foreach($aliasDns as $aliasDn) { + $deleted = ldap_delete($conn, $aliasDn); + if(!$deleted) { + $this->logger->error('Deleting alias ' . $aliasDn . ' for email ' . $email . ' failed'); + } + } + } + + private function getAliasEntries($conn, string $aliasBaseDn, string $email) : array + { + $filter = "(mailAddress=$email)"; + $aliasEntries = ldap_search($conn, $aliasBaseDn, $filter); + if (!$aliasEntries) { + return []; + } + + $aliasEntries = ldap_get_entries($conn, $aliasEntries); + $aliasEntries = array_filter($aliasEntries, fn($entry) => is_array($entry)); + $aliasEntries = array_map( + fn ($entry) => $entry['dn'], + $aliasEntries + ); + + return $aliasEntries; + } + + private function getLDAPConnection(string $uid) + { + $backends = $this->userManager->getBackends(); + $conn = null; + foreach ($backends as $backend) { + if ($backend->getBackendName() === 'LDAP') { + $access = $backend->getLDAPAccess($uid); + $connection = $access->getConnection(); + $configuration = $connection->getConfiguration(); + + if (!$configuration['ldap_configuration_active']) { + continue; + } + + $adminDn = $configuration['ldap_dn']; + $adminPassword = $configuration['ldap_agent_password']; + $host = $configuration['ldap_host']; + $port = intval($configuration['ldap_port']); + + $conn = ldap_connect($host, $port); + ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_bind($conn, $adminDn, $adminPassword); + + if (!$conn) { + continue; + } + + return $conn; + } + } + + if (!$conn) { + throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); + } + } +} diff --git a/lib/Listeners/UserDeletedListener.php b/lib/Listeners/UserDeletedListener.php index fb9f13fd..e0b87818 100644 --- a/lib/Listeners/UserDeletedListener.php +++ b/lib/Listeners/UserDeletedListener.php @@ -36,18 +36,7 @@ class UserDeletedListener implements IEventListener return; } - $user = $event->getUser(); - $email = $user->getEMailAddress(); - $uid = $user->getUID(); - - try { - $conn = $this->getLDAPConnection($uid); - $this->deleteAliasEntries($conn, $email); - ldap_close($conn); - } - catch (Exception $e) { - $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); - } + $uid = $event->getUser()->getUID(); $this->logger->info("PostDelete user {user}", array('user' => $uid)); $this->ecloudDelete( @@ -95,70 +84,4 @@ class UserDeletedListener implements IEventListener return null; } - - private function deleteAliasEntries($conn, string $email) - { - $aliasBaseDn = getenv('LDAP_ALIASES_BASE_DN'); - $aliasDns = $this->getAliasEntries($conn, $aliasBaseDn, $email); - foreach($aliasDns as $aliasDn) { - $deleted = ldap_delete($conn, $aliasDn); - if(!$deleted) { - $this->logger->error('Deleting alias ' . $aliasDn . ' for email ' . $email . ' failed'); - } - } - } - - private function getAliasEntries($conn, string $aliasBaseDn, string $email) : array - { - $filter = "(mailAddress=$email)"; - $aliasEntries = ldap_search($conn, $aliasBaseDn, $filter); - if (!$aliasEntries) { - return []; - } - - $aliasEntries = ldap_get_entries($conn, $aliasEntries); - $aliasEntries = array_filter($aliasEntries, fn($entry) => is_array($entry)); - $aliasEntries = array_map( - fn ($entry) => $entry['dn'], - $aliasEntries - ); - - return $aliasEntries; - } - - private function getLDAPConnection(string $uid) - { - $backends = $this->userManager->getBackends(); - $conn = null; - foreach ($backends as $backend) { - if ($backend->getBackendName() === 'LDAP') { - $access = $backend->getLDAPAccess($uid); - $connection = $access->getConnection(); - $configuration = $connection->getConfiguration(); - - if (!$configuration['ldap_configuration_active']) { - continue; - } - - $adminDn = $configuration['ldap_dn']; - $adminPassword = $configuration['ldap_agent_password']; - $host = $configuration['ldap_host']; - $port = intval($configuration['ldap_port']); - - $conn = ldap_connect($host, $port); - ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_bind($conn, $adminDn, $adminPassword); - - if (!$conn) { - continue; - } - - return $conn; - } - } - - if (!$conn) { - throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); - } - } } -- GitLab From 6aa05c7a67eeab239fe840c906552cbff7b10294 Mon Sep 17 00:00:00 2001 From: Akhil Date: Thu, 19 May 2022 23:45:13 +0530 Subject: [PATCH 06/16] Use postDeleteLDAP.php --- lib/Listeners/UserDeletedListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Listeners/UserDeletedListener.php b/lib/Listeners/UserDeletedListener.php index e0b87818..52319b9c 100644 --- a/lib/Listeners/UserDeletedListener.php +++ b/lib/Listeners/UserDeletedListener.php @@ -58,7 +58,7 @@ class UserDeletedListener implements IEventListener */ public function ecloudDelete(string $userID, string $welcomeDomain, string $welcomeSecret) { - $postDeleteUrl = "https://" . $welcomeDomain . "/postDelete.php"; + $postDeleteUrl = "https://" . $welcomeDomain . "/postDeleteLDAP.php"; $curl = new Curl(); /** -- GitLab From 2a820b5c19e5b2ec6b653075a9893c74b344c944 Mon Sep 17 00:00:00 2001 From: Akhil Date: Fri, 20 May 2022 17:30:55 +0530 Subject: [PATCH 07/16] Register LDAPConnectionService --- lib/AppInfo/Application.php | 5 ++ lib/Listeners/BeforeUserDeletedListener.php | 61 ++++----------------- lib/Service/LDAPConnectionService.php | 59 ++++++++++++++++++++ 3 files changed, 74 insertions(+), 51 deletions(-) create mode 100644 lib/Service/LDAPConnectionService.php diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index f4a5ec51..e8a30518 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -34,6 +34,7 @@ use OCP\AppFramework\Bootstrap\IBootContext; use OCP\User\Events\UserDeletedEvent; use OCA\EcloudAccounts\Listeners\UserDeletedListener; use OCA\EcloudAccounts\Listeners\BeforeUserDeletedListener; +use OCA\EcloudAccounts\Service\LDAPConnectionService; use OCP\User\Events\BeforeUserDeletedEvent; @@ -55,5 +56,9 @@ class Application extends App implements IBootstrap public function boot(IBootContext $context): void { + $serverContainer = $context->getServerContainer(); + $serverContainer->registerService('LDAPConnectionService', function($c) { + return new LDAPConnectionService(); + }); } } diff --git a/lib/Listeners/BeforeUserDeletedListener.php b/lib/Listeners/BeforeUserDeletedListener.php index 68adb425..c92c38ba 100644 --- a/lib/Listeners/BeforeUserDeletedListener.php +++ b/lib/Listeners/BeforeUserDeletedListener.php @@ -7,22 +7,19 @@ namespace OCA\EcloudAccounts\Listeners; use Exception; use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; -use OCP\IConfig; use OCP\ILogger; -use OCP\IUserManager; use OCP\User\Events\BeforeUserDeletedEvent; +use OCA\EcloudAccounts\Service\LDAPConnectionService; class BeforeUserDeletedListener implements IEventListener { private $logger; - private $config; - private $userManager; + private $LDAPConnectionService; - public function __construct(ILogger $logger, IConfig $config, IUserManager $userManager) + public function __construct(ILogger $logger, LDAPConnectionService $LDAPConnectionService) { $this->logger = $logger; - $this->config = $config; - $this->userManager = $userManager; + $this->LDAPConnectionService = $LDAPConnectionService; } @@ -37,23 +34,21 @@ class BeforeUserDeletedListener implements IEventListener $uid = $user->getUID(); try { - $conn = $this->getLDAPConnection($uid); + $conn = $this->LDAPConnectionService->getLDAPConnection($uid); $this->deleteAliasEntries($conn, $email); - ldap_close($conn); - } - catch (Exception $e) { + $this->LDAPConnectionService->closeLDAPConnection($conn); + } catch (Exception $e) { $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); } - } private function deleteAliasEntries($conn, string $email) { $aliasBaseDn = getenv('LDAP_ALIASES_BASE_DN'); $aliasDns = $this->getAliasEntries($conn, $aliasBaseDn, $email); - foreach($aliasDns as $aliasDn) { + foreach ($aliasDns as $aliasDn) { $deleted = ldap_delete($conn, $aliasDn); - if(!$deleted) { + if (!$deleted) { $this->logger->error('Deleting alias ' . $aliasDn . ' for email ' . $email . ' failed'); } } @@ -68,7 +63,7 @@ class BeforeUserDeletedListener implements IEventListener } $aliasEntries = ldap_get_entries($conn, $aliasEntries); - $aliasEntries = array_filter($aliasEntries, fn($entry) => is_array($entry)); + $aliasEntries = array_filter($aliasEntries, fn ($entry) => is_array($entry)); $aliasEntries = array_map( fn ($entry) => $entry['dn'], $aliasEntries @@ -76,40 +71,4 @@ class BeforeUserDeletedListener implements IEventListener return $aliasEntries; } - - private function getLDAPConnection(string $uid) - { - $backends = $this->userManager->getBackends(); - $conn = null; - foreach ($backends as $backend) { - if ($backend->getBackendName() === 'LDAP') { - $access = $backend->getLDAPAccess($uid); - $connection = $access->getConnection(); - $configuration = $connection->getConfiguration(); - - if (!$configuration['ldap_configuration_active']) { - continue; - } - - $adminDn = $configuration['ldap_dn']; - $adminPassword = $configuration['ldap_agent_password']; - $host = $configuration['ldap_host']; - $port = intval($configuration['ldap_port']); - - $conn = ldap_connect($host, $port); - ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_bind($conn, $adminDn, $adminPassword); - - if (!$conn) { - continue; - } - - return $conn; - } - } - - if (!$conn) { - throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); - } - } } diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php new file mode 100644 index 00000000..d5c4d7d4 --- /dev/null +++ b/lib/Service/LDAPConnectionService.php @@ -0,0 +1,59 @@ +userManager = $userManager; + } + + public function getLDAPConnection(string $uid) + { + $backends = $this->userManager->getBackends(); + $conn = null; + foreach ($backends as $backend) { + if ($backend->getBackendName() === 'LDAP') { + $access = $backend->getLDAPAccess($uid); + $connection = $access->getConnection(); + $configuration = $connection->getConfiguration(); + + if (!$configuration['ldap_configuration_active']) { + continue; + } + + $adminDn = $configuration['ldap_dn']; + $adminPassword = $configuration['ldap_agent_password']; + $host = $configuration['ldap_host']; + $port = intval($configuration['ldap_port']); + + $conn = ldap_connect($host, $port); + ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_bind($conn, $adminDn, $adminPassword); + + if (!$conn) { + continue; + } + + return $conn; + } + } + + if (!$conn) { + throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); + } + } + + public function closeLDAPConnection($conn) : void { + ldap_close($conn); + } +} -- GitLab From 5c7dd662c0b1bee244ef56f54a1d01599990bf26 Mon Sep 17 00:00:00 2001 From: Akhil Date: Mon, 23 May 2022 22:25:09 +0530 Subject: [PATCH 08/16] Remove username from ldap configuration gettor --- lib/Listeners/BeforeUserDeletedListener.php | 8 +-- lib/Service/LDAPConnectionService.php | 60 ++++++++++++++------- 2 files changed, 45 insertions(+), 23 deletions(-) diff --git a/lib/Listeners/BeforeUserDeletedListener.php b/lib/Listeners/BeforeUserDeletedListener.php index c92c38ba..91653a44 100644 --- a/lib/Listeners/BeforeUserDeletedListener.php +++ b/lib/Listeners/BeforeUserDeletedListener.php @@ -34,9 +34,11 @@ class BeforeUserDeletedListener implements IEventListener $uid = $user->getUID(); try { - $conn = $this->LDAPConnectionService->getLDAPConnection($uid); - $this->deleteAliasEntries($conn, $email); - $this->LDAPConnectionService->closeLDAPConnection($conn); + if ($this->LDAPConnectionService->isLDAPEnabled()) { + $conn = $this->LDAPConnectionService->getLDAPConnection($uid); + $this->deleteAliasEntries($conn, $email); + $this->LDAPConnectionService->closeLDAPConnection($conn); + } } catch (Exception $e) { $this->logger->error('Error deleting aliases for user '. $uid . ' :' . $e->getMessage()); } diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index d5c4d7d4..0a9ae3d8 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -12,48 +12,68 @@ class LDAPConnectionService /** @var IUserManager */ private $userManager; + private $configuration; + + private $LDAPEnabled; + public function __construct(IUserManager $userManager) { $this->userManager = $userManager; + $this->getConfigurationFromBackend(); } - public function getLDAPConnection(string $uid) + + private function getConfigurationFromBackend() { + // We don't actually need user id to get access from backend + $uid = ''; $backends = $this->userManager->getBackends(); - $conn = null; foreach ($backends as $backend) { if ($backend->getBackendName() === 'LDAP') { $access = $backend->getLDAPAccess($uid); $connection = $access->getConnection(); $configuration = $connection->getConfiguration(); - if (!$configuration['ldap_configuration_active']) { - continue; + if ($configuration['ldap_configuration_active']) { + $this->LDAPEnabled = true; + $this->configuration = $configuration; + break; } + } + } + } - $adminDn = $configuration['ldap_dn']; - $adminPassword = $configuration['ldap_agent_password']; - $host = $configuration['ldap_host']; - $port = intval($configuration['ldap_port']); - - $conn = ldap_connect($host, $port); - ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); - ldap_bind($conn, $adminDn, $adminPassword); + public function isLDAPEnabled() : bool { + return $this->LDAPEnabled; + } + + public function getUserBaseDn() : string + { + if (isset($this->configuration['ldap_base_users'])) { + return $this->configuration['ldap_base_users']; + } + throw new Exception('User Base Dn not set!'); + } - if (!$conn) { - continue; - } + public function getLDAPConnection() + { + $adminDn = $this->configuration['ldap_dn']; + $adminPassword = $this->configuration['ldap_agent_password']; + $host = $this->configuration['ldap_host']; + $port = intval($this->configuration['ldap_port']); - return $conn; - } - } + $conn = ldap_connect($host, $port); + ldap_set_option($conn, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_bind($conn, $adminDn, $adminPassword); if (!$conn) { - throw new Exception('Could not connect to LDAP server to delete aliases for user ' . $uid); + throw new Exception('Could not connect to LDAP server!'); } + return $conn; } - public function closeLDAPConnection($conn) : void { + public function closeLDAPConnection($conn) : void + { ldap_close($conn); } } -- GitLab From 1d3a664b9a3b9ab82f074eb5bdd0482ad8cdf9bd Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 14:12:30 +0530 Subject: [PATCH 09/16] Update quota in LDAP when admin updates --- lib/Listeners/UserChangedListener.php | 64 +++++++++++++++++++++++++++ lib/Service/LDAPConnectionService.php | 11 ++++- 2 files changed, 73 insertions(+), 2 deletions(-) create mode 100644 lib/Listeners/UserChangedListener.php diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php new file mode 100644 index 00000000..a2d353c3 --- /dev/null +++ b/lib/Listeners/UserChangedListener.php @@ -0,0 +1,64 @@ +util = $util; + $this->ldapConnectionService = $LDAPConnectionService; + $this->logger = $logger; + } + + public function handle(Event $event): void + { + if (!($event instanceof UserChangedEvent)) { + return; + } + + $feature = $event->getFeature(); + + if ($feature !== self::QUOTA_FEATURE) { + return; + } + $user = $event->getUser(); + $username = $user->getUID(); + $updatedQuota = $event->getValue(); + + try { + $conn = $this->ldapConnectionService->getLDAPConnection(); + $userDn = $this->ldapConnectionService->username2dn($username); + $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); + + $entry = [ + 'quota' => $quotaInBytes + ]; + + if (!ldap_modify($conn, $userDn, $entry)) { + throw new Exception('Could not modify user entry at LDAP server!'); + } + $this->ldapConnectionService->closeLDAPConnection($conn); + } catch (Exception $e) { + $this->logger->error("Error setting quota for user $username " . $e->getMessage()); + } + } +} diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index 0a9ae3d8..43fa2afa 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -16,6 +16,8 @@ class LDAPConnectionService private $LDAPEnabled; + private $access; + public function __construct(IUserManager $userManager) { $this->userManager = $userManager; @@ -30,8 +32,8 @@ class LDAPConnectionService $backends = $this->userManager->getBackends(); foreach ($backends as $backend) { if ($backend->getBackendName() === 'LDAP') { - $access = $backend->getLDAPAccess($uid); - $connection = $access->getConnection(); + $this->access = $backend->getLDAPAccess($uid); + $connection = $this->access->getConnection(); $configuration = $connection->getConfiguration(); if ($configuration['ldap_configuration_active']) { @@ -46,7 +48,12 @@ class LDAPConnectionService public function isLDAPEnabled() : bool { return $this->LDAPEnabled; } + + public function username2dn(string $username) { + return $this->access->username2dn($username); + } + public function getUserBaseDn() : string { if (isset($this->configuration['ldap_base_users'])) { -- GitLab From 03d5a5db0f91c308fe6faa93e04e1814d2a06412 Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 14:23:29 +0530 Subject: [PATCH 10/16] Add mailboxMapper --- lib/Db/MailboxMapper.php | 61 +++++++++++++++++++++++++++ lib/Listeners/UserChangedListener.php | 27 +++++++++--- 2 files changed, 83 insertions(+), 5 deletions(-) create mode 100644 lib/Db/MailboxMapper.php diff --git a/lib/Db/MailboxMapper.php b/lib/Db/MailboxMapper.php new file mode 100644 index 00000000..fb21bc77 --- /dev/null +++ b/lib/Db/MailboxMapper.php @@ -0,0 +1,61 @@ +config = $config; + $this->logger = $logger; + $params = $this->getConnectionParams(); + $this->conn = DriverManager::getConnection($params); + } + + + private function getConnectionParams() + { + $config = $this->config->getSystemValue('user_backend_sql_raw'); + + if (!$config) { + throw new DbConnectionParamsException('Database connection params for mailbox not available in config.php!'); + } + + $params = [ + 'dbname' => $config['db_name'], + 'charset' => $config['mariadb_charset'], + 'user' => $config['db_user'], + 'password' => $config['db_password'], + 'host' => $config['db_host'], + 'port' => $config['db_port'], + 'driver' => 'pdo_mysql' + ]; + return $params; + } + + public function updateMailboxQuota(string $username, int $quotaInMb) + { + try { + $qb = $this->conn->createQueryBuilder(); + $qb->update('mailbox', 'm') + ->set('m.quota', $quotaInMb) + ->where('m.username = :username') + ->setParameter('username', $username); + + $qb->execute(); + } catch (Exception $e) { + $this->logger->error('Error setting mailbox quota of user ' . $username . ' to ' . strval($quotaInMb) . ': ' . $e->getMessage()); + } + } +} diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index a2d353c3..abf6c043 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -10,6 +10,7 @@ use OCP\EventDispatcher\IEventListener; use OCP\Util; use OCP\ILogger; use OCP\User\Events\UserChangedEvent; +use OCA\EcloudAccounts\Db\MailboxMapper; use OCA\EcloudAccounts\Service\LDAPConnectionService; class UserChangedListener implements IEventListener @@ -22,10 +23,13 @@ class UserChangedListener implements IEventListener private $ldapConnectionService; - public function __construct(Util $util, LDAPConnectionService $LDAPConnectionService, ILogger $logger) + private $mailboxMapper; + + public function __construct(Util $util, LDAPConnectionService $LDAPConnectionService, ILogger $logger, MailboxMapper $mailboxMapper) { $this->util = $util; $this->ldapConnectionService = $LDAPConnectionService; + $this->mailboxMapper = $mailboxMapper; $this->logger = $logger; } @@ -43,22 +47,35 @@ class UserChangedListener implements IEventListener $user = $event->getUser(); $username = $user->getUID(); $updatedQuota = $event->getValue(); + $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); + $backend = $user->getBackend()->getBackendName(); try { + if ($backend === 'SQL raw') { + $this->mailboxMapper->updateMailboxQuota($username, $quotaInBytes); + } + if ($backend === 'LDAP') { + $this->updateQuotaInLDAP($username, $quotaInBytes); + } + } catch (Exception $e) { + $this->logger->error("Error setting quota for user $username " . $e->getMessage()); + } + } + + private function updateQuotaInLDAP(string $username, int $quota) + { + if ($this->LDAPConnectionService->isLDAPEnabled()) { $conn = $this->ldapConnectionService->getLDAPConnection(); $userDn = $this->ldapConnectionService->username2dn($username); - $quotaInBytes = (int) $this->util->computerFileSize($updatedQuota); $entry = [ - 'quota' => $quotaInBytes + 'quota' => $quota ]; if (!ldap_modify($conn, $userDn, $entry)) { throw new Exception('Could not modify user entry at LDAP server!'); } $this->ldapConnectionService->closeLDAPConnection($conn); - } catch (Exception $e) { - $this->logger->error("Error setting quota for user $username " . $e->getMessage()); } } } -- GitLab From 0f6ce5dc0877d7f3297e70c93c0e4aeb18edfc9c Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 15:21:39 +0530 Subject: [PATCH 11/16] Add isUserOnLDAPBackend --- lib/Service/LDAPConnectionService.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index 43fa2afa..3857ba87 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -45,6 +45,11 @@ class LDAPConnectionService } } + public function isUserOnLDAPBackend(IUser $user) { + $backend = $user->getBackend(); + return $backend->getBackendName() === 'LDAP'; + } + public function isLDAPEnabled() : bool { return $this->LDAPEnabled; } -- GitLab From bb7e263b07bde50f6f802d10a0c7a87ed6fcad9e Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 15:50:32 +0530 Subject: [PATCH 12/16] Remove IUser check --- lib/Service/LDAPConnectionService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index 3857ba87..295c5138 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -45,7 +45,7 @@ class LDAPConnectionService } } - public function isUserOnLDAPBackend(IUser $user) { + public function isUserOnLDAPBackend($user) { $backend = $user->getBackend(); return $backend->getBackendName() === 'LDAP'; } -- GitLab From 89c053085ad650730fdd1e147892095358680a75 Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 15:57:55 +0530 Subject: [PATCH 13/16] Fix postDelete hook --- lib/AppInfo/Application.php | 3 +++ lib/Listeners/BeforeUserDeletedListener.php | 2 +- lib/Listeners/UserDeletedListener.php | 23 ++++++++++++++------- 3 files changed, 19 insertions(+), 9 deletions(-) diff --git a/lib/AppInfo/Application.php b/lib/AppInfo/Application.php index e8a30518..cc216832 100644 --- a/lib/AppInfo/Application.php +++ b/lib/AppInfo/Application.php @@ -36,6 +36,8 @@ use OCA\EcloudAccounts\Listeners\UserDeletedListener; use OCA\EcloudAccounts\Listeners\BeforeUserDeletedListener; use OCA\EcloudAccounts\Service\LDAPConnectionService; use OCP\User\Events\BeforeUserDeletedEvent; +use OCP\User\Events\UserChangedEvent; +use OCA\EcloudAccounts\Listeners\UserChangedListener; class Application extends App implements IBootstrap @@ -52,6 +54,7 @@ class Application extends App implements IBootstrap { $context->registerEventListener(UserDeletedEvent::class, UserDeletedListener::class); $context->registerEventListener(BeforeUserDeletedEvent::class, BeforeUserDeletedListener::class); + $context->registerEventListener(UserChangedEvent::class, UserChangedListener::class); } public function boot(IBootContext $context): void diff --git a/lib/Listeners/BeforeUserDeletedListener.php b/lib/Listeners/BeforeUserDeletedListener.php index 91653a44..42601dfd 100644 --- a/lib/Listeners/BeforeUserDeletedListener.php +++ b/lib/Listeners/BeforeUserDeletedListener.php @@ -34,7 +34,7 @@ class BeforeUserDeletedListener implements IEventListener $uid = $user->getUID(); try { - if ($this->LDAPConnectionService->isLDAPEnabled()) { + if ($this->LDAPConnectionService->isUserOnLDAPBackend($user)) { $conn = $this->LDAPConnectionService->getLDAPConnection($uid); $this->deleteAliasEntries($conn, $email); $this->LDAPConnectionService->closeLDAPConnection($conn); diff --git a/lib/Listeners/UserDeletedListener.php b/lib/Listeners/UserDeletedListener.php index 52319b9c..6e63f568 100644 --- a/lib/Listeners/UserDeletedListener.php +++ b/lib/Listeners/UserDeletedListener.php @@ -11,8 +11,8 @@ use OCP\EventDispatcher\Event; use OCP\EventDispatcher\IEventListener; use OCP\IConfig; use OCP\ILogger; -use OCP\IUserManager; use OCP\User\Events\UserDeletedEvent; +use OCA\EcloudAccounts\Service\LDAPConnectionService; require_once 'curl.class.php'; @@ -20,13 +20,13 @@ class UserDeletedListener implements IEventListener { private $logger; private $config; - private $userManager; + private $ldapConnectionService; - public function __construct(ILogger $logger, IConfig $config, IUserManager $userManager) + public function __construct(ILogger $logger, IConfig $config, LDAPConnectionService $LDAPConnectionService) { $this->logger = $logger; $this->config = $config; - $this->userManager = $userManager; + $this->ldapConnectionService = $LDAPConnectionService; } @@ -36,13 +36,16 @@ class UserDeletedListener implements IEventListener return; } - $uid = $event->getUser()->getUID(); + $user = $event->getUser(); + $uid = $user->getUID(); + $isUserOnLDAP = $this->ldapConnectionService->isUserOnLDAPBackend($user); $this->logger->info("PostDelete user {user}", array('user' => $uid)); $this->ecloudDelete( $uid, $this->config->getSystemValue('e_welcome_domain'), - $this->config->getSystemValue('e_welcome_secret') + $this->config->getSystemValue('e_welcome_secret'), + $isUserOnLDAP ); } @@ -56,9 +59,13 @@ class UserDeletedListener implements IEventListener * @param $welcomeSecret string generated at ecloud selfhosting install and added as a custom var in NC's config * @return mixed response of the external endpoint */ - public function ecloudDelete(string $userID, string $welcomeDomain, string $welcomeSecret) + public function ecloudDelete(string $userID, string $welcomeDomain, string $welcomeSecret, bool $isUserOnLDAP = false) { - $postDeleteUrl = "https://" . $welcomeDomain . "/postDeleteLDAP.php"; + $endpoint = 'postDelete.php'; + if($isUserOnLDAP) { + $endpoint = 'postDeleteLDAP.php'; + } + $postDeleteUrl = "https://" . $welcomeDomain . $endpoint; $curl = new Curl(); /** -- GitLab From 1b32b75ad02b3c550f55aa6165358e5b43ea897b Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 18:42:12 +0530 Subject: [PATCH 14/16] Fix connection service property name --- lib/Listeners/UserChangedListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Listeners/UserChangedListener.php b/lib/Listeners/UserChangedListener.php index abf6c043..40c782c2 100644 --- a/lib/Listeners/UserChangedListener.php +++ b/lib/Listeners/UserChangedListener.php @@ -64,7 +64,7 @@ class UserChangedListener implements IEventListener private function updateQuotaInLDAP(string $username, int $quota) { - if ($this->LDAPConnectionService->isLDAPEnabled()) { + if ($this->ldapConnectionService->isLDAPEnabled()) { $conn = $this->ldapConnectionService->getLDAPConnection(); $userDn = $this->ldapConnectionService->username2dn($username); -- GitLab From 649856e8a3260a39f74dae9e72f06c7a569b3f06 Mon Sep 17 00:00:00 2001 From: Akhil Date: Tue, 24 May 2022 19:19:17 +0530 Subject: [PATCH 15/16] Correct to isLDAPEnabled --- lib/Service/LDAPConnectionService.php | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/Service/LDAPConnectionService.php b/lib/Service/LDAPConnectionService.php index 295c5138..dc0ee7b2 100644 --- a/lib/Service/LDAPConnectionService.php +++ b/lib/Service/LDAPConnectionService.php @@ -4,6 +4,7 @@ declare(strict_types=1); namespace OCA\EcloudAccounts\Service; +use Exception; use OCP\IUserManager; class LDAPConnectionService @@ -14,7 +15,7 @@ class LDAPConnectionService private $configuration; - private $LDAPEnabled; + private $ldapEnabled; private $access; @@ -37,7 +38,7 @@ class LDAPConnectionService $configuration = $connection->getConfiguration(); if ($configuration['ldap_configuration_active']) { - $this->LDAPEnabled = true; + $this->ldapEnabled = true; $this->configuration = $configuration; break; } @@ -51,7 +52,7 @@ class LDAPConnectionService } public function isLDAPEnabled() : bool { - return $this->LDAPEnabled; + return $this->ldapEnabled; } public function username2dn(string $username) { @@ -69,6 +70,10 @@ class LDAPConnectionService public function getLDAPConnection() { + if(!$this->ldapEnabled) { + throw new Exception('LDAP backend is not enabled'); + } + $adminDn = $this->configuration['ldap_dn']; $adminPassword = $this->configuration['ldap_agent_password']; $host = $this->configuration['ldap_host']; -- GitLab From df3bbc2da4c0de9e3a46bdab77b576125540a11a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Arnau=20V=C3=A0zquez?= Date: Tue, 24 May 2022 15:55:21 +0000 Subject: [PATCH 16/16] Check for LDAP enabled --- lib/Listeners/BeforeUserDeletedListener.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Listeners/BeforeUserDeletedListener.php b/lib/Listeners/BeforeUserDeletedListener.php index 42601dfd..0ca586cb 100644 --- a/lib/Listeners/BeforeUserDeletedListener.php +++ b/lib/Listeners/BeforeUserDeletedListener.php @@ -34,7 +34,7 @@ class BeforeUserDeletedListener implements IEventListener $uid = $user->getUID(); try { - if ($this->LDAPConnectionService->isUserOnLDAPBackend($user)) { + if ($this->LDAPConnectionService->isLDAPEnabled() && $this->LDAPConnectionService->isUserOnLDAPBackend($user)) { $conn = $this->LDAPConnectionService->getLDAPConnection($uid); $this->deleteAliasEntries($conn, $email); $this->LDAPConnectionService->closeLDAPConnection($conn); -- GitLab