Open andypl78 opened 7 years ago
I don't know how to make a new plugin or how to use the API of ISPConfig 3.1 so I edited the old one to support one Master and one Slave. Hope this help.
Index.php:
<?php
class IspconfigChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
{
public function Init()
{
$this->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', '');
$sDsn2 = \trim($this->Config()->Get('plugin', 'pdo_dsn2', ''));
$sUser2 = (string) $this->Config()->Get('plugin', 'user2', '');
$sPassword2 = (string) $this->Config()->Get('plugin', 'password2', '');
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
{
include_once __DIR__.'/IspConfigChangePasswordDriver.php';
$oProvider = new IspConfigChangePasswordDriver();
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
$oProvider->SetConfig($sDsn, $sUser, $sPassword, $sDsn2, $sUser2, $sPassword2);
$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('Master ISPConfig PDO dsn')
->SetDefaultValue('mysql:host=127.0.0.1;dbname=dbispconfig'),
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('Master DB User')
->SetDefaultValue('root'),
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('Master DB Password')
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
->SetDefaultValue(''),
\RainLoop\Plugins\Property::NewInstance('pdo_dsn2')->SetLabel('Slave ISPConfig PDO dsn')
->SetDefaultValue('mysql:host=127.0.0.1;dbname=dbispconfig'),
\RainLoop\Plugins\Property::NewInstance('user2')->SetLabel('Slave DB User')
->SetDefaultValue('root'),
\RainLoop\Plugins\Property::NewInstance('password2')->SetLabel('Slave 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('*')
);
}
}
IspConfigChangePasswordDriver.php:
<?php
class IspConfigChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
{
/**
* @var string
*/
private $sDsn = '';
/**
* @var string
*/
private $sUser = '';
/**
* @var string
*/
private $sPassword = '';
/**
* @var string
*/
private $sDsn2 = '';
/**
* @var string
*/
private $sUser2 = '';
/**
* @var string
*/
private $sPassword2 = '';
/**
* @var string
*/
private $sAllowedEmails = '';
/**
* @var \MailSo\Log\Logger
*/
private $oLogger = null;
/**
* @param string $sDsn
* @param string $sUser
* @param string $sPassword
* @param string $sDsn2
* @param string $sUser2
* @param string $sPassword2
*
* @return \IspConfigChangePasswordDriver
*/
public function SetConfig($sDsn, $sUser, $sPassword, $sDsn2, $sUser2, $sPassword2)
{
$this->sDsn = $sDsn;
$this->sUser = $sUser;
$this->sPassword = $sPassword;
$this->sDsn2 = $sDsn2;
$this->sUser2 = $sUser2;
$this->sPassword2 = $sPassword2;
return $this;
}
/**
* @param string $sAllowedEmails
*
* @return \IspConfigChangePasswordDriver
*/
public function SetAllowedEmails($sAllowedEmails)
{
$this->sAllowedEmails = $sAllowedEmails;
return $this;
}
/**
* @param \MailSo\Log\Logger $oLogger
*
* @return \IspConfigChangePasswordDriver
*/
public function SetLogger($oLogger)
{
if ($oLogger instanceof \MailSo\Log\Logger)
{
$this->oLogger = $oLogger;
}
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)
{
if ($this->oLogger)
{
$this->oLogger->Write('ISP: Try to change password for '.$oAccount->Email());
}
$bResult = false;
$bResult2 = false;
$sNewPass = $this->cryptPassword($sNewPassword);
$sOldPass = '';
if (!empty($this->sDsn) && !empty($this->sDsn2) && 0 < \strlen($this->sUser) && 0 < \strlen($this->sUser2) && 0 < \strlen($this->sPassword) && \strlen($this->sPassword2) && $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 = ? LIMIT 1');
if ($oStmt->execute(array($oAccount->IncLogin())))
{
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['mailuser_id']))
{
$sDbPassword = \stripslashes($aFetchResult[0]['password']);
$sOldPass = $sDbPassword;
$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($sNewPass, $aFetchResult[0]['mailuser_id']));
}
}
}
$oPdo = new \PDO($this->sDsn2, $this->sUser2, $this->sPassword2);
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$oStmt = $oPdo->prepare('SELECT password, mailuser_id FROM mail_user WHERE login = ? LIMIT 1');
if ($oStmt->execute(array($oAccount->IncLogin())))
{
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['mailuser_id']))
{
$sDbPassword = \stripslashes($aFetchResult[0]['password']);
$sDbSalt = '$1$'.\substr($sDbPassword, 3, 8).'$';
if (\crypt(\stripslashes($sPrevPassword), $sDbSalt) === $sDbPassword)
{
$oStmt = $oPdo->prepare('UPDATE mail_user SET password = ? WHERE mailuser_id = ?');
$bResult2 = (bool) $oStmt->execute(
array($sNewPass, $aFetchResult[0]['mailuser_id']));
}
}
}
}
catch (\Exception $oException)
{
if($bResult && !$bResult2)
{
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 = ? LIMIT 1');
if ($oStmt->execute(array($oAccount->IncLogin())))
{
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['mailuser_id']))
{
$sDbPassword = \stripslashes($aFetchResult[0]['password']);
$sDbSalt = '$1$'.\substr($sDbPassword, 3, 8).'$';
$oStmt = $oPdo->prepare('UPDATE mail_user SET password = ? WHERE mailuser_id = ?');
$oStmt->execute(array($sOldPass, $aFetchResult[0]['mailuser_id']));
}
}
}
catch (\Exception $oException)
{
$this->oLogger->WriteException($oException);
}
}
if ($this->oLogger)
{
$this->oLogger->WriteException($oException);
}
}
}
return $bResult2;
}
/**
* @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.'$');
}
}
Hi, did anyone manage to get this to work? I can't get this plugin to work with ISPconfig 3.1
My God ... we are in September of 2019 and this problem still exist? What happened to the amazing developers of this plugin? Help us, please! This plugin doesn't work in multi servers!
Hi, did anyone manage to get this to work? I can't get this plugin to work with ISPconfig 3.1
Same problem here... I almost broke Google serching for a solution, but I don't found. I tried the @OrihuelaConde code also, but also not work for me. I am using ISPConfig 3.1.15 on 5 Debian 9, multi server, dedicated web, mail, etc...
My God ... we are in September of 2019 and this problem still exist? What happened to the amazing developers of this plugin? Help us, please! This plugin doesn't work in multi servers!
I'm rather surprised as well.
The plugin works on one of the domains controlled by ISPConfig but not another. The broken domain simply returns, "Could not save password".
I deployed a fine solution
RainLoop version, browser, OS: Latest
Please add posibility to change password via API ISPConfig 3.1