From 30e3a8cc0fc311522983cc6ffcccdf11ff70501c Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Fri, 10 Feb 2023 11:11:24 +0100 Subject: [PATCH 01/10] added new config options to overwrite the mail address --- .../LdapMailAccountsConfig.php | 12 +++ plugins/ldap-mail-accounts/index.php | 79 +++++++++++++------ 2 files changed, 68 insertions(+), 23 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php index f1a62786c..186fd5bee 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php +++ b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php @@ -18,6 +18,10 @@ class LdapMailAccountsConfig public const CONFIG_FIELD_USERNAME = "field_username"; public const CONFIG_SEARCH_STRING = "search_string"; public const CONFIG_FIELD_MAIL_DOMAIN = "field_domain"; + public const CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT = "field_mail_address_main_account"; + public const CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "field_mail_address_additional_account"; + public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT = "bool_overwrite_mail_address_main_account"; + public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "bool_overwrite_mail_address_additional_account"; public $server; public $protocol; @@ -30,6 +34,10 @@ class LdapMailAccountsConfig public $field_username; public $search_string; public $field_domain; + public $field_mail_address_main_account; + public $field_mail_address_additional_account; + public $bool_overwrite_mail_address_main_account; + public $bool_overwrite_mail_address_additional_account; public static function MakeConfig(Plugin $config): LdapMailAccountsConfig { @@ -45,6 +53,10 @@ class LdapMailAccountsConfig $ldap->field_username = trim($config->Get("plugin", self::CONFIG_FIELD_USERNAME)); $ldap->search_string = trim($config->Get("plugin", self::CONFIG_SEARCH_STRING)); $ldap->field_domain = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_DOMAIN)); + $ldap->bool_overwrite_mail_address_main_account = $config->Get("plugin", self::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT); + $ldap->field_mail_address_main_account = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT)); + $ldap->bool_overwrite_mail_address_additional_account = $config->Get("plugin", self::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT); + $ldap->field_mail_address_additional_account = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT)); return $ldap; } diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 7b6fb48d9..84f2b2609 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -55,73 +55,106 @@ class LdapMailAccountsPlugin extends AbstractPlugin */ protected function configMapping(): array { + $groupOverwriteMainAccount = new \RainLoop\Plugins\PropertyCollection('Overwrite mail address of main account'); + $groupOverwriteMainAccount->exchangeArray([ + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT)->SetLabel('Enabled') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) + ->SetDefaultValue(false), + + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT) + ->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)") + ->SetDefaultValue("mail"), + ]); + + $groupOverwriteAdditionalAccount = new \RainLoop\Plugins\PropertyCollection('Overwrite mail address of additional account'); + $groupOverwriteAdditionalAccount->exchangeArray([ + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT)->SetLabel('Enabled') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) + ->SetDefaultValue(false), + + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT) + ->SetLabel("Mail address field for additional account") + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) + ->SetDescription("The ldap field containing the mail address to use on the found additional mail account. + \nThe value found inside ldap will be used as mail address of the additional mail accounts created by this plugin.") + ->SetDefaultValue("mail"), + ]); + return [ - Property::NewInstance(LdapMailAccountsConfig::CONFIG_SERVER) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_SERVER) ->SetLabel("LDAP Server URL") ->SetPlaceholder("ldap://server:port") - ->SetType(PluginPropertyType::STRING), + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_PROTOCOL_VERSION) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_PROTOCOL_VERSION) ->SetLabel("LDAP Protocol Version") - ->SetType(PluginPropertyType::SELECTION) + ->SetType(RainLoop\Enumerations\PluginPropertyType::SELECTION) ->SetDefaultValue([2, 3]), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_BIND_USER) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BIND_USER) ->SetLabel("LDAP Username") ->SetDescription("The user to use for binding to the LDAP server. Should be a DN or RDN. Leave empty for anonymous bind.") - ->SetType(PluginPropertyType::STRING), + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_BIND_PASSWORD) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BIND_PASSWORD) ->SetLabel("LDAP Password") ->SetDescription("Leave empty for anonymous bind.") - ->SetType(PluginPropertyType::PASSWORD), + ->SetType(RainLoop\Enumerations\PluginPropertyType::PASSWORD), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_OBJECTCLASS) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_OBJECTCLASS) ->SetLabel("Object class") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The object class to use when searching for additional mail accounts of the logged in SnappyMail user") ->SetDefaultValue("user"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_BASE) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BASE) ->SetLabel("Base DN") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The base DN to search in for additional mail accounts of the logged in SnappyMail user"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_SEARCH) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_SEARCH) ->SetLabel("Search field") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The name of the ldap attribute that has to contain the here defined 'LDAP search string'.") ->SetDefaultValue("member"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_SEARCH_STRING) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_SEARCH_STRING) ->SetLabel("LDAP search string") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The search string used to find ldap objects of mail accounts the user has access to. \nPossible placeholers:\n#USERNAME# - replaced with the username of the actual SnappyMail user \n#BASE_DN# - replaced with the value inside the field 'User base DN'.") ->SetDefaultValue("uid=#USERNAME#"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_USERNAME) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_USERNAME) ->SetLabel("Username field of additional account") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The field containing the username of the found additional mail account. \nThis username gets used by SnappyMail to login to the additional mail account. \nIf this field contains an email address, only the local-part before the @ is used.") ->SetDefaultValue("uid"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_DOMAIN) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_DOMAIN) ->SetLabel("Domain name field of additional account") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The field containing the domain name of the found additional mail account. \nThis domain gets looked up by SnappyMail to choose the right connection parameters at logging in to the additional mail account. \nIf this field contains an email address, only the domain-part after the @ is used.") ->SetDefaultValue("mail"), - Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_NAME) + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_NAME) ->SetLabel("Additional account name field") - ->SetType(PluginPropertyType::STRING) + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The field containing the default sender name of the found additional mail account.") - ->SetDefaultValue("displayName") + ->SetDefaultValue("displayName"), + + $groupOverwriteMainAccount, + + $groupOverwriteAdditionalAccount, + ]; } } From 424c1ff90a228fdbc3cb0c69554e2c449db3f1e2 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Fri, 10 Feb 2023 12:04:50 +0100 Subject: [PATCH 02/10] Prepared ldap query to optionally read mail addresses for main account and additional accounts --- .../ldap-mail-accounts/LdapMailAccounts.php | 40 +++++++++++++++++-- .../LdapMailAccountsConfig.php | 4 +- plugins/ldap-mail-accounts/index.php | 4 +- 3 files changed, 41 insertions(+), 7 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index d82eec809..d2603f3b2 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -84,7 +84,11 @@ class LdapMailAccounts $this->config->objectclass, $this->config->field_name, $this->config->field_username, - $this->config->field_domain + $this->config->field_domain, + $this->config->bool_overwrite_mail_address_main_account, + $this->config->field_mail_address_main_account, + $this->config->bool_overwrite_mail_address_additional_account, + $this->config->field_mail_address_additional_account ); } catch (LdapMailAccountsException $e) { @@ -264,6 +268,10 @@ class LdapMailAccounts * @param string $nameField * @param string $usernameField * @param string $domainField + * @param bool $overwriteMailMainAccount + * @param string $mailAddressFieldMainAccount + * @param bool $overwriteMailAdditionalAccount + * @param string $mailAddressFieldAdditionalAccount * @return LdapMailAccountResult[] * @throws LdapMailAccountsException */ @@ -274,7 +282,11 @@ class LdapMailAccounts string $objectClass, string $nameField, string $usernameField, - string $domainField): array + string $domainField, + bool $overwriteMailMainAccount, + string $mailAddressFieldMainAccount, + bool $overwriteMailAdditionalAccount, + string $mailAddressFieldAdditionalAccount): array { $this->EnsureBound(); $nameField = strtolower($nameField); @@ -284,7 +296,20 @@ class LdapMailAccounts $filter = "(&(objectclass=$objectClass)($searchField=$searchString))"; $this->logger->Write("Used ldap filter to search for additional mail accounts: $filter", \LOG_NOTICE, self::LOG_KEY); - $ldapResult = @ldap_search($this->ldap, $searchBase, $filter, ['dn', $usernameField, $nameField, $domainField]); + //Set together the attributes to search inside the LDAP + $ldapAttributes = ['dn', $usernameField, $nameField, $domainField]; + if ($overwriteMailMainAccount) + { + \array_push($ldapAttributes, $mailAddressFieldMainAccount); + } + + if ($overwriteMailAdditionalAccount) + { + \array_push($ldapAttributes, $mailAddressFieldAdditionalAccount); + } + + + $ldapResult = @ldap_search($this->ldap, $searchBase, $filter, $ldapAttributes); if (!$ldapResult) { $this->HandleLdapError("Fetch $objectClass"); return []; @@ -311,6 +336,9 @@ class LdapMailAccounts $result->domain = $this->LdapGetAttribute($entry, $domainField, true, true); $result->domain = $this->RemoveEventualLocalPart($result->domain); + $result->mailMainAccount = $this->LdapGetAttribute($entry, $mailAddressFieldMainAccount, true, $overwriteMailMainAccount); + $result->mailAdditionalAccount = $this->LdapGetAttribute($entry, $mailAddressFieldAdditionalAccount, true, $overwriteMailAdditionalAccount); + $results[] = $result; } @@ -407,4 +435,10 @@ class LdapMailAccountResult /** @var string */ public $domain; + + /** @var string */ + public $mailMainAccount; + + /** @var string */ + public $mailAdditionalAccount; } diff --git a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php index 186fd5bee..ac08699e8 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php +++ b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php @@ -18,10 +18,10 @@ class LdapMailAccountsConfig public const CONFIG_FIELD_USERNAME = "field_username"; public const CONFIG_SEARCH_STRING = "search_string"; public const CONFIG_FIELD_MAIL_DOMAIN = "field_domain"; - public const CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT = "field_mail_address_main_account"; - public const CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "field_mail_address_additional_account"; public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT = "bool_overwrite_mail_address_main_account"; + public const CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT = "field_mail_address_main_account"; public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "bool_overwrite_mail_address_additional_account"; + public const CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "field_mail_address_additional_account"; public $server; public $protocol; diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 84f2b2609..711755499 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -12,11 +12,11 @@ class LdapMailAccountsPlugin extends AbstractPlugin { const NAME = 'LDAP Mail Accounts', - VERSION = '1.1', + VERSION = '2.0.0', AUTHOR = 'cm-schl', URL = 'https://github.com/cm-sch', RELEASE = '2022-12-08', - REQUIRED = '2.23.0', + REQUIRED = '2.25.4', CATEGORY = 'Accounts', DESCRIPTION = 'Add additional mail accounts the SnappyMail user has access to by a LDAP query. Basing on the work of FWest98 (https://github.com/FWest98).'; From 9cfe164633422e0f1e12ed1c04f5841820ebf386 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Wed, 15 Feb 2023 17:57:59 +0100 Subject: [PATCH 03/10] Works now with additional accounts: The mail address is correctly set by ldap value. But plugin needs rework: it makes no sense to let the user use the non existing mail address "username@domain" used only by SnappyMail. Plugin should always use a looked up mail address --- .../ldap-mail-accounts/LdapMailAccounts.php | 23 ++++++++++----- plugins/ldap-mail-accounts/index.php | 28 +++++++++++++++++++ 2 files changed, 44 insertions(+), 7 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index d2603f3b2..bbd7ec58c 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -113,7 +113,7 @@ class LdapMailAccounts $aAccounts = $oActions->GetAccounts($oAccount); - //Search for accounts with suffix " (LDAP)" at the end of the name that where created by this plugin and initially remove them from the + //Search for accounts with suffix " (LDAP)" at the end of the name that were created by this plugin and initially remove them from the //account array. This only removes the visibility but does not delete the config done by the user. So if a user looses access to a //mailbox the user will not see the account anymore but the configuration can be restored when the user regains access to it foreach($aAccounts as $key => $aAccount) @@ -129,31 +129,40 @@ class LdapMailAccounts $sUsername = $mailAddressResult->username; $sDomain = $mailAddressResult->domain; $sName = $mailAddressResult->name; + $sEmail = ""; + + //Create the email string - if disabled inside the config the email is a combination of the found username + @ + the found domain + if ($this->config->bool_overwrite_mail_address_additional_account) { + $sEmail = $mailAddressResult->mailAdditionalAccount; + } + else { + $sEmail = "$sUsername@$sDomain"; + } //Check if the domain of the found mail address is in the list of configured domains if ($oActions->DomainProvider()->Load($sDomain, true)) { //only execute if the found account isn't already in the list of additional accounts //and if the found account is different from the main account - if (!isset($aAccounts["$sUsername@$sDomain"]) && $oAccount->Email() !== "$sUsername@$sDomain") + if (!isset($aAccounts[$sEmail]) && $oAccount->Email() !== $sEmail) { //Try to login the user with the same password as the primary account has //if this fails the user will see the new mail addresses but will be asked for the correct password $sPass = $oAccount->IncPassword(); - $oNewAccount = RainLoop\Model\AdditionalAccount::NewInstanceFromCredentials($oActions, "$sUsername@$sDomain", $sUsername, $sPass); + $oNewAccount = RainLoop\Model\AdditionalAccount::NewInstanceFromCredentials($oActions, $sEmail, $sUsername, $sPass); - $aAccounts["$sUsername@$sDomain"] = $oNewAccount->asTokenArray($oAccount); + $aAccounts[$sEmail] = $oNewAccount->asTokenArray($oAccount); } //Always inject/update the found mailbox names into the array (also if the mailbox already existed) - if (isset($aAccounts["$sUsername@$sDomain"])) + if (isset($aAccounts[$sEmail])) { - $aAccounts["$sUsername@$sDomain"]['name'] = $sName . " (LDAP)"; + $aAccounts[$sEmail]['name'] = $sName . " (LDAP)"; } } else { - $this->logger->Write("Domain $sDomain is not part of configured domains in SnappyMail Admin Panel - mail address $sUsername@$sDomain will not be added.", \LOG_NOTICE, self::LOG_KEY); + $this->logger->Write("Domain $sDomain is not part of configured domains in SnappyMail Admin Panel - mail address $sEmail will not be added.", \LOG_NOTICE, self::LOG_KEY); } } diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 711755499..422b227ba 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -32,6 +32,8 @@ 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'); } // Function gets called by RainLoop/Actions/User.php @@ -50,6 +52,32 @@ class LdapMailAccountsPlugin extends AbstractPlugin $oldapMailAccounts->AddLdapMailAccounts($oAccount); } + // Function gets called by Account.php + /** + * Overwrite the mailaddress of the account with the one found in LDAP by this plugin at IMAP login + * + * @param Account $oAccount + * @param ImapClient $oImapClient + * @param \MailSo\Imap\Settings $oSettings + */ + public function MapImapCredentialsByLDAP(\RainLoop\Model\Account $oAccount, \MailSo\Imap\ImapClient $oImapClient, \MailSo\Imap\Settings $oSettings) + { + //$oSettings->Login = $oAccount->IncLogin(); + } + + // Function gets called by Account.php + /** + * Overwrite the mailaddress of the account with the one found in LDAP by this plugin at SMTP login + * + * @param Account $oAccount + * @param SmtpClient $oSmtpClient + * @param \MailSo\Smtp\Settings $oSettings + */ + public function MapSmtpCredentialsByLDAP(\RainLoop\Model\Account $oAccount, \MailSo\Smtp\SmtpClient $oSmtpClient, \MailSo\Smtp\Settings $oSettings) + { + + } + /** * Defines the content of the plugin configuration page inside the Admin Panel of SnappyMail */ From b8c681d1a5831c86067e1856ac3e5adb7d3c38fc Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Fri, 17 Feb 2023 12:01:39 +0100 Subject: [PATCH 04/10] Additional accounts now always get the mail address from ldap --- .../ldap-mail-accounts/LdapMailAccounts.php | 24 +++-------------- .../LdapMailAccountsConfig.php | 7 ++--- plugins/ldap-mail-accounts/index.php | 27 +++++++------------ 3 files changed, 16 insertions(+), 42 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index bbd7ec58c..0d6cdebda 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -87,7 +87,6 @@ class LdapMailAccounts $this->config->field_domain, $this->config->bool_overwrite_mail_address_main_account, $this->config->field_mail_address_main_account, - $this->config->bool_overwrite_mail_address_additional_account, $this->config->field_mail_address_additional_account ); } @@ -129,15 +128,7 @@ class LdapMailAccounts $sUsername = $mailAddressResult->username; $sDomain = $mailAddressResult->domain; $sName = $mailAddressResult->name; - $sEmail = ""; - - //Create the email string - if disabled inside the config the email is a combination of the found username + @ + the found domain - if ($this->config->bool_overwrite_mail_address_additional_account) { - $sEmail = $mailAddressResult->mailAdditionalAccount; - } - else { - $sEmail = "$sUsername@$sDomain"; - } + $sEmail = $mailAddressResult->mailAdditionalAccount; //Check if the domain of the found mail address is in the list of configured domains if ($oActions->DomainProvider()->Load($sDomain, true)) @@ -149,7 +140,7 @@ class LdapMailAccounts //Try to login the user with the same password as the primary account has //if this fails the user will see the new mail addresses but will be asked for the correct password $sPass = $oAccount->IncPassword(); - + //After creating the accounts here $sUsername is used as username to login to the IMAP server (see Account.php) $oNewAccount = RainLoop\Model\AdditionalAccount::NewInstanceFromCredentials($oActions, $sEmail, $sUsername, $sPass); $aAccounts[$sEmail] = $oNewAccount->asTokenArray($oAccount); @@ -294,7 +285,6 @@ class LdapMailAccounts string $domainField, bool $overwriteMailMainAccount, string $mailAddressFieldMainAccount, - bool $overwriteMailAdditionalAccount, string $mailAddressFieldAdditionalAccount): array { $this->EnsureBound(); @@ -306,18 +296,12 @@ class LdapMailAccounts $this->logger->Write("Used ldap filter to search for additional mail accounts: $filter", \LOG_NOTICE, self::LOG_KEY); //Set together the attributes to search inside the LDAP - $ldapAttributes = ['dn', $usernameField, $nameField, $domainField]; + $ldapAttributes = ['dn', $usernameField, $nameField, $domainField, $mailAddressFieldAdditionalAccount]; if ($overwriteMailMainAccount) { \array_push($ldapAttributes, $mailAddressFieldMainAccount); } - if ($overwriteMailAdditionalAccount) - { - \array_push($ldapAttributes, $mailAddressFieldAdditionalAccount); - } - - $ldapResult = @ldap_search($this->ldap, $searchBase, $filter, $ldapAttributes); if (!$ldapResult) { $this->HandleLdapError("Fetch $objectClass"); @@ -346,7 +330,7 @@ class LdapMailAccounts $result->domain = $this->RemoveEventualLocalPart($result->domain); $result->mailMainAccount = $this->LdapGetAttribute($entry, $mailAddressFieldMainAccount, true, $overwriteMailMainAccount); - $result->mailAdditionalAccount = $this->LdapGetAttribute($entry, $mailAddressFieldAdditionalAccount, true, $overwriteMailAdditionalAccount); + $result->mailAdditionalAccount = $this->LdapGetAttribute($entry, $mailAddressFieldAdditionalAccount, true, true); $results[] = $result; } diff --git a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php index ac08699e8..ab62ed58d 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php +++ b/plugins/ldap-mail-accounts/LdapMailAccountsConfig.php @@ -18,10 +18,9 @@ class LdapMailAccountsConfig public const CONFIG_FIELD_USERNAME = "field_username"; public const CONFIG_SEARCH_STRING = "search_string"; public const CONFIG_FIELD_MAIL_DOMAIN = "field_domain"; + public const CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "field_mail_address_additional_account"; public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT = "bool_overwrite_mail_address_main_account"; public const CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT = "field_mail_address_main_account"; - public const CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "bool_overwrite_mail_address_additional_account"; - public const CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT = "field_mail_address_additional_account"; public $server; public $protocol; @@ -37,7 +36,6 @@ class LdapMailAccountsConfig public $field_mail_address_main_account; public $field_mail_address_additional_account; public $bool_overwrite_mail_address_main_account; - public $bool_overwrite_mail_address_additional_account; public static function MakeConfig(Plugin $config): LdapMailAccountsConfig { @@ -53,10 +51,9 @@ class LdapMailAccountsConfig $ldap->field_username = trim($config->Get("plugin", self::CONFIG_FIELD_USERNAME)); $ldap->search_string = trim($config->Get("plugin", self::CONFIG_SEARCH_STRING)); $ldap->field_domain = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_DOMAIN)); + $ldap->field_mail_address_additional_account = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT)); $ldap->bool_overwrite_mail_address_main_account = $config->Get("plugin", self::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_MAIN_ACCOUNT); $ldap->field_mail_address_main_account = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_ADDRESS_MAIN_ACCOUNT)); - $ldap->bool_overwrite_mail_address_additional_account = $config->Get("plugin", self::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT); - $ldap->field_mail_address_additional_account = trim($config->Get("plugin", self::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT)); return $ldap; } diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 422b227ba..f08f01213 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -63,6 +63,7 @@ class LdapMailAccountsPlugin extends AbstractPlugin public function MapImapCredentialsByLDAP(\RainLoop\Model\Account $oAccount, \MailSo\Imap\ImapClient $oImapClient, \MailSo\Imap\Settings $oSettings) { //$oSettings->Login = $oAccount->IncLogin(); + //$this->Manager()->Actions()->Logger()->Write("E-Mail address: $oSettings->Login", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); } // Function gets called by Account.php @@ -97,20 +98,6 @@ class LdapMailAccountsPlugin extends AbstractPlugin ->SetDefaultValue("mail"), ]); - $groupOverwriteAdditionalAccount = new \RainLoop\Plugins\PropertyCollection('Overwrite mail address of additional account'); - $groupOverwriteAdditionalAccount->exchangeArray([ - \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_BOOL_OVERWRITE_MAIL_ADDRESS_ADDITIONAL_ACCOUNT)->SetLabel('Enabled') - ->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL) - ->SetDefaultValue(false), - - \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT) - ->SetLabel("Mail address field for additional account") - ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) - ->SetDescription("The ldap field containing the mail address to use on the found additional mail account. - \nThe value found inside ldap will be used as mail address of the additional mail accounts created by this plugin.") - ->SetDefaultValue("mail"), - ]); - return [ \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_SERVER) ->SetLabel("LDAP Server URL") @@ -173,15 +160,21 @@ class LdapMailAccountsPlugin extends AbstractPlugin \nIf this field contains an email address, only the domain-part after the @ is used.") ->SetDefaultValue("mail"), + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_ADDRESS_ADDITIONAL_ACCOUNT) + ->SetLabel("Mail address field for additional account") + ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) + ->SetDescription("The ldap field containing the mail address to use on the found additional mail account. + \nThe value found inside ldap will be used as mail address of the additional mail accounts created by this plugin. + \nIn most cases this could be the same ldap field as in \"Domain name field of additional account\"") + ->SetDefaultValue("mail"), + \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_NAME) ->SetLabel("Additional account name field") ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) ->SetDescription("The field containing the default sender name of the found additional mail account.") ->SetDefaultValue("displayName"), - $groupOverwriteMainAccount, - - $groupOverwriteAdditionalAccount, + $groupOverwriteMainAccount ]; } From 7948e86a07b69d25b361575001f60d6609868f08 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Fri, 17 Feb 2023 12:33:32 +0100 Subject: [PATCH 05/10] added comment --- plugins/ldap-mail-accounts/LdapMailAccounts.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index 0d6cdebda..c45c38a4b 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -134,8 +134,11 @@ class LdapMailAccounts if ($oActions->DomainProvider()->Load($sDomain, true)) { //only execute if the found account isn't already in the list of additional accounts - //and if the found account is different from the main account - if (!isset($aAccounts[$sEmail]) && $oAccount->Email() !== $sEmail) + //and if the found account is different from the main account. + //The check if the address is different from the one of the main account when using the Nextcloud integration needs + //to be done twice: directly on the mail address (when Nextcloud is configured to log the user in by mail address) + //or on "$sUsername@$sDomain" for the case Nextcloud logs the user in to SnappyMail by his username and a default domain. + if (!isset($aAccounts[$sEmail]) && $oAccount->Email() !== $sEmail && $oAccount->Email() !== "$sUsername@$sDomain") { //Try to login the user with the same password as the primary account has //if this fails the user will see the new mail addresses but will be asked for the correct password 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 06/10] 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"), ]); From 58b368552f7f64d2699e27f5dc54f394f795f8e9 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:05:10 +0100 Subject: [PATCH 07/10] Overwrite of main address works - Cleanup of not used functions - Rewrite of FindLdapResults function to work in both cases: for additional accounts and main account --- .../ldap-mail-accounts/LdapMailAccounts.php | 33 ++++++------- plugins/ldap-mail-accounts/index.php | 47 ++++--------------- 2 files changed, 23 insertions(+), 57 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index 5f8be4e48..066ee0a35 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -91,16 +91,15 @@ class LdapMailAccounts $this->config->field_name, $this->config->field_username, $this->config->field_domain, - $this->config->bool_overwrite_mail_address_main_account, + true, $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); + $this->logger->Write("Could not find user $username in LDAP! Overwriting of main mail address not possible.", \LOG_NOTICE, self::LOG_KEY); return false; } @@ -153,8 +152,7 @@ class LdapMailAccounts $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, + false, $this->config->field_mail_address_additional_account ); } @@ -339,10 +337,8 @@ class LdapMailAccounts * @param string $nameField * @param string $usernameField * @param string $domainField - * @param bool $overwriteMailMainAccount - * @param string $mailAddressFieldMainAccount - * @param bool $overwriteMailAdditionalAccount - * @param string $mailAddressFieldAdditionalAccount + * @param bool $overwriteMailMainAccount true if the mail address of the main account should be looked up for overwriting. false if additional mail accounts should be searched + * @param string $mailAddressField The field containing the mail address (of main account or additional mail account) * @return LdapMailAccountResult[] * @throws LdapMailAccountsException */ @@ -355,8 +351,7 @@ class LdapMailAccounts string $usernameField, string $domainField, bool $overwriteMailMainAccount, - string $mailAddressFieldMainAccount, - string $mailAddressFieldAdditionalAccount): array + string $mailAddressField): array { $this->EnsureBound(); $nameField = strtolower($nameField); @@ -364,14 +359,10 @@ class LdapMailAccounts $domainField = strtolower($domainField); $filter = "(&(objectclass=$objectClass)($searchField=$searchString))"; - $this->logger->Write("Used ldap filter to search for additional mail accounts: $filter", \LOG_NOTICE, self::LOG_KEY); + $this->logger->Write("Used ldap filter to search for mail account(s): $filter", \LOG_NOTICE, self::LOG_KEY); //Set together the attributes to search inside the LDAP - $ldapAttributes = ['dn', $usernameField, $nameField, $domainField, $mailAddressFieldAdditionalAccount]; - if ($overwriteMailMainAccount) - { - \array_push($ldapAttributes, $mailAddressFieldMainAccount); - } + $ldapAttributes = ['dn', $usernameField, $nameField, $domainField, $mailAddressField]; $ldapResult = @ldap_search($this->ldap, $searchBase, $filter, $ldapAttributes); if (!$ldapResult) { @@ -400,8 +391,12 @@ class LdapMailAccounts $result->domain = $this->LdapGetAttribute($entry, $domainField, true, true); $result->domain = $this->RemoveEventualLocalPart($result->domain); - $result->mailMainAccount = $this->LdapGetAttribute($entry, $mailAddressFieldMainAccount, true, $overwriteMailMainAccount); - $result->mailAdditionalAccount = $this->LdapGetAttribute($entry, $mailAddressFieldAdditionalAccount, true, true); + if($overwriteMailMainAccount) { + $result->mailMainAccount = $this->LdapGetAttribute($entry, $mailAddressField, true, true); + } + else { + $result->mailAdditionalAccount = $this->LdapGetAttribute($entry, $mailAddressField, true, true); + } $results[] = $result; } diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index c2b08d5fc..345ad602a 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -32,8 +32,6 @@ 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('login.credentials', 'overwriteMainAccountEmail'); } @@ -46,16 +44,18 @@ class LdapMailAccountsPlugin extends AbstractPlugin */ public function overwriteMainAccountEmail(&$sEmail, &$sLogin) { - $this->Manager()->Actions()->Logger()->Write("Login DATA: login: $sLogin email: $sEmail", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); +$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()); + // Set up config + $config = LdapMailAccountsConfig::MakeConfig($this->Config()); - $oldapMailAccounts = new LdapMailAccounts($config, $this->Manager()->Actions()->Logger()); + if ($config->bool_overwrite_mail_address_main_account) + { + $oldapMailAccounts = new LdapMailAccounts($config, $this->Manager()->Actions()->Logger()); + $oldapMailAccounts->overwriteEmail($sEmail, $sLogin); + } - $oldapMailAccounts->overwriteEmail($sEmail, $sLogin); - - $this->Manager()->Actions()->Logger()->Write("Login DATA: login: $sLogin email: $sEmail", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); +$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 @@ -68,39 +68,10 @@ class LdapMailAccountsPlugin extends AbstractPlugin { // Set up config $config = LdapMailAccountsConfig::MakeConfig($this->Config()); - $oldapMailAccounts = new LdapMailAccounts($config, $this->Manager()->Actions()->Logger()); - $oldapMailAccounts->AddLdapMailAccounts($oAccount); } - // Function gets called by Account.php - /** - * Overwrite the mailaddress of the account with the one found in LDAP by this plugin at IMAP login - * - * @param Account $oAccount - * @param ImapClient $oImapClient - * @param \MailSo\Imap\Settings $oSettings - */ - public function MapImapCredentialsByLDAP(\RainLoop\Model\Account $oAccount, \MailSo\Imap\ImapClient $oImapClient, \MailSo\Imap\Settings $oSettings) - { - //$oSettings->Login = $oAccount->IncLogin(); - //$this->Manager()->Actions()->Logger()->Write("E-Mail address: $oSettings->Login", \LOG_WARNING, "LDAP MAIL ACCOUNTS PLUGIN"); - } - - // Function gets called by Account.php - /** - * Overwrite the mailaddress of the account with the one found in LDAP by this plugin at SMTP login - * - * @param Account $oAccount - * @param SmtpClient $oSmtpClient - * @param \MailSo\Smtp\Settings $oSettings - */ - public function MapSmtpCredentialsByLDAP(\RainLoop\Model\Account $oAccount, \MailSo\Smtp\SmtpClient $oSmtpClient, \MailSo\Smtp\Settings $oSettings) - { - - } - /** * Defines the content of the plugin configuration page inside the Admin Panel of SnappyMail */ From c732cec62fc8e9ecd0560ff5090ee3dccbfb0401 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Tue, 7 Mar 2023 15:31:09 +0100 Subject: [PATCH 08/10] Clearer description whats username for in the config --- plugins/ldap-mail-accounts/LdapMailAccounts.php | 8 ++++---- plugins/ldap-mail-accounts/index.php | 11 +++++++---- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/plugins/ldap-mail-accounts/LdapMailAccounts.php b/plugins/ldap-mail-accounts/LdapMailAccounts.php index 066ee0a35..e68e9e179 100644 --- a/plugins/ldap-mail-accounts/LdapMailAccounts.php +++ b/plugins/ldap-mail-accounts/LdapMailAccounts.php @@ -62,7 +62,7 @@ class LdapMailAccounts try { $this->EnsureBound(); } catch (LdapMailAccountsException $e) { - return false; // exceptions are only thrown from the handleerror function that does logging already + return false; // exceptions are only thrown from the handle error function that does logging already } // Try to get account information. IncLogin() returns the username of the user @@ -96,7 +96,7 @@ class LdapMailAccounts ); } catch (LdapMailAccountsException $e) { - return false; // exceptions are only thrown from the handleerror function that does logging already + return false; // exceptions are only thrown from the handle error function that does logging already } if (count($mailAddressResults) < 1) { $this->logger->Write("Could not find user $username in LDAP! Overwriting of main mail address not possible.", \LOG_NOTICE, self::LOG_KEY); @@ -128,7 +128,7 @@ class LdapMailAccounts try { $this->EnsureBound(); } catch (LdapMailAccountsException $e) { - return false; // exceptions are only thrown from the handleerror function that does logging already + return false; // exceptions are only thrown from the handle error function that does logging already } // Try to get account information. IncLogin() returns the username of the user @@ -157,7 +157,7 @@ class LdapMailAccounts ); } catch (LdapMailAccountsException $e) { - return false; // exceptions are only thrown from the handleerror function that does logging already + return false; // exceptions are only thrown from the handle error function that does logging already } if (count($mailAddressResults) < 1) { $this->logger->Write("Could not find user $username", \LOG_NOTICE, self::LOG_KEY); diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 345ad602a..8d28d1e78 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -139,11 +139,14 @@ $this->Manager()->Actions()->Logger()->Write("Login DATA: login: $sLogin email: ->SetDefaultValue("uid=#USERNAME#"), \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_USERNAME) - ->SetLabel("Username field of additional account") + ->SetLabel("Username field") ->SetType(RainLoop\Enumerations\PluginPropertyType::STRING) - ->SetDescription("The field containing the username of the found additional mail account. - \nThis username gets used by SnappyMail to login to the additional mail account. - \nIf this field contains an email address, only the local-part before the @ is used.") + ->SetDescription("Used when searching for additional accounts or when overwriting the mail address of the main account. + \nThe field containing the username of the mail account. + \nWhen looking up additional accounts: + \nIf this field contains an email address, only the local-part before the @ is used. The domain part is retrieved configuring the field below. This username gets used by SnappyMail to login to the additional mail account + \nWhen overwriting the main account mail address: + \nThe username from SnappyMail login gets used to search an LDAP entry containig a field with the same username.") ->SetDefaultValue("uid"), \RainLoop\Plugins\Property::NewInstance(LdapMailAccountsConfig::CONFIG_FIELD_MAIL_DOMAIN) From 2d4e72805a1f02e1f6abbabcb2ea4727775d8f61 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:37:37 +0100 Subject: [PATCH 09/10] Updated readme.md --- plugins/ldap-mail-accounts/README.md | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/plugins/ldap-mail-accounts/README.md b/plugins/ldap-mail-accounts/README.md index 28176c2e8..8f7417e8b 100644 --- a/plugins/ldap-mail-accounts/README.md +++ b/plugins/ldap-mail-accounts/README.md @@ -4,6 +4,10 @@ This plugin can be used to add additional mail accounts to SnappyMail when a user logs in successfully. The list of additional accounts is retrieved by a ldap query that can be configured inside the plugin settings.\ On a successful login the username of the SnappyMail user is passed to the plugin and will be searched in the ldap. If additional mail accounts are found, the username and domain-part of those will be used to add the new mail account. The plugin tries to log in the user with the same password used to login to SnappyMail - if this fails SnappyMail asks the user to insert his credentials. +Version 2.0.0 changes the way additional mail accounts get their e-mail address: the mail address connected with additional mail accounts is now always the address found inside the ldap. +Now it is also possible to overwrite the mail address of the main account: if a user logs into SnappyMail with a username and SnappyMail added the configured default domain the mail address of the main account could have been some not existing address like "username@default-domain.com". This could have happend when using the Nextcloud SnappyMail integration that offers an automatic login using the Nextcloud username. +The plugin now can be configured to overwrite the username or mail address used at login with a mail address found inside ldap. + ### Configuration - Install and activate the plugin using the SnappyMail Admin Panel -> menu Extensions. - Click on the gear symbol beside the plugin to open the configration dialog. @@ -11,7 +15,9 @@ On a successful login the username of the SnappyMail user is passed to the plugi - The fields `Object class`, `Base DN`, `Search field` and `LDAP search string` are used to put together a ldap search filter which will return the additional mail accounts of a user:\ `(&(objectclass=)(=))`.\ This filter will be executed on the `Base DN` you have defined. `LDAP search string` can contain the placeholders `#USERNAME#` (will be replaced with the username the user logged in to Snappymail) and `#BASE_DN#` (will be replaced with the value you inserted into the field `Base DN` inside the plugin settings). This will allow you to create more complex search strings like `uid=#USERNAME#`. - - `Username field of additional account`, `Domain name field of additional account` and `Additional account name field` are used to define the ldap attributes to read when the ldap search was successful. For example insert `mail` into the `Username field of additional account` and the `Domain name field of additional account` to use the [local-part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the mail address as username and the [domain-part](https://en.wikipedia.org/wiki/Email_address#Domain) as domain for the additional account.\ - `Username field of additional account` and `Domain name field of additional account` before use get checked by the plugin if they contain a mail address and if true only the local-part or domain-part is returned. If no `@` is found the content of the found ldap attribute is returned without modification. This can be usefull if your user should login with something different than the mail address (a username that is diffrent from the local-part of the mail address). + - `Username field`, `Domain name field of additional account`, `Mail address field for additional account` and `Additional account name field` are used to define the ldap attributes to read when the ldap search was successful. For example insert `mail` into the `Username field` and the `Domain name field of additional account` to use the [local-part](https://en.wikipedia.org/wiki/Email_address#Local-part) of the mail address as username and the [domain-part](https://en.wikipedia.org/wiki/Email_address#Domain) as domain for the additional account.\ + `Username field` and `Domain name field of additional account` before use get checked by the plugin if they contain a mail address and if true only the local-part or domain-part is returned. If no `@` is found the content of the found ldap attribute is returned without modification. This can be usefull if your user should login with something different than the mail address (a username that is diffrent from the local-part of the mail address). -**Important:** keep in mind, that SnappyMail normally needs a mail address as username. In some special circumstances (login with an ldap username, not a mail address) this can mean that you have to configure the plugin to put together a 'fake' mail address like `@`. + Section `Overwrite mail address of main account` can be used to overwrite the username or mail address used at login with a value found in ldap. If activated, the username or mail address used at login will be looked up inside the `Username field` in ldap (for details see how a search for additional accounts is made). If the username is found, the value of the field `Mail address field for main account` will be used to overwrite the mail address of the main account. + +**Important:** SnappyMail normally needs a mail address as username. This plugin handles some special circumstances (login with an ldap username, not a mail address) so that you can login to your IMAP server with the ldap username but send mails with a mail address connected to this ldap user. From 75f198c8a0ebe286cec047ee924e83bf23aa1444 Mon Sep 17 00:00:00 2001 From: cm-schl <63400209+cm-schl@users.noreply.github.com> Date: Tue, 14 Mar 2023 14:50:22 +0100 Subject: [PATCH 10/10] Update release date --- plugins/ldap-mail-accounts/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/ldap-mail-accounts/index.php b/plugins/ldap-mail-accounts/index.php index 8d28d1e78..e5258e26d 100644 --- a/plugins/ldap-mail-accounts/index.php +++ b/plugins/ldap-mail-accounts/index.php @@ -15,7 +15,7 @@ class LdapMailAccountsPlugin extends AbstractPlugin VERSION = '2.0.0', AUTHOR = 'cm-schl', URL = 'https://github.com/cm-sch', - RELEASE = '2022-12-08', + RELEASE = '2023-03-14', REQUIRED = '2.25.4', CATEGORY = 'Accounts', DESCRIPTION = 'Add additional mail accounts the SnappyMail user has access to by a LDAP query. Basing on the work of FWest98 (https://github.com/FWest98).';