From 14e5ebbf7bd65cfb06e58b282271e79e6a8e73ee Mon Sep 17 00:00:00 2001 From: Marius Gripsgard Date: Wed, 23 Aug 2017 03:14:34 +0200 Subject: [PATCH] Add change email account password plugin for Mail-in-a-Box --- plugins/mailinabox-change-password/LICENSE | 20 +++ .../MailInABoxChangePasswordDriver.php | 157 ++++++++++++++++++ plugins/mailinabox-change-password/README | 1 + plugins/mailinabox-change-password/VERSION | 1 + plugins/mailinabox-change-password/index.php | 54 ++++++ 5 files changed, 233 insertions(+) create mode 100644 plugins/mailinabox-change-password/LICENSE create mode 100644 plugins/mailinabox-change-password/MailInABoxChangePasswordDriver.php create mode 100644 plugins/mailinabox-change-password/README create mode 100644 plugins/mailinabox-change-password/VERSION create mode 100644 plugins/mailinabox-change-password/index.php diff --git a/plugins/mailinabox-change-password/LICENSE b/plugins/mailinabox-change-password/LICENSE new file mode 100644 index 000000000..6ebe205bf --- /dev/null +++ b/plugins/mailinabox-change-password/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2017 Marius Gripsgard + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of +the Software, and to permit persons to whom the Software is furnished to do so, +subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/plugins/mailinabox-change-password/MailInABoxChangePasswordDriver.php b/plugins/mailinabox-change-password/MailInABoxChangePasswordDriver.php new file mode 100644 index 000000000..95534f543 --- /dev/null +++ b/plugins/mailinabox-change-password/MailInABoxChangePasswordDriver.php @@ -0,0 +1,157 @@ +sHost = $sHost; + $this->sAdminUser = $sAdminUser; + $this->sAdminPassword = $sAdminPassword; + return $this; + } + /** + * @param string $sAllowedEmails + * + * @return \MailInABoxChangePasswordDriver + */ + public function SetAllowedEmails($sAllowedEmails) + { + $this->sAllowedEmails = $sAllowedEmails; + return $this; + } + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \MailInABoxChangePasswordDriver + */ + public function SetLogger($oLogger) + { + if ($oLogger instanceof \MailSo\Log\Logger) + { + $this->oLogger = $oLogger; + } + return $this; + } + /** + * @param string $sDesc + * @param int $iType = \MailSo\Log\Enumerations\Type::INFO + * + * @return \MailInABoxChangePasswordDriver + */ + public function WriteLog($sDesc, $iType = \MailSo\Log\Enumerations\Type::INFO) + { + if ($this->oLogger) + { + $this->oLogger->Write($sDesc, $iType); + } + return $this; + } + /** + * @param \RainLoop\Model\Account $oAccount + * + * @return bool + */ + public function PasswordChangePossibility($oAccount) + { + return $oAccount && $oAccount->Email() && + \RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails); + } + /** + * @param \RainLoop\Model\Account $oAccount + * @param string $sPrevPassword + * @param string $sNewPassword + * + * @return bool + */ + public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) + { + $this->WriteLog('Mail-in-a-box: Try to change password for '.$oAccount->Email()); + $bResult = false; + if (!empty($this->sHost) && !empty($this->sAdminUser) && !empty($this->sAdminPassword) && $oAccount) + { + $this->WriteLog('Mail-in-a-box:[Check] Required Fields Present'); + $sEmail = \trim(\strtolower($oAccount->Email())); + $sHost = \rtrim(\trim($this->sHost), '/'); + $sUrl = $sHost.'/admin/mail/users/password'; + + $sAdminUser = $this->sAdminUser; + $sAdminPassword = $this->sAdminPassword; + $iCode = 0; + $aPost = array( + 'email' => $sEmail, + 'password' => $sNewPassword, + ); + $aOptions = array( + CURLOPT_URL => $sUrl, + CURLOPT_HEADER => false, + CURLOPT_FAILONERROR => true, + CURLOPT_SSL_VERIFYPEER => false, + CURLOPT_RETURNTRANSFER => true, + CURLOPT_POST => true, + CURLOPT_POSTFIELDS => \http_build_query($aPost, '', '&'), + CURLOPT_TIMEOUT => 20, + CURLOPT_SSL_VERIFYHOST => false, + CURLOPT_USERPWD => $sAdminUser.':'.$sAdminPassword, + CURLOPT_HTTPAUTH => CURLAUTH_BASIC + ); + $oCurl = \curl_init(); + \curl_setopt_array($oCurl, $aOptions); + $this->WriteLog('Mail-in-a-box: Send post request: '.$sUrl); + $mResult = \curl_exec($oCurl); + $iCode = (int) \curl_getinfo($oCurl, CURLINFO_HTTP_CODE); + $sContentType = (string) \curl_getinfo($oCurl, CURLINFO_CONTENT_TYPE); + $this->WriteLog('Mail-in-a-box: Post request result: (Status: '.$iCode.', ContentType: '.$sContentType.')'); + if (false === $mResult || 200 !== $iCode) + { + $this->WriteLog('Mail-in-a-box: Error: '.\curl_error($oCurl), \MailSo\Log\Enumerations\Type::WARNING); + } + if (\is_resource($oCurl)) + { + \curl_close($oCurl); + } + if (false !== $mResult && 200 === $iCode) + { + $this->WriteLog('Mail-in-a-box: Password Change Status: Success'); + $bResult = true; + } + else + { + $this->WriteLog('Mail-in-a-box[Error]: Empty Response: Code: '.$iCode); + } + } + return $bResult; + } +} diff --git a/plugins/mailinabox-change-password/README b/plugins/mailinabox-change-password/README new file mode 100644 index 000000000..9f419ce62 --- /dev/null +++ b/plugins/mailinabox-change-password/README @@ -0,0 +1 @@ +Plugin that adds functionality to change the email account password (Mail-in-a-Box). diff --git a/plugins/mailinabox-change-password/VERSION b/plugins/mailinabox-change-password/VERSION new file mode 100644 index 000000000..d3827e75a --- /dev/null +++ b/plugins/mailinabox-change-password/VERSION @@ -0,0 +1 @@ +1.0 diff --git a/plugins/mailinabox-change-password/index.php b/plugins/mailinabox-change-password/index.php new file mode 100644 index 000000000..b88235e54 --- /dev/null +++ b/plugins/mailinabox-change-password/index.php @@ -0,0 +1,54 @@ +addHook('main.fabrica', 'MainFabrica'); + } + /** + * @param string $sName + * @param mixed $oProvider + */ + public function MainFabrica($sName, &$oProvider) + { + switch ($sName) + { + case 'change-password': + include_once __DIR__.'/MailInABoxChangePasswordDriver.php'; + $sHost = \trim($this->Config()->Get('plugin', 'host', '')); + $sAdminUser = (string) $this->Config()->Get('plugin', 'admin_user', ''); + $sAdminPassword = (string) $this->Config()->Get('plugin', 'admin_password', ''); + $oProvider = new \MailInABoxChangePasswordDriver(); + $oProvider->SetLogger($this->Manager()->Actions()->Logger()); + $oProvider->SetConfig($sHost, $sAdminUser, $sAdminPassword); + $oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', '')))); + break; + } + } + /** + * @return array + */ + public function configMapping() + { + return array( + \RainLoop\Plugins\Property::NewInstance('host')->SetLabel('Mail-in-a-box Host') + ->SetDefaultValue('https://box.mailinabox.email') + ->SetDescription('Mail-in-a-box host URL. Example: https://box.mailinabox.email'), + \RainLoop\Plugins\Property::NewInstance('admin_user')->SetLabel('Admin User') + ->SetDefaultValue(''), + \RainLoop\Plugins\Property::NewInstance('admin_password')->SetLabel('Admin Password') + ->SetDefaultValue(''), + \RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) + ->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net') + ->SetDefaultValue('*') + ); + } +}