From 7d1f105cfb895b6cc6c102e643b2c6cbe1f92050 Mon Sep 17 00:00:00 2001 From: RainLoop Team Date: Fri, 22 Nov 2013 02:04:25 +0400 Subject: [PATCH] ISP manager Change password plugin --- .../IspManagerChangePasswordDriver.php | 151 ++++++++++++++++++ plugins/ispmanager-change-password/LICENSE | 20 +++ plugins/ispmanager-change-password/README | 1 + plugins/ispmanager-change-password/VERSION | 1 + plugins/ispmanager-change-password/index.php | 76 +++++++++ 5 files changed, 249 insertions(+) create mode 100644 plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php create mode 100644 plugins/ispmanager-change-password/LICENSE create mode 100644 plugins/ispmanager-change-password/README create mode 100644 plugins/ispmanager-change-password/VERSION create mode 100644 plugins/ispmanager-change-password/index.php diff --git a/plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php b/plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php new file mode 100644 index 000000000..bfdbe2463 --- /dev/null +++ b/plugins/ispmanager-change-password/IspManagerChangePasswordDriver.php @@ -0,0 +1,151 @@ +sDsn = $sDsn; + $this->sUser = $sUser; + $this->sPassword = $sPassword; + + return $this; + } + + /** + * @param string $aDomains + * + * @return \IspManagerChangePasswordDriver + */ + public function SetAllowedEmails($sAllowedEmails) + { + $this->sAllowedEmails = $sAllowedEmails; + return $this; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \IspManagerChangePasswordDriver + */ + public function SetLogger($oLogger) + { + if ($oLogger instanceof \MailSo\Log\Logger) + { + $this->oLogger = $oLogger; + } + + return $this; + } + + /** + * @param \RainLoop\Account $oAccount + * + * @return bool + */ + public function PasswordChangePossibility($oAccount) + { + return $oAccount && $oAccount->Email() && + \RainLoop\Plugins\Helper::ValidateWildcardValues($oAccount->Email(), $this->sAllowedEmails); + } + + /** + * @param \RainLoop\Account $oAccount + * @param string $sPrevPassword + * @param string $sNewPassword + * + * @return bool + */ + public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword) + { + if ($this->oLogger) + { + $this->oLogger->Write('ISP: Try to change password for '.$oAccount->Email()); + } + + $bResult = false; + if (!empty($this->sDsn) && 0 < \strlen($this->sUser) && 0 < \strlen($this->sPassword) && $oAccount) + { + try + { + $oPdo = new \PDO($this->sDsn, $this->sUser, $this->sPassword); + $oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION); + + $oStmt = $oPdo->prepare('SELECT password, mailuser_id FROM mail_user WHERE login = ?'); + if ($oStmt->execute(array($oAccount->IncLogin()))) + { + $aFetchResult = $oStmt->fetch(\PDO::FETCH_ASSOC); + if (\is_array($aFetchResult) && isset($aFetchResult['password'], $aFetchResult['mailuser_id'])) + { + $sDbPassword = \stripslashes($aFetchResult['password']); + $sDbSalt = '$1$'.\substr($sDbPassword, 3, 8).'$'; + + if (\crypt(\stripslashes($sPrevPassword), $sDbSalt) === $sDbPassword) + { + $oStmt = $oPdo->prepare('UPDATE mail_user SET password = ? WHERE mailuser_id = ?'); + $bResult = (bool) $oStmt->execute( + array($this->cryptPassword($sNewPassword), $aFetchResult['mailuser_id'])); + } + } + } + } + catch (\Exception $oException) + { + if ($this->oLogger) + { + $this->oLogger->WriteException($oException); + } + } + } + + return $bResult; + } + + /** + * @param string $sPassword + * @return string + */ + private function cryptPassword($sPassword) + { + $sSalt = ''; + $sBase64 = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/'; + + for ($iIndex = 0; $iIndex < 8; $iIndex++) + { + $sSalt .= $sBase64[\rand(0, 63)]; + } + + return \crypt($sPassword, '$1$'.$sSalt.'$'); + } +} \ No newline at end of file diff --git a/plugins/ispmanager-change-password/LICENSE b/plugins/ispmanager-change-password/LICENSE new file mode 100644 index 000000000..271342337 --- /dev/null +++ b/plugins/ispmanager-change-password/LICENSE @@ -0,0 +1,20 @@ +The MIT License (MIT) + +Copyright (c) 2013 RainLoop Team + +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/ispmanager-change-password/README b/plugins/ispmanager-change-password/README new file mode 100644 index 000000000..37c0ce352 --- /dev/null +++ b/plugins/ispmanager-change-password/README @@ -0,0 +1 @@ +Plugin that adds functionality to change the email account password (ISPmanager). \ No newline at end of file diff --git a/plugins/ispmanager-change-password/VERSION b/plugins/ispmanager-change-password/VERSION new file mode 100644 index 000000000..9f8e9b69a --- /dev/null +++ b/plugins/ispmanager-change-password/VERSION @@ -0,0 +1 @@ +1.0 \ No newline at end of file diff --git a/plugins/ispmanager-change-password/index.php b/plugins/ispmanager-change-password/index.php new file mode 100644 index 000000000..4507b3e66 --- /dev/null +++ b/plugins/ispmanager-change-password/index.php @@ -0,0 +1,76 @@ +addHook('main.fabrica', 'MainFabrica'); + } + + /** + * @return string + */ + public function Supported() + { + if (!extension_loaded('pdo') || !class_exists('PDO')) + { + return 'The PHP exention PDO (mysql) must be installed to use this plugin'; + } + + $aDrivers = \PDO::getAvailableDrivers(); + if (!is_array($aDrivers) || !in_array('mysql', $aDrivers)) + { + return 'The PHP exention PDO (mysql) must be installed to use this plugin'; + } + + return ''; + } + + /** + * @param string $sName + * @param mixed $oProvider + */ + public function MainFabrica($sName, &$oProvider) + { + switch ($sName) + { + case 'change-password': + + $sDsn = \trim($this->Config()->Get('plugin', 'pdo_dsn', '')); + $sUser = (string) $this->Config()->Get('plugin', 'user', ''); + $sPassword = (string) $this->Config()->Get('plugin', 'password', ''); + + if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword)) + { + include_once __DIR__.'/IspManagerChangePasswordDriver.php'; + + $oProvider = new IspManagerChangePasswordDriver(); + $oProvider->SetLogger($this->Manager()->Actions()->Logger()); + $oProvider->SetConfig($sDsn, $sUser, $sPassword); + $oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', '')))); + } + + break; + } + } + + /** + * @return array + */ + public function configMapping() + { + return array( + \RainLoop\Plugins\Property::NewInstance('pdo_dsn')->SetLabel('ISPmanager PDO dsn') + ->SetDefaultValue('mysql:host=127.0.0.1;dbname=dbispconfig'), + \RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User') + ->SetDefaultValue('root'), + \RainLoop\Plugins\Property::NewInstance('password')->SetLabel('DB Password') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::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('*') + ); + } +} \ No newline at end of file