From e1768a13dc199c376186727147b9950cf2896705 Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Sun, 10 Mar 2019 17:15:45 +0100 Subject: [PATCH 1/2] Added generic REST plugin --- plugins/rest-change-password/LICENSE | 20 ++ plugins/rest-change-password/README | 1 + .../RestChangePasswordDriver.php | 172 ++++++++++++++++++ plugins/rest-change-password/VERSION | 1 + plugins/rest-change-password/index.php | 78 ++++++++ 5 files changed, 272 insertions(+) create mode 100644 plugins/rest-change-password/LICENSE create mode 100644 plugins/rest-change-password/README create mode 100644 plugins/rest-change-password/RestChangePasswordDriver.php create mode 100644 plugins/rest-change-password/VERSION create mode 100644 plugins/rest-change-password/index.php diff --git a/plugins/rest-change-password/LICENSE b/plugins/rest-change-password/LICENSE new file mode 100644 index 000000000..271342337 --- /dev/null +++ b/plugins/rest-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/rest-change-password/README b/plugins/rest-change-password/README new file mode 100644 index 000000000..f045f42e7 --- /dev/null +++ b/plugins/rest-change-password/README @@ -0,0 +1 @@ +Plugin that adds functionality to change the email account password (Generic REST). \ No newline at end of file diff --git a/plugins/rest-change-password/RestChangePasswordDriver.php b/plugins/rest-change-password/RestChangePasswordDriver.php new file mode 100644 index 000000000..72a77fefb --- /dev/null +++ b/plugins/rest-change-password/RestChangePasswordDriver.php @@ -0,0 +1,172 @@ +sUrl = $sUrl; + $this->sKey = $sKey; + + return $this; + } + + $oProvider->SetFieldNames($sFieldEmail, $sFieldOldpassword, $sFieldNewpassword); + + /** + * @param string $sFieldEmail + * @param string $sFieldOldpassword + * @param string $sFieldNewpassword + * + * @return \RestChangePasswordDriver + */ + public function SetFieldNames($sFieldEmail, $sFieldOldpassword, $sFieldNewpassword) + { + $this->sFieldEmail = $sFieldEmail; + $this->sFieldOldpassword = $sFieldOldpassword; + $this->sFieldNewpassword = $sFieldNewpassword; + return $this; + } + + /** + * @param string $sAllowedEmails + * + * @return \RestChangePasswordDriver + */ + public function SetAllowedEmails($sAllowedEmails) + { + $this->sAllowedEmails = $sAllowedEmails; + return $this; + } + + /** + * @param \MailSo\Log\Logger $oLogger + * + * @return \RestChangePasswordDriver + */ + 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('Rest: Try to change password for '.$oAccount->Email()); + } + + $bResult = false; + if (!empty($this->sHost) && 0 < $this->iPort && $oAccount) + { + $sEmail = \trim(\strtolower($oAccount->Email())); + + # Adding the REST Api key to the url, try to use always https + $sUrl = str_replace('://', '://'+$this->sKey+"@", $this->sUrl); + + $iCode = 0; + $oHttp = \MailSo\Base\Http::SingletonInstance(); + + if ($this->oLogger) + { + $this->oLogger->Write('Rest[Api Request]:'.$sUrl); + } + + $mResult = $oHttp->SendPostRequest($sUrl, + array( + $this->sFieldEmail => $sEmail, + $this->sFieldOldpassword => $sPrevPassword, + $this->sFieldNewpassword => $sNewPassword, + ), 'MailSo Http User Agent (v1)', $iCode, $this->oLogger); + + if (false !== $mResult && 200 === $iCode) + { + $aRes = null; + @\parse_str($mResult, $aRes); + if (is_array($aRes) && (!isset($aRes['error']) || (int) $aRes['error'] !== 1)) + { + $bResult = true; + } + else + { + if ($this->oLogger) + { + $this->oLogger->Write('Rest[Error]: Response: '.$mResult); + } + } + } + else + { + if ($this->oLogger) + { + $this->oLogger->Write('Rest[Error]: Empty Response: Code:'.$iCode); + } + } + } + + return $bResult; + } +} diff --git a/plugins/rest-change-password/VERSION b/plugins/rest-change-password/VERSION new file mode 100644 index 000000000..9f8e9b69a --- /dev/null +++ b/plugins/rest-change-password/VERSION @@ -0,0 +1 @@ +1.0 \ No newline at end of file diff --git a/plugins/rest-change-password/index.php b/plugins/rest-change-password/index.php new file mode 100644 index 000000000..115a7303f --- /dev/null +++ b/plugins/rest-change-password/index.php @@ -0,0 +1,78 @@ +addHook('main.fabrica', 'MainFabrica'); + } + + /** + * @param string $sName + * @param mixed $oProvider + */ + public function MainFabrica($sName, &$oProvider) + { + switch ($sName) + { + case 'change-password': + + $sUrl = \trim($this->Config()->Get('plugin', 'rest_url', '')); + $sKey = \trim($this->Config()->Get('plugin', 'rest_key', '')); + + $sFieldEmail = \trim($this->Config()->Get('plugin', 'rest_field_email', '')); + $sFieldOldpassword = \trim($this->Config()->Get('plugin', 'rest_field_oldpassword', '')); + $sFieldNewpassword = \trim($this->Config()->Get('plugin', 'rest_field_newpassword', '')); + + if (!empty($sHost) && (!empty($sKey)) + { + include_once __DIR__.'/RestChangePasswordDriver.php'; + + $oProvider = new RestChangePasswordDriver(); + $oProvider->SetLogger($this->Manager()->Actions()->Logger()); + $oProvider->SetConfig($sUrl, $sKey); + $oProvider->SetFieldNames($sFieldEmail, $sFieldOldpassword, $sFieldNewpassword); + $oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', '')))); + } + + break; + } + } + + /** + * @return array + */ + public function configMapping() + { + return array( + \RainLoop\Plugins\Property::NewInstance('rest_url') + ->SetLabel('REST API Url') + ->SetDefaultValue('') + ->SetDescription('Ex: http://localhost:8080/api/change_password or https://domain.com/api/user/passsword_update'), + \RainLoop\Plugins\Property::NewInstance('rest_key') + ->SetLabel('REST API key') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD) + ->SetDescription('REST API Key for authentication, if you have "user" and "passsword" enter it as "user:password"') + ->SetDefaultValue(''), + \RainLoop\Plugins\Property::NewInstance('rest_field_email') + ->SetLabel('Field "email" name') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) + ->SetDescription('Enter the name of the REST field name for email') + ->SetDefaultValue('email'), + \RainLoop\Plugins\Property::NewInstance('rest_field_oldpassword') + ->SetLabel('Field "oldpassword" name') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) + ->SetDescription('Enter the name of the REST field name for oldpassword') + ->SetDefaultValue('oldpassword'), + \RainLoop\Plugins\Property::NewInstance('rest_field_newpassword') + ->SetLabel('Field "newpassword" name') + ->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT) + ->SetDescription('Enter the name of the REST field name for newpassword') + ->SetDefaultValue('newpassword'), + \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('*') + ); + } +} From b8ad70a8e3926c7f1ac70bd25a04c341181b009d Mon Sep 17 00:00:00 2001 From: Ernesto Serrano Date: Thu, 14 Mar 2019 14:45:19 +0100 Subject: [PATCH 2/2] Update index.php --- plugins/rest-change-password/index.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/rest-change-password/index.php b/plugins/rest-change-password/index.php index 115a7303f..63aeaa446 100644 --- a/plugins/rest-change-password/index.php +++ b/plugins/rest-change-password/index.php @@ -24,7 +24,7 @@ class RestChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin $sFieldOldpassword = \trim($this->Config()->Get('plugin', 'rest_field_oldpassword', '')); $sFieldNewpassword = \trim($this->Config()->Get('plugin', 'rest_field_newpassword', '')); - if (!empty($sHost) && (!empty($sKey)) + if (!empty($sHost) && (!empty($sKey))) { include_once __DIR__.'/RestChangePasswordDriver.php';