From a8f6dab672d417e653e6a81038bc66284b52dbef Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Fri, 3 Mar 2023 12:27:56 +0100 Subject: [PATCH] Working prototype. - Needs check if overwriting mail address is activated - Needs rework on ldap query function (looks up to much data) - Code cleanup is needed --- .../ldap-mail-accounts/LdapMailAccounts.php | 74 ++++++++++++++++++- plugins/ldap-mail-accounts/index.php | 29 +++++++- 2 files changed, 97 insertions(+), 6 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index c45c38a4b..5f8be4e48 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -46,15 +46,83 @@ class LdapMailAccounts $this->Connect(); } + + /** + * @inheritDoc + * + * AOverwrite the MainAccount mail address by looking up the new one in the ldap directory + * + * The ldap search string has to be configured in the plugin configuration of the extension (in the SnappyMail Admin Panel) + * + * @param string &$sEmail + * @param string &$sLogin + */ + public function overwriteEmail(&$sEmail, &$sLogin) + { + try { + $this->EnsureBound(); + } catch (LdapMailAccountsException $e) { + return false; // exceptions are only thrown from the handleerror function that does logging already + } + + // Try to get account information. IncLogin() returns the username of the user + // and removes the domainname if this was configured inside the domain config. + $username = $sEmail; + $oActions = \RainLoop\Api::Actions(); + $oDomain = $oActions->DomainProvider()->Load(\MailSo\Base\Utils::GetDomainFromEmail($sEmail), true); + if ($oDomain->IncShortLogin()){ + $username = @ldap_escape($this->RemoveEventualDomainPart($sEmail), "", LDAP_ESCAPE_FILTER); + } + + $searchString = $this->config->search_string; + + // Replace placeholders inside the ldap search string with actual values + $searchString = str_replace("#USERNAME#", $username, $searchString); + $searchString = str_replace("#BASE_DN#", $this->config->base, $searchString); + + $this->logger->Write("ldap search string after replacement of placeholders: $searchString", \LOG_NOTICE, self::LOG_KEY); + + try { + $mailAddressResults = $this->FindLdapResults( + $this->config->field_search, + $searchString, + $this->config->base, + $this->config->objectclass, + $this->config->field_name, + $this->config->field_username, + $this->config->field_domain, + $this->config->bool_overwrite_mail_address_main_account, + $this->config->field_mail_address_main_account, + $this->config->field_mail_address_additional_account + ); + } + catch (LdapMailAccountsException $e) { + return false; // exceptions are only thrown from the handleerror function that does logging already + } + if (count($mailAddressResults) < 1) { + $this->logger->Write("Could not find user $username", \LOG_NOTICE, self::LOG_KEY); + return false; + } + + foreach($mailAddressResults as $mailAddressResult) + { + if($mailAddressResult->username === $username) { + //$sLogin is already set to be the same as $sEmail by function "resolveLoginCredentials" in /RainLoop/Actions/UserAuth.php + //that called this hook, so we just have to overwrite the mail address + $sEmail = $mailAddressResult->mailMainAccount; + } + } + } + /** * @inheritDoc * * Add additional mail accounts to the given primary account by looking up the ldap directory * - * The ldap lookup has to be configured in the plugin configuration of the extension (in the SnappyMail Admin Panel) + * The ldap search string has to be configured in the plugin configuration of the extension (in the SnappyMail Admin Panel) * * @param MainAccount $oAccount - * @return bool true if additional accounts have been added or no additional accounts where found in . false if an error occured + * @return bool true if additional accounts have been added or no additional accounts where found in ldap. false if an error occured */ public function AddLdapMailAccounts(MainAccount $oAccount): bool { @@ -64,7 +132,7 @@ class LdapMailAccounts return false; // exceptions are only thrown from the handleerror function that does logging already } - // Try to get account information. Login() returns the username of the user + // Try to get account information. IncLogin() returns the username of the user // and removes the domainname if this was configured inside the domain config. $username = @ldap_escape($oAccount->IncLogin(), "", LDAP_ESCAPE_FILTER); diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index f08f01213..c2b08d5fc 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -32,8 +32,30 @@ class LdapMailAccountsPlugin extends AbstractPlugin public function Init(): void { $this->addHook("login.success", 'AddAdditionalLdapMailAccounts'); - $this->addHook('imap.before-login', 'MapImapCredentialsByLDAP'); - $this->addHook('smtp.before-login', 'MapSmtpCredentialsByLDAP'); + //$this->addHook('imap.before-login', 'MapImapCredentialsByLDAP'); + //$this->addHook('smtp.before-login', 'MapSmtpCredentialsByLDAP'); + $this->addHook('login.credentials', 'overwriteMainAccountEmail'); + } + + // Function gets called by RainLoop/Actions/UserAuth.php + /** + * Overwrite the MainAccount mail address by looking up the new one in the ldap directory + * + * @param string &$sEmail + * @param string &$sLogin + */ + public function overwriteMainAccountEmail(&$sEmail, &$sLogin) + { + $this->Manager()->Actions()->Logger()->Write("Login DATA: login: $sLogin email: $sEmail", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); + + // Set up config + $config = LdapMailAccountsConfig::MakeConfig($this->Config()); + + $oldapMailAccounts = new LdapMailAccounts($config, $this->Manager()->Actions()->Logger()); + + $oldapMailAccounts->overwriteEmail($sEmail, $sLogin); + + $this->Manager()->Actions()->Logger()->Write("Login DATA: login: $sLogin email: $sEmail", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); } // Function gets called by RainLoop/Actions/User.php @@ -94,7 +116,8 @@ class LdapMailAccountsPlugin extends AbstractPlugin ->SetLabel("Mail address field for main account") ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The ldap field containing the mail address to use on the SnappyMail main account. - \nThe value found inside ldap will overwrite the mail address of the SnappyMail main account (the account the user logged in at SnappyMail)") + \nThe value found inside ldap will overwrite the mail address of the SnappyMail main account (the account the user logged in at SnappyMail) + \nThe mail address used at login will still be used to login to the servers.") ->SetDefaultValue("mail"), ]);