mirror of
https://github.com/the-djmaze/snappymail.git
synced 2024-09-20 07:35:55 +08:00
Bugfix: bootstrap jQuery('#') syntax error
Changed: use ES2015 Changed: gulp uglify to terser Removed: ChangePassword Removed: nanoscroll Removed: JS polyfills
This commit is contained in:
parent
9aa0cf92a9
commit
aae7883b99
|
@ -65,17 +65,7 @@ export const bSafari = !bChrome && -1 < sUserAgent.indexOf('safari');
|
|||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const bMobileDevice =
|
||||
(/android/i).test(sUserAgent) ||
|
||||
(/iphone/i).test(sUserAgent) ||
|
||||
(/ipod/i).test(sUserAgent) ||
|
||||
(/ipad/i).test(sUserAgent) ||
|
||||
(/blackberry/i).test(sUserAgent);
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
*/
|
||||
export const bDisableNanoScroll = bMobileDevice;
|
||||
export const bMobileDevice = (/android|iphone|ipod|ipad|blackberry|mobile/i).test(sUserAgent);
|
||||
|
||||
/**
|
||||
* @type {boolean}
|
||||
|
|
16
dev/External/ko.js
vendored
16
dev/External/ko.js
vendored
|
@ -711,22 +711,6 @@ ko.bindingHandlers.droppable = {
|
|||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.nano = {
|
||||
init: (element) => {
|
||||
const Globals = require('Common/Globals'),
|
||||
Settings = require('Storage/Settings');
|
||||
|
||||
if (!Globals.bDisableNanoScroll && !Settings.appSettingsGet('useNativeScrollbars')) {
|
||||
$(element)
|
||||
.addClass('nano')
|
||||
.nanoScroller({
|
||||
iOSNativeScrolling: false,
|
||||
preventPageScrolling: true
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
ko.bindingHandlers.saveTrigger = {
|
||||
init: (element) => {
|
||||
const $el = $(element);
|
||||
|
|
|
@ -721,18 +721,6 @@ class RemoteUserAjax extends AbstractAjaxRemote {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} prevPassword
|
||||
* @param {string} newPassword
|
||||
*/
|
||||
changePassword(fCallback, prevPassword, newPassword) {
|
||||
this.defaultRequest(fCallback, 'ChangePassword', {
|
||||
'PrevPassword': prevPassword,
|
||||
'NewPassword': newPassword
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @param {?Function} fCallback
|
||||
* @param {string} sFolderFullNameRaw
|
||||
|
|
|
@ -16,7 +16,6 @@ import { ContactsUserSettings } from 'Settings/User/Contacts';
|
|||
import { AccountsUserSettings } from 'Settings/User/Accounts';
|
||||
import { FiltersUserSettings } from 'Settings/User/Filters';
|
||||
import { SecurityUserSettings } from 'Settings/User/Security';
|
||||
import { ChangePasswordUserSettings } from 'Settings/User/ChangePassword';
|
||||
import { TemplatesUserSettings } from 'Settings/User/Templates';
|
||||
import { FoldersUserSettings } from 'Settings/User/Folders';
|
||||
import { ThemesUserSettings } from 'Settings/User/Themes';
|
||||
|
@ -79,15 +78,6 @@ class SettingsUserScreen extends AbstractSettingsScreen {
|
|||
addSettingsViewModel(SecurityUserSettings, 'SettingsSecurity', 'SETTINGS_LABELS/LABEL_SECURITY_NAME', 'security');
|
||||
}
|
||||
|
||||
if (Settings.settingsGet('ChangePasswordIsAllowed')) {
|
||||
addSettingsViewModel(
|
||||
ChangePasswordUserSettings,
|
||||
'SettingsChangePassword',
|
||||
'SETTINGS_LABELS/LABEL_CHANGE_PASSWORD_NAME',
|
||||
'change-password'
|
||||
);
|
||||
}
|
||||
|
||||
if (Settings.capa(Capa.Templates)) {
|
||||
addSettingsViewModel(
|
||||
TemplatesUserSettings,
|
||||
|
|
|
@ -1,104 +0,0 @@
|
|||
import _ from '_';
|
||||
import ko from 'ko';
|
||||
|
||||
import { StorageResultType, Notification } from 'Common/Enums';
|
||||
import { getNotificationFromResponse, i18n } from 'Common/Translator';
|
||||
|
||||
import Remote from 'Remote/User/Ajax';
|
||||
|
||||
import { getApp } from 'Helper/Apps/User';
|
||||
import { command } from 'Knoin/Knoin';
|
||||
|
||||
class ChangePasswordUserSettings {
|
||||
constructor() {
|
||||
this.changeProcess = ko.observable(false);
|
||||
|
||||
this.errorDescription = ko.observable('');
|
||||
this.passwordMismatch = ko.observable(false);
|
||||
this.passwordUpdateError = ko.observable(false);
|
||||
this.passwordUpdateSuccess = ko.observable(false);
|
||||
|
||||
this.currentPassword = ko.observable('');
|
||||
this.currentPassword.error = ko.observable(false);
|
||||
this.newPassword = ko.observable('');
|
||||
this.newPassword2 = ko.observable('');
|
||||
|
||||
this.currentPassword.subscribe(() => {
|
||||
this.passwordUpdateError(false);
|
||||
this.passwordUpdateSuccess(false);
|
||||
this.currentPassword.error(false);
|
||||
});
|
||||
|
||||
this.newPassword.subscribe(() => {
|
||||
this.passwordUpdateError(false);
|
||||
this.passwordUpdateSuccess(false);
|
||||
this.passwordMismatch(false);
|
||||
});
|
||||
|
||||
this.newPassword2.subscribe(() => {
|
||||
this.passwordUpdateError(false);
|
||||
this.passwordUpdateSuccess(false);
|
||||
this.passwordMismatch(false);
|
||||
});
|
||||
|
||||
this.onChangePasswordResponse = _.bind(this.onChangePasswordResponse, this);
|
||||
}
|
||||
|
||||
@command(
|
||||
(self) =>
|
||||
!self.changeProcess() && '' !== self.currentPassword() && '' !== self.newPassword() && '' !== self.newPassword2()
|
||||
)
|
||||
saveNewPasswordCommand() {
|
||||
if (this.newPassword() !== this.newPassword2()) {
|
||||
this.passwordMismatch(true);
|
||||
this.errorDescription(i18n('SETTINGS_CHANGE_PASSWORD/ERROR_PASSWORD_MISMATCH'));
|
||||
} else {
|
||||
this.changeProcess(true);
|
||||
|
||||
this.passwordUpdateError(false);
|
||||
this.passwordUpdateSuccess(false);
|
||||
this.currentPassword.error(false);
|
||||
this.passwordMismatch(false);
|
||||
this.errorDescription('');
|
||||
|
||||
Remote.changePassword(this.onChangePasswordResponse, this.currentPassword(), this.newPassword());
|
||||
}
|
||||
}
|
||||
|
||||
onHide() {
|
||||
this.changeProcess(false);
|
||||
this.currentPassword('');
|
||||
this.newPassword('');
|
||||
this.newPassword2('');
|
||||
this.errorDescription('');
|
||||
this.passwordMismatch(false);
|
||||
this.currentPassword.error(false);
|
||||
}
|
||||
|
||||
onChangePasswordResponse(result, data) {
|
||||
this.changeProcess(false);
|
||||
this.passwordMismatch(false);
|
||||
this.errorDescription('');
|
||||
this.currentPassword.error(false);
|
||||
|
||||
if (StorageResultType.Success === result && data && data.Result) {
|
||||
this.currentPassword('');
|
||||
this.newPassword('');
|
||||
this.newPassword2('');
|
||||
|
||||
this.passwordUpdateSuccess(true);
|
||||
this.currentPassword.error(false);
|
||||
|
||||
getApp().setClientSideToken(data.Result);
|
||||
} else {
|
||||
if (data && Notification.CurrentPasswordIncorrect === data.ErrorCode) {
|
||||
this.currentPassword.error(true);
|
||||
}
|
||||
|
||||
this.passwordUpdateError(true);
|
||||
this.errorDescription(getNotificationFromResponse(data, Notification.CouldNotSaveNewPassword));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export { ChangePasswordUserSettings, ChangePasswordUserSettings as default };
|
|
@ -50,7 +50,6 @@
|
|||
@import "Ui.less";
|
||||
@import "Main.less";
|
||||
@import "Layout.less";
|
||||
@import "Scroll.less";
|
||||
@import "Components.less";
|
||||
@import "SystemDropDown.less";
|
||||
@import "Login.less";
|
||||
|
|
|
@ -1,38 +0,0 @@
|
|||
|
||||
.nano.scroller-shadow-top:before, .nano.scroller-shadow-bottom:after {
|
||||
content: "";
|
||||
position: absolute;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 10px;
|
||||
z-index: 102;
|
||||
box-shadow: 0px 0px 20px rgba(0, 0, 0, 0.4);
|
||||
}
|
||||
|
||||
.nano.scroller-shadow-top:before {
|
||||
top: -10px;
|
||||
}
|
||||
|
||||
.nano.scroller-shadow-bottom:after {
|
||||
bottom: -10px;
|
||||
}
|
||||
|
||||
.nano.fixIndex.scroller-shadow-top:before, .nano.fixIndex.scroller-shadow-bottom:after {
|
||||
z-index: 98;
|
||||
}
|
||||
|
||||
/*
|
||||
.nano {
|
||||
.pane .slider {
|
||||
.transition(top 0.1s ease-out);
|
||||
}
|
||||
|
||||
.pane2 .slider2 {
|
||||
.transition(left 0.1s ease-out);
|
||||
}
|
||||
|
||||
.pane.active .slider, .pane2.active .slider2 {
|
||||
.transition(none);
|
||||
}
|
||||
}
|
||||
*/
|
|
@ -1,9 +1,3 @@
|
|||
import elementDatasetPolyfill from 'element-dataset';
|
||||
elementDatasetPolyfill();
|
||||
|
||||
require('json3');
|
||||
require('intersection-observer');
|
||||
|
||||
import window from 'window';
|
||||
import { progressJs } from '../vendors/Progress.js/src/progress.js';
|
||||
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
import 'core-js/features/object/assign';
|
||||
import 'core-js/features/array/includes';
|
||||
import 'core-js/features/string/includes';
|
||||
import 'core-js/features/promise';
|
||||
import 'raf/polyfill';
|
16
package.json
16
package.json
|
@ -49,7 +49,6 @@
|
|||
"@babel/core": "7.8.4",
|
||||
"@babel/plugin-proposal-class-properties": "7.8.3",
|
||||
"@babel/plugin-proposal-decorators": "7.8.3",
|
||||
"@babel/plugin-transform-runtime": "7.8.3",
|
||||
"@babel/preset-env": "7.8.4",
|
||||
"@babel/runtime-corejs3": "7.8.4",
|
||||
"autolinker": "3.11.1",
|
||||
|
@ -57,9 +56,7 @@
|
|||
"babel-loader": "8.0.6",
|
||||
"classnames": "2.2.6",
|
||||
"copy-webpack-plugin": "5.1.1",
|
||||
"core-js": "3.6.4",
|
||||
"css-loader": "3.4.2",
|
||||
"element-dataset": "2.2.6",
|
||||
"emailjs-addressparser": "2.0.2",
|
||||
"eslint": "6.8.0",
|
||||
"eslint-config-prettier": "6.10.0",
|
||||
|
@ -85,24 +82,17 @@
|
|||
"gulp-size": "3.0.0",
|
||||
"gulp-sourcemaps": "2.6.5",
|
||||
"gulp-stripbom": "1.0.5",
|
||||
"gulp-terser": "^1.2.0",
|
||||
"gulp-through": "0.4.0",
|
||||
"gulp-uglify": "3.0.2",
|
||||
"gulp-util": "3.0.8",
|
||||
"gulp-zip": "5.0.1",
|
||||
"ifvisible.js": "1.0.6",
|
||||
"intersection-observer": "0.7.0",
|
||||
"jquery": "3.4.1",
|
||||
"jquery-backstretch": "2.1.18",
|
||||
"jquery-migrate": "3.1.0",
|
||||
"jquery-mousewheel": "3.1.13",
|
||||
"jquery-scrollstop": "1.2.0",
|
||||
"js-cookie": "2.2.1",
|
||||
"json-loader": "0.5.7",
|
||||
"json3": "3.3.3",
|
||||
"knockout": "3.4.2",
|
||||
"knockout-sortable": "1.2.0",
|
||||
"lozad": "1.14.0",
|
||||
"matchmedia-polyfill": "0.3.2",
|
||||
"moment": "2.24.0",
|
||||
"node-fs": "0.1.7",
|
||||
"normalize.css": "8.0.1",
|
||||
|
@ -110,7 +100,6 @@
|
|||
"opentip": "2.4.3",
|
||||
"pikaday": "1.8.0",
|
||||
"prettier": "1.19.1",
|
||||
"raf": "3.4.1",
|
||||
"raw-loader": "4.0.0",
|
||||
"rimraf": "3.0.1",
|
||||
"simplestatemanager": "4.1.1",
|
||||
|
@ -118,5 +107,6 @@
|
|||
"underscore": "1.9.2",
|
||||
"webpack": "4.41.5",
|
||||
"webpack-cli": "3.3.10"
|
||||
}
|
||||
},
|
||||
"dependencies": {}
|
||||
}
|
||||
|
|
|
@ -1,237 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mDatabase = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mTable = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mSql = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mDatabase
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmDatabase($mDatabase)
|
||||
{
|
||||
$this->mDatabase = $mDatabase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mTable
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmTable($mTable)
|
||||
{
|
||||
$this->mTable = $mTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mSql
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
public function SetmSql($mSql)
|
||||
{
|
||||
$this->mSql = $mSql;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCustomSqlDriver
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
|
||||
$dsn = 'mysql:host='.$this->mHost.';dbname='.$this->mDatabase.';charset=utf8';
|
||||
$options = array(
|
||||
PDO::ATTR_EMULATE_PREPARES => true,
|
||||
PDO::ATTR_PERSISTENT => true,
|
||||
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
|
||||
);
|
||||
|
||||
try
|
||||
{
|
||||
$conn = new PDO($dsn,$this->mUser,$this->mPass,$options);
|
||||
|
||||
//prepare SQL varaibles
|
||||
$sEmail = $oAccount->Email();
|
||||
$sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
|
||||
$sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
|
||||
|
||||
// some variables cannot be prepared
|
||||
$this->mSql = str_replace(array(
|
||||
':table'
|
||||
), array(
|
||||
$this->mTable
|
||||
), $this->mSql);
|
||||
|
||||
$placeholders = array(
|
||||
':email' => $sEmail,
|
||||
':oldpass' => $sPrevPassword,
|
||||
':newpass' => $sNewPassword,
|
||||
':domain' => $sEmailDomain,
|
||||
':username' => $sEmailUser
|
||||
);
|
||||
|
||||
// we have to check that all placehoders are used in the query, passing any unused placeholders will generate an error
|
||||
$used_placeholders = array();
|
||||
|
||||
foreach($placeholders as $placeholder => $value) {
|
||||
if(preg_match_all('/'.$placeholder . '(?![a-zA-Z0-9\-])'.'/', $this->mSql) === 1) {
|
||||
// backwards-compabitibility: remove single and double quotes around placeholders
|
||||
$this->mSql = str_replace('`'.$placeholder.'`', $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace("'".$placeholder."'", $placeholder, $this->mSql);
|
||||
$this->mSql = str_replace('"'.$placeholder.'"', $placeholder, $this->mSql);
|
||||
$used_placeholders[$placeholder] = $value;
|
||||
}
|
||||
}
|
||||
|
||||
$statement = $conn->prepare($this->mSql);
|
||||
|
||||
// everything is ready (hopefully), bind the values
|
||||
foreach($used_placeholders as $placeholder => $value) {
|
||||
$statement->bindValue($placeholder, $value);
|
||||
}
|
||||
|
||||
// and execute
|
||||
$mSqlReturn = $statement->execute();
|
||||
|
||||
/* can be used for debugging
|
||||
ob_start();
|
||||
$statement->debugDumpParams();
|
||||
$r = ob_get_contents();
|
||||
ob_end_clean();
|
||||
$this->oLogger->Write($r);
|
||||
*/
|
||||
|
||||
if ($mSqlReturn == true)
|
||||
{
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! Password changed.');
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either current password is incorrect, or new password does not match criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Martin Vilimovsky (vilimovsky@mvcs.cz)
|
||||
|
||||
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.
|
|
@ -1 +0,0 @@
|
|||
You can use your own SQL (MySQL) statement (with wildcards) to change password
|
|
@ -1,10 +0,0 @@
|
|||
Rainloop change password custom mysql plugin
|
||||
============================================
|
||||
|
||||
This plugin adds change password capability to Rainloop webmail by write your own SQL statement
|
||||
|
||||
##### Installation is simple:
|
||||
|
||||
1. Drop the change-password-custom-sql in the plugins directory (eg. _RainLoopDir_/data/data_xxxxx/_default/plugins/*)
|
||||
2. In rainloop admin panel go to Plugins, and activate change-password-custom-sql.
|
||||
3. Enter mysql details on the plugin config screen.
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,53 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCustomSqlPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCustomSqlDriver.php';
|
||||
$oProvider = new ChangePasswordCustomSqlDriver();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
->SetmDatabase($this->Config()->Get('plugin', 'mDatabase', ''))
|
||||
->SetmTable($this->Config()->Get('plugin', 'mTable', ''))
|
||||
->SetmSql($this->Config()->Get('plugin', 'mSql', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD),
|
||||
\RainLoop\Plugins\Property::NewInstance('mDatabase')->SetLabel('MySQL Database'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mTable')->SetLabel('MySQL Table'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mSql')->SetLabel('SQL statement')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::STRING_TEXT)
|
||||
->SetDescription('SQL statement (allowed wildcards :table, :email, :oldpass, :newpass, :domain, :username). Use SQL functions for encryption.')
|
||||
->SetDefaultValue('UPDATE :table SET password = md5(:newpass) WHERE domain = :domain AND username = :username and oldpass = md5(:oldpass)')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCyberPanel implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $mPass = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $mHost
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmHost($mHost)
|
||||
{
|
||||
$this->mHost = $mHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mUser
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmUser($mUser)
|
||||
{
|
||||
$this->mUser = $mUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $mPass
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
public function SetmPass($mPass)
|
||||
{
|
||||
$this->mPass = $mPass;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordCyberPanel
|
||||
*/
|
||||
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();
|
||||
}
|
||||
|
||||
/**
|
||||
* @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('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
$db = mysqli_connect($this->mHost, $this->mUser, $this->mPass, 'cyberpanel');
|
||||
|
||||
try
|
||||
{
|
||||
$sEmail = mysqli_real_escape_string($db, $oAccount->Email());
|
||||
$sEmailUser = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail));
|
||||
$sEmailDomain = mysqli_real_escape_string($db, \MailSo\Base\Utils::GetDomainFromEmail($sEmail));
|
||||
|
||||
$password_check_query = "SELECT * FROM e_users WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
$result = mysqli_query($db, $password_check_query);
|
||||
$password_check = mysqli_fetch_assoc($result);
|
||||
|
||||
if (password_verify($sPrevPassword, substr($password_check['password'], 7))) {
|
||||
$hashed_password = mysqli_real_escape_string($db, '{CRYPT}'.password_hash($sNewPassword, PASSWORD_BCRYPT, ['cost' => 12,]));
|
||||
$password_update_query = "UPDATE e_users SET password = '$hashed_password' WHERE emailOwner_id = '$sEmailDomain' AND email = '$sEmail'";
|
||||
mysqli_query($db, $password_update_query);
|
||||
$bResult = true;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Success! The password was changed.');
|
||||
}
|
||||
} else {
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Something went wrong. Either the current password is incorrect or the new password does not meet the criteria.');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2019 David Forbush
|
||||
|
||||
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.
|
|
@ -1 +0,0 @@
|
|||
This plugin allows you to change passwords of email accounts managed by CyberPanel web panel software
|
|
@ -1,10 +0,0 @@
|
|||
RainLoop CyberPanel Password Changing Plugin
|
||||
============================================
|
||||
|
||||
This plugin adds password changing capability to RainLoop webmail for servers running CyberPanel web panel software.
|
||||
|
||||
##### Installation is simple:
|
||||
|
||||
1. Place the change-password-cyberpanel folder in the plugins directory (e.g. _RainLoopDir_/data/data_xxxxx/_default/plugins/*).
|
||||
2. In RainLoop administration panel, go to Plugins and activate change-password-cyberpanel.
|
||||
3. Enter CyberPanel's SQL user details on the plugin configuration screen.
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,44 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordCyberPanelPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
include_once __DIR__.'/ChangePasswordCyberPanel.php';
|
||||
$oProvider = new ChangePasswordCyberPanel();
|
||||
$oProvider
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
->SetmHost($this->Config()->Get('plugin', 'mHost', ''))
|
||||
->SetmUser($this->Config()->Get('plugin', 'mUser', ''))
|
||||
->SetmPass($this->Config()->Get('plugin', 'mPass', ''))
|
||||
;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('mHost')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mUser')->SetLabel('MySQL User'),
|
||||
\RainLoop\Plugins\Property::NewInstance('mPass')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,47 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordExampleDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \ChangePasswordExampleDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
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)
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
// TODO
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,41 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordExamplePlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordExampleDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordExampleDriver();
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,188 +0,0 @@
|
|||
<?php
|
||||
|
||||
class CpanelChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPost = 2087;
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
*/
|
||||
private $bSsl = true;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
* @param int $iPost
|
||||
* @param bool $bSsl
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \CpanelChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sHost, $iPost, $bSsl, $sUser, $sPassword)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
$this->iPost = $iPost;
|
||||
$this->bSsl = !!$bSsl;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \CpanelChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \CpanelChangePasswordDriver
|
||||
*/
|
||||
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('Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
if (!\class_exists('xmlapi'))
|
||||
{
|
||||
include_once __DIR__.'/xmlapi.php';
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
if (!empty($this->sHost) && 0 < $this->iPost &&
|
||||
0 < \strlen($this->sUser) && 0 < \strlen($this->sPassword) &&
|
||||
$oAccount && \class_exists('xmlapi'))
|
||||
{
|
||||
$sEmail = $oAccount->Email();
|
||||
$sEmailUser = \MailSo\Base\Utils::GetAccountNameFromEmail($sEmail);
|
||||
$sEmailDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
|
||||
|
||||
$sHost = $this->sHost;
|
||||
$sHost = \str_replace('{user:domain}', $sEmailDomain, $sHost);
|
||||
|
||||
$sUser = $this->sUser;
|
||||
$sUser = \str_replace('{user:email}', $sEmail, $sUser);
|
||||
$sUser = \str_replace('{user:login}', $sEmailUser, $sUser);
|
||||
|
||||
$sPassword = $this->sPassword;
|
||||
$sPassword = \str_replace('{user:password}', $oAccount->Password(), $sPassword);
|
||||
|
||||
try
|
||||
{
|
||||
$oXmlApi = new \xmlapi($sHost);
|
||||
$oXmlApi->set_port($this->iPost);
|
||||
$oXmlApi->set_protocol($this->bSsl ? 'https' : 'http');
|
||||
$oXmlApi->set_debug(false);
|
||||
$oXmlApi->set_output('json');
|
||||
// $oXmlApi->set_http_client('fopen');
|
||||
$oXmlApi->set_http_client('curl');
|
||||
$oXmlApi->password_auth($sUser, $sPassword);
|
||||
|
||||
$aArgs = array(
|
||||
'email' => $sEmailUser,
|
||||
'domain' => $sEmailDomain,
|
||||
'password' => $sNewPassword
|
||||
);
|
||||
|
||||
$sResult = $oXmlApi->api2_query($sUser, 'Email', 'passwdpop', $aArgs);
|
||||
if ($sResult)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('CPANEL: '.$sResult, \MailSo\Log\Enumerations\Type::INFO);
|
||||
}
|
||||
|
||||
$aResult = @\json_decode($sResult, true);
|
||||
$bResult = isset($aResult['cpanelresult']['data'][0]['result']) &&
|
||||
!!$aResult['cpanelresult']['data'][0]['result'];
|
||||
}
|
||||
|
||||
if (!$bResult && $this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('CPANEL: '.$sResult, \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('CPANEL: Incorrent configuration data', \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
1.3
|
|
@ -1,65 +0,0 @@
|
|||
<?php
|
||||
|
||||
class CpanelChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sHost = \trim($this->Config()->Get('plugin', 'host', ''));
|
||||
$iPost = (int) $this->Config()->Get('plugin', 'port', 2087);
|
||||
$sUser = (string) $this->Config()->Get('plugin', 'user', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
$bSsl = (bool) $this->Config()->Get('plugin', 'ssl', false);
|
||||
|
||||
if (!empty($sHost) && 0 < $iPost && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/CpanelChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new CpanelChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sHost, $iPost, $bSsl, $sUser, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('cPanel Host')
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('cPanel Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(2087),
|
||||
\RainLoop\Plugins\Property::NewInstance('ssl')->SetLabel('Use SSL')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetDefaultValue(false),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('cPanel User')
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('cPanel 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('*')
|
||||
);
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load diff
|
@ -1,152 +0,0 @@
|
|||
<?php
|
||||
|
||||
class DirectAdminChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $iPort = 2222;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return \DirectAdminChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sHost, $iPort)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
$this->iPort = $iPort;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \DirectAdminChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \DirectAdminChangePasswordDriver
|
||||
*/
|
||||
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('DirectAdmin: Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
if (!empty($this->sHost) && 0 < $this->iPort && $oAccount)
|
||||
{
|
||||
$sEmail = \trim(\strtolower($oAccount->Email()));
|
||||
|
||||
$sHost = \trim($this->sHost);
|
||||
$sHost = \str_replace('{user:host-imap}', $oAccount->Domain()->IncHost(), $sHost);
|
||||
$sHost = \str_replace('{user:host-smtp}', $oAccount->Domain()->OutHost(), $sHost);
|
||||
$sHost = \str_replace('{user:domain}', \MailSo\Base\Utils::GetDomainFromEmail($sEmail), $sHost);
|
||||
$sHost = \rtrim($this->sHost, '/\\');
|
||||
|
||||
if (!\preg_match('/^http[s]?:\/\//i', $sHost))
|
||||
{
|
||||
$sHost = 'http://'.$sHost;
|
||||
}
|
||||
|
||||
$sUrl = $sHost.':'.$this->iPort.'/CMD_CHANGE_EMAIL_PASSWORD';
|
||||
|
||||
$iCode = 0;
|
||||
$oHttp = \MailSo\Base\Http::SingletonInstance();
|
||||
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('DirectAdmin[Api Request]:'.$sUrl);
|
||||
}
|
||||
|
||||
$mResult = $oHttp->SendPostRequest($sUrl,
|
||||
array(
|
||||
'email' => $sEmail,
|
||||
'oldpassword' => $sPrevPassword,
|
||||
'password1' => $sNewPassword,
|
||||
'password2' => $sNewPassword,
|
||||
'api' => '1'
|
||||
), '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('DirectAdmin[Error]: Response: '.$mResult);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('DirectAdmin[Error]: Empty Response: Code:'.$iCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (DirectAdmin).
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,55 +0,0 @@
|
|||
<?php
|
||||
|
||||
class DirectadminChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sHost = \trim($this->Config()->Get('plugin', 'direct_admin_host', ''));
|
||||
$iPort = (int) $this->Config()->Get('plugin', 'direct_admin_port', 2222);
|
||||
|
||||
if (!empty($sHost) && 0 < $iPort)
|
||||
{
|
||||
include_once __DIR__.'/DirectAdminChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new DirectAdminChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sHost, $iPort);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('direct_admin_host')->SetLabel('DirectAdmin Host')
|
||||
->SetDefaultValue('')
|
||||
->SetDescription('Allowed patterns: {user:host-imap}, {user:host-smtp}, {user:domain}'),
|
||||
\RainLoop\Plugins\Property::NewInstance('direct_admin_port')->SetLabel('DirectAdmin Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(2222),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,293 +0,0 @@
|
|||
<?php
|
||||
|
||||
class FroxlorChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDsn = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sDsn
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \FroxlorChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sDsn, $sUser, $sPassword)
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \FroxlorChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \FroxlorChangePasswordDriver
|
||||
*/
|
||||
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('Froxlor: 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_enc, id FROM mail_users WHERE username = ? LIMIT 1');
|
||||
if ($oStmt->execute(array($oAccount->IncLogin())))
|
||||
{
|
||||
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password_enc'], $aFetchResult[0]['id']))
|
||||
{
|
||||
$sDbPassword = \stripslashes($aFetchResult[0]['password_enc']);
|
||||
|
||||
if ( $this->validatePasswordLogin( $sDbPassword, $sPrevPassword ) ) {
|
||||
$sEncNewPassword = $this->cryptPassword($sNewPassword, 3);
|
||||
$oStmt = $oPdo->prepare('UPDATE mail_users SET password_enc = ?,password = ? WHERE id = ?');
|
||||
$bResult = (bool) $oStmt->execute(
|
||||
array($sEncNewPassword, $sNewPassword, $aFetchResult[0]['id']));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @return string
|
||||
*/
|
||||
private function cryptPassword($sPassword, $type = 3)
|
||||
{
|
||||
return $this->makeCryptPassword($sPassword,$type);
|
||||
}
|
||||
|
||||
/**
|
||||
* This file is part of the Froxlor project.
|
||||
* Copyright (c) 2010 the Froxlor Team (see authors).
|
||||
*
|
||||
* For the full copyright and license information, please view the COPYING
|
||||
* file that was distributed with this source code. You can also view the
|
||||
* COPYING file online at http://files.froxlor.org/misc/COPYING.txt
|
||||
*
|
||||
* @copyright (c) the authors
|
||||
* @author Michal Wojcik <m.wojcik@sonet3.pl>
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
* @license GPLv2 http://files.froxlor.org/misc/COPYING.txt
|
||||
* @package Functions
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Make crypted password from clear text password
|
||||
*
|
||||
* @author Michal Wojcik <m.wojcik@sonet3.pl>
|
||||
* @author Michael Kaufmann <mkaufmann@nutime.de>
|
||||
* @author Froxlor team <team@froxlor.org> (2010-)
|
||||
*
|
||||
* 0 - default crypt (depenend on system configuration)
|
||||
* 1 - MD5 $1$
|
||||
* 2 - BLOWFISH $2a$ | $2y$07$ (on php 5.3.7+)
|
||||
* 3 - SHA-256 $5$ (default)
|
||||
* 4 - SHA-512 $6$
|
||||
*
|
||||
* @param string $password Password to be crypted
|
||||
*
|
||||
* @return string encrypted password
|
||||
*/
|
||||
private function makeCryptPassword ($password,$type = 3) {
|
||||
switch ($type) {
|
||||
case 0:
|
||||
$cryptPassword = \crypt($password);
|
||||
break;
|
||||
case 1:
|
||||
$cryptPassword = \crypt($password, '$1$' . $this->generatePassword(true). $this->generatePassword(true));
|
||||
break;
|
||||
case 2:
|
||||
if (\version_compare(\phpversion(), '5.3.7', '<')) {
|
||||
$cryptPassword = \crypt($password, '$2a$' . $this->generatePassword(true). $this->generatePassword(true));
|
||||
} else {
|
||||
// Blowfish hashing with a salt as follows: "$2a$", "$2x$" or "$2y$",
|
||||
// a two digit cost parameter, "$", and 22 characters from the alphabet "./0-9A-Za-z"
|
||||
$cryptPassword = \crypt(
|
||||
$password,
|
||||
'$2y$07$' . \substr($this->generatePassword(true).$this->generatePassword(true).$this->generatePassword(true), 0, 22)
|
||||
);
|
||||
}
|
||||
break;
|
||||
case 3:
|
||||
$cryptPassword = \crypt($password, '$5$' . $this->generatePassword(true). $this->generatePassword(true));
|
||||
break;
|
||||
case 4:
|
||||
$cryptPassword = \crypt($password, '$6$' . $this->generatePassword(true). $this->generatePassword(true));
|
||||
break;
|
||||
default:
|
||||
$cryptPassword = \crypt($password);
|
||||
break;
|
||||
}
|
||||
|
||||
return $cryptPassword;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a random password
|
||||
*
|
||||
* @param boolean $isSalt
|
||||
* optional, create a hash for a salt used in makeCryptPassword because crypt() does not like some special characters in its salts, default is false
|
||||
*/
|
||||
private function generatePassword($isSalt = false)
|
||||
{
|
||||
$alpha_lower = 'abcdefghijklmnopqrstuvwxyz';
|
||||
$alpha_upper = \strtoupper($alpha_lower);
|
||||
$numeric = '0123456789';
|
||||
$special = '!?<>§$%&+#=';
|
||||
$length = 10;
|
||||
|
||||
$pw = $this->special_shuffle($alpha_lower);
|
||||
$n = \floor(($length) / 4);
|
||||
$pw .= \mb_substr($this->special_shuffle($alpha_upper), 0, $n);
|
||||
$pw .= \mb_substr($this->special_shuffle($numeric), 0, $n);
|
||||
$pw = \mb_substr($pw, - $length);
|
||||
return $this->special_shuffle($pw);
|
||||
}
|
||||
|
||||
/**
|
||||
* multibyte-character safe shuffle function
|
||||
*
|
||||
* @param string $str
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function special_shuffle($str = null)
|
||||
{
|
||||
$len = \mb_strlen($str);
|
||||
$sploded = array();
|
||||
while ($len -- > 0) {
|
||||
$sploded[] = \mb_substr($str, $len, 1);
|
||||
}
|
||||
\shuffle($sploded);
|
||||
return \join('', $sploded);
|
||||
}
|
||||
|
||||
/**
|
||||
* Function validatePasswordLogin
|
||||
*
|
||||
* compare user password-hash with given user-password
|
||||
* and check if they are the same
|
||||
* additionally it updates the hash if the system settings changed
|
||||
* or if the very old md5() sum is used
|
||||
*
|
||||
* @param array $userinfo user-data from table
|
||||
* @param string $password the password to validate
|
||||
* @param string $table either panel_customers or panel_admins
|
||||
* @param string $uid user-id-field in $table
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private function validatePasswordLogin($pwd_hash, $password = null) {
|
||||
|
||||
$systype = 3; // SHA256
|
||||
$update_hash = false;
|
||||
// check for good'ole md5
|
||||
if (\strlen($pwd_hash) == 32 && \ctype_xdigit($pwd_hash)) {
|
||||
$pwd_check = \md5($password);
|
||||
$update_hash = true;
|
||||
} else {
|
||||
// cut out the salt from the hash
|
||||
$pwd_salt = \str_replace(\substr(\strrchr($pwd_hash, "$"), 1), "", $pwd_hash);
|
||||
// create same hash to compare
|
||||
$pwd_check = \crypt($password, $pwd_salt);
|
||||
// check whether the hash needs to be updated
|
||||
$hash_type_chk = \substr($pwd_hash, 0, 3);
|
||||
if (($systype == 1 && $hash_type_chk != '$1$') || // MD5
|
||||
($systype == 2 && $hash_type_chk != '$2$') || // BLOWFISH
|
||||
($systype == 3 && $hash_type_chk != '$5$') || // SHA256
|
||||
($systype == 4 && $hash_type_chk != '$6$') // SHA512
|
||||
) {
|
||||
$update_hash = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $pwd_check;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Bob Kromonos Achten
|
||||
|
||||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (Froxlor).
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
class FroxlorchangePasswordPlugin 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', '');
|
||||
|
||||
if (!empty($sDsn) && 0 < \strlen($sUser) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/FroxlorChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new FroxlorChangePasswordDriver();
|
||||
$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('Froxlor PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=froxlor'),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Embed Google Analytics (Universal Analytics) code into your webmail installation pages.
|
|
@ -1 +0,0 @@
|
|||
1.5
|
|
@ -1,49 +0,0 @@
|
|||
<?php
|
||||
|
||||
class GoogleAnalyticsPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
if ('' !== $this->Config()->Get('plugin', 'account', ''))
|
||||
{
|
||||
$this->addJs('js/include.js');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
$oAccount = \RainLoop\Plugins\Property::NewInstance('account')->SetLabel('Account')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue('')
|
||||
;
|
||||
|
||||
if (\method_exists($oAccount, 'SetPlaceholder'))
|
||||
{
|
||||
$oAccount->SetPlaceholder('UA-XXXXXXXX-X');
|
||||
}
|
||||
|
||||
return array($oAccount,
|
||||
\RainLoop\Plugins\Property::NewInstance('domain_name')->SetLabel('Domain Name')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('universal_analytics')->SetLabel('Use Universal Analytics')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('track_pageview')->SetLabel('Track Pageview')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(true),
|
||||
\RainLoop\Plugins\Property::NewInstance('send_events')->SetLabel('Send Events')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::BOOL)
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(false)
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
|
||||
$(function () {
|
||||
|
||||
if (!window.rl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var
|
||||
sAccount = window.rl.pluginSettingsGet('google-analytics', 'account'),
|
||||
sDomain = window.rl.pluginSettingsGet('google-analytics', 'domain_name'),
|
||||
bUniversalAnalytics = !!window.rl.pluginSettingsGet('google-analytics', 'universal_analytics'),
|
||||
bTrackPageview = !!window.rl.pluginSettingsGet('google-analytics', 'track_pageview'),
|
||||
bSendEvent = !!window.rl.pluginSettingsGet('google-analytics', 'send_events'),
|
||||
fSendEvent = null
|
||||
;
|
||||
|
||||
if (sAccount && '' !== sAccount)
|
||||
{
|
||||
if (bUniversalAnalytics)
|
||||
{
|
||||
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
|
||||
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
|
||||
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
|
||||
})(window,document,'script','//www.google-analytics.com/analytics.js','ga');
|
||||
|
||||
if (window.ga)
|
||||
{
|
||||
if (sDomain)
|
||||
{
|
||||
window.ga('create', sAccount, sDomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
window.ga('create', sAccount);
|
||||
}
|
||||
|
||||
if (bTrackPageview)
|
||||
{
|
||||
window.ga('send', 'pageview');
|
||||
window.setInterval(function () {
|
||||
window.ga('send', 'pageview');
|
||||
}, 1000 * 60 * 2);
|
||||
}
|
||||
|
||||
if (bSendEvent)
|
||||
{
|
||||
fSendEvent = function(sCategory, sAction, sLabel) {
|
||||
window.ga('send', 'event', sCategory, sAction, sLabel);
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
window._gaq = window._gaq || [];
|
||||
window._gaq.push(['_setAccount', sAccount]);
|
||||
|
||||
if (sDomain)
|
||||
{
|
||||
window._gaq.push(['_setDomainName', sDomain]);
|
||||
}
|
||||
|
||||
if (bTrackPageview)
|
||||
{
|
||||
window._gaq.push(['_trackPageview']);
|
||||
window.setInterval(function () {
|
||||
window._gaq.push(['_trackPageview']);
|
||||
}, 1000 * 60 * 2);
|
||||
}
|
||||
|
||||
if (bSendEvent)
|
||||
{
|
||||
fSendEvent = function(sCategory, sAction, sLabel) {
|
||||
window._gaq.push(['_trackEvent', sCategory, sAction, sLabel]);
|
||||
};
|
||||
}
|
||||
|
||||
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
|
||||
ga.src = ('https:' === document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
|
||||
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
|
||||
}
|
||||
|
||||
if (fSendEvent)
|
||||
{
|
||||
window.rl.addHook('ajax-default-response', function (sAction, oData, sType) {
|
||||
switch (sAction)
|
||||
{
|
||||
case 'Login':
|
||||
case 'SendMessage':
|
||||
case 'MessageMove':
|
||||
case 'MessageDelete':
|
||||
fSendEvent('RainLoop', sAction,
|
||||
'success' === sType && oData && oData['Result'] ? 'true' : 'false');
|
||||
break;
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
|
@ -1,138 +0,0 @@
|
|||
<?php
|
||||
|
||||
class HmailserverChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sLogin = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sLogin
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \HmailserverChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sLogin, $sPassword)
|
||||
{
|
||||
$this->sLogin = $sLogin;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \HmailserverChangePasswordDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \HmailserverChangePasswordDriver
|
||||
*/
|
||||
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 $oHmailAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oHmailAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Try to change password for '.$oHmailAccount->Email());
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
|
||||
try
|
||||
{
|
||||
$oHmailApp = new COM("hMailServer.Application");
|
||||
$oHmailApp->Connect();
|
||||
|
||||
if ($oHmailApp->Authenticate($this->sLogin, $this->sPassword))
|
||||
{
|
||||
$sEmail = $oHmailAccount->Email();
|
||||
$sDomain = \MailSo\Base\Utils::GetDomainFromEmail($sEmail);
|
||||
|
||||
$oHmailDomain = $oHmailApp->Domains->ItemByName($sDomain);
|
||||
if ($oHmailDomain)
|
||||
{
|
||||
$oHmailAccount = $oHmailDomain->Accounts->ItemByAddress($sEmail);
|
||||
if ($oHmailAccount)
|
||||
{
|
||||
$oHmailAccount->Password = $sNewPassword;
|
||||
$oHmailAccount->Save();
|
||||
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oLogger->Write('HMAILSERVER: Unknown account ('.$sEmail.')', \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oLogger->Write('HMAILSERVER: Unknown domain ('.$sDomain.')', \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$this->oLogger->Write('HMAILSERVER: Auth error', \MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2014 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.
|
|
@ -1 +0,0 @@
|
|||
1.2
|
|
@ -1,67 +0,0 @@
|
|||
<?php
|
||||
|
||||
class HmailserverChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!class_exists('COM'))
|
||||
{
|
||||
return 'The PHP extension COM must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sLogin = (string) $this->Config()->Get('plugin', 'login', '');
|
||||
$sPassword = (string) $this->Config()->Get('plugin', 'password', '');
|
||||
|
||||
if (0 < \strlen($sLogin) && 0 < \strlen($sPassword))
|
||||
{
|
||||
include_once __DIR__.'/HmailserverChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new HmailserverChangePasswordDriver();
|
||||
$oProvider->SetLogger($this->Manager()->Actions()->Logger());
|
||||
$oProvider->SetConfig($sLogin, $sPassword);
|
||||
$oProvider->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))));
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('login')->SetLabel('HmailServer Admin Login')
|
||||
->SetDefaultValue('Administrator'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('HmailServer Admin 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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,151 +0,0 @@
|
|||
<?php
|
||||
|
||||
class IspConfigChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDsn = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sDsn
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sDsn, $sUser, $sPassword)
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
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;
|
||||
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 = ? 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 = ?');
|
||||
$bResult = (bool) $oStmt->execute(
|
||||
array($this->cryptPassword($sNewPassword), $aFetchResult[0]['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.'$');
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (ISPConfig).
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,76 +0,0 @@
|
|||
<?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 extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension 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__.'/IspConfigChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new IspConfigChangePasswordDriver();
|
||||
$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('ISPConfig 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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,276 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordISPmailDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPort = 3306;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDatabase = 'mailserver';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sTable = 'virtual_users';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUsercol = 'email';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPasscol = 'password';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = 'mailuser';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEncrypt = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetHost($sHost)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetPort($iPort)
|
||||
{
|
||||
$this->iPort = (int) $iPort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDatabase
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetDatabase($sDatabase)
|
||||
{
|
||||
$this->sDatabase = $sDatabase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTable
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetTable($sTable)
|
||||
{
|
||||
$this->sTable = $sTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUsercol
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetUserColumn($sUsercol)
|
||||
{
|
||||
$this->sUsercol = $sUsercol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPasscol
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetPasswordColumn($sPasscol)
|
||||
{
|
||||
$this->sPasscol = $sPasscol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUser
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetUser($sUser)
|
||||
{
|
||||
$this->sUser = $sUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
$this->sPassword = $sPassword;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncrypt
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetEncrypt($sEncrypt)
|
||||
{
|
||||
$this->sEncrypt = $sEncrypt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordISPmailDriver
|
||||
*/
|
||||
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('ISPmail: Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
unset($sPrevPassword);
|
||||
|
||||
$bResult = false;
|
||||
|
||||
if (0 < \strlen($sNewPassword))
|
||||
{
|
||||
try
|
||||
{
|
||||
$sDsn = 'mysql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase;
|
||||
|
||||
$oPdo = new \PDO($sDsn, $this->sUser, $this->sPassword);
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$sUpdatePassword = $this->cryptPassword($sNewPassword, $oPdo);
|
||||
if (0 < \strlen($sUpdatePassword))
|
||||
{
|
||||
$oStmt = $oPdo->prepare("UPDATE {$this->sTable} SET {$this->sPasscol} = ? WHERE {$this->sUsercol} = ?");
|
||||
$bResult = (bool) $oStmt->execute(array($sUpdatePassword, $oAccount->Email()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('ISPmail: Encrypted password is empty',
|
||||
\MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
$oPdo = null;
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @param \PDO $oPdo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function cryptPassword($sPassword, $oPdo)
|
||||
{
|
||||
$sResult = '';
|
||||
$sSalt = substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, 16);
|
||||
switch (strtolower($this->sEncrypt))
|
||||
{
|
||||
default:
|
||||
case 'plain-md5':
|
||||
$sResult = '{PLAIN-MD5}' . md5($sPassword);
|
||||
break;
|
||||
|
||||
case 'sha256-crypt':
|
||||
$sResult = '{SHA256-CRYPT}' . crypt($sPassword,'$5$'.$sSalt);
|
||||
break;
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Julien Lutran (https://github.com/jlutran)
|
||||
|
||||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (ISPmail).
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,95 +0,0 @@
|
|||
<?php
|
||||
|
||||
class IspmailChangePasswordPlugin 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 extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension 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':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordISPmailDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordISPmailDriver();
|
||||
|
||||
$oProvider
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('MySQL Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('MySQL Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('MySQL Database')
|
||||
->SetDefaultValue('mailserver'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('MySQL table')
|
||||
->SetDefaultValue('virtual_users'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('MySQL username column')
|
||||
->SetDefaultValue('email'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('MySQL password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('MySQL User')
|
||||
->SetDefaultValue('mailuser'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('MySQL Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('PLAIN-MD5', 'SHA256-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,242 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordLdapDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHostName = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iHostPort = 389;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUserDnFormat = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPasswordField = 'userPassword';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPasswordEncType = 'SHA';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @param string $sHostName
|
||||
* @param int $iHostPort
|
||||
* @param string $sUserDnFormat
|
||||
* @param string $sPasswordField
|
||||
* @param string $sPasswordEncType
|
||||
*
|
||||
* @return \ChangePasswordLdapDriver
|
||||
*/
|
||||
public function SetConfig($sHostName, $iHostPort, $sUserDnFormat, $sPasswordField, $sPasswordEncType)
|
||||
{
|
||||
$this->sHostName = $sHostName;
|
||||
$this->iHostPort = $iHostPort;
|
||||
$this->sUserDnFormat = $sUserDnFormat;
|
||||
$this->sPasswordField = $sPasswordField;
|
||||
$this->sPasswordEncType = $sPasswordEncType;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \ChangePasswordLdapDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordLdapDriver
|
||||
*/
|
||||
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\Model\Account $oAccount
|
||||
* @param string $sPrevPassword
|
||||
* @param string $sNewPassword
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function ChangePassword(\RainLoop\Account $oAccount, $sPrevPassword, $sNewPassword)
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
try
|
||||
{
|
||||
$sDomain = \MailSo\Base\Utils::GetDomainFromEmail($oAccount->Email());
|
||||
$sUserDn = \strtr($this->sUserDnFormat, array(
|
||||
'{domain}' => $sDomain,
|
||||
'{domain:dc}' => 'dc='.\strtr($sDomain, array('.' => ',dc=')),
|
||||
'{email}' => $oAccount->Email(),
|
||||
'{email:user}' => \MailSo\Base\Utils::GetAccountNameFromEmail($oAccount->Email()),
|
||||
'{email:domain}' => $sDomain,
|
||||
'{login}' => $oAccount->Login(),
|
||||
'{imap:login}' => $oAccount->Login(),
|
||||
'{imap:host}' => $oAccount->DomainIncHost(),
|
||||
'{imap:port}' => $oAccount->DomainIncPort(),
|
||||
'{gecos}' => function_exists('posix_getpwnam') ? posix_getpwnam($oAccount->Login()) : ''
|
||||
));
|
||||
|
||||
$oCon = @\ldap_connect($this->sHostName, $this->iHostPort);
|
||||
if ($oCon)
|
||||
{
|
||||
if (!@\ldap_set_option($oCon, LDAP_OPT_PROTOCOL_VERSION, 3))
|
||||
{
|
||||
$this->oLogger->Write(
|
||||
'Failed to set LDAP Protocol version to 3, TLS not supported.',
|
||||
\MailSo\Log\Enumerations\Type::WARNING,
|
||||
'LDAP'
|
||||
);
|
||||
}
|
||||
else if (@!ldap_start_tls($oCon))
|
||||
{
|
||||
$this->oLogger->Write("ldap_start_tls failed: ".$oCon, \MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
|
||||
}
|
||||
|
||||
if (!@\ldap_bind($oCon, $sUserDn, $sPrevPassword))
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$sError = $oCon ? @\ldap_error($oCon) : '';
|
||||
$iErrno = $oCon ? @\ldap_errno($oCon) : 0;
|
||||
|
||||
$this->oLogger->Write('ldap_bind error: '.$sError.' ('.$iErrno.')',
|
||||
\MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
$sSshaSalt = '';
|
||||
$sShaPrefix = '{SHA}';
|
||||
$sEncodedNewPassword = $sNewPassword;
|
||||
switch (\strtolower($this->sPasswordEncType))
|
||||
{
|
||||
case 'ssha':
|
||||
$sSshaSalt = $this->getSalt(4);
|
||||
$sShaPrefix = '{SSHA}';
|
||||
case 'sha':
|
||||
switch (true)
|
||||
{
|
||||
default:
|
||||
case \function_exists('sha1'):
|
||||
$sEncodedNewPassword = $sShaPrefix.\base64_encode(\sha1($sNewPassword.$sSshaSalt, true).$sSshaSalt);
|
||||
break;
|
||||
case \function_exists('hash'):
|
||||
$sEncodedNewPassword = $sShaPrefix.\base64_encode(\hash('sha1', $sNewPassword, true).$sSshaSalt);
|
||||
break;
|
||||
case \function_exists('mhash') && defined('MHASH_SHA1'):
|
||||
$sEncodedNewPassword = $sShaPrefix.\base64_encode(\mhash(MHASH_SHA1, $sNewPassword).$sSshaSalt);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 'md5':
|
||||
$sEncodedNewPassword = '{MD5}'.\base64_encode(\pack('H*', \md5($sNewPassword)));
|
||||
break;
|
||||
case 'crypt':
|
||||
$sEncodedNewPassword = '{CRYPT}'.\crypt($sNewPassword, $this->getSalt(2));
|
||||
break;
|
||||
}
|
||||
|
||||
$aEntry = array();
|
||||
$aEntry[$this->sPasswordField] = (string) $sEncodedNewPassword;
|
||||
|
||||
if (!!@\ldap_modify($oCon, $sUserDn, $aEntry))
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$sError = $oCon ? @\ldap_error($oCon) : '';
|
||||
$iErrno = $oCon ? @\ldap_errno($oCon) : 0;
|
||||
|
||||
$this->oLogger->Write('ldap_modify error: '.$sError.' ('.$iErrno.')',
|
||||
\MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException,
|
||||
\MailSo\Log\Enumerations\Type::WARNING, 'LDAP');
|
||||
}
|
||||
|
||||
$bResult = false;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iLength
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getSalt($iLength)
|
||||
{
|
||||
$sChars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||||
$iCharsLength = \strlen($sChars);
|
||||
|
||||
$sResult = '';
|
||||
while (\strlen($sResult) < $iLength)
|
||||
{
|
||||
$sResult .= \substr($sChars, \rand() % $iCharsLength, 1);
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (LDAP Password).
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,79 +0,0 @@
|
|||
<?php
|
||||
|
||||
class LdapChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function Supported()
|
||||
{
|
||||
if (!\function_exists('ldap_connect'))
|
||||
{
|
||||
return 'The LDAP PHP extension must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
$sHostName = \trim($this->Config()->Get('plugin', 'hostname', ''));
|
||||
$iHostPort = (int) $this->Config()->Get('plugin', 'port', 389);
|
||||
$sUserDnFormat = \trim($this->Config()->Get('plugin', 'user_dn_format', ''));
|
||||
$sPasswordField = \trim($this->Config()->Get('plugin', 'password_field', ''));
|
||||
$sPasswordEncType = \trim($this->Config()->Get('plugin', 'password_enc_type', ''));
|
||||
|
||||
if (!empty($sHostName) && 0 < $iHostPort && !empty($sUserDnFormat) && !empty($sPasswordField) && !empty($sPasswordEncType))
|
||||
{
|
||||
include_once __DIR__.'/ChangePasswordLdapDriver.php';
|
||||
|
||||
$oProvider = new \ChangePasswordLdapDriver();
|
||||
|
||||
$oProvider
|
||||
->SetConfig($sHostName, $iHostPort, $sUserDnFormat, $sPasswordField, $sPasswordEncType)
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('hostname')->SetLabel('LDAP hostname')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('LDAP port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(389),
|
||||
\RainLoop\Plugins\Property::NewInstance('user_dn_format')->SetLabel('User DN format')
|
||||
->SetDescription('LDAP user dn format. Supported tokens: {email}, {email:user}, {email:domain}, {login}, {domain}, {domain:dc}, {imap:login}, {imap:host}, {imap:port}, {gecos}')
|
||||
->SetDefaultValue('uid={imap:login},ou=Users,{domain:dc}'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password_field')->SetLabel('Password field')
|
||||
->SetDefaultValue('userPassword'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password_enc_type')->SetLabel('Encryption type')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('SHA', 'SSHA', 'MD5', 'Crypt', 'Clear')),
|
||||
\RainLoop\Plugins\Property::NewInstance('allowed_emails')->SetLabel('Allowed emails')
|
||||
->SetDescription('Allowed emails, space as delimiter, wildcard supported. Example: user1@domain1.net user2@domain1.net *@domain2.net')
|
||||
->SetDefaultValue('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2016 Caleb Blankemeyer (https://github.com/zikeji)
|
||||
|
||||
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.
|
|
@ -1,162 +0,0 @@
|
|||
<?php
|
||||
|
||||
class MailcowChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDsn = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sDsn
|
||||
* @param string $sUser
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \IspConfigChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sDsn, $sUser, $sPassword)
|
||||
{
|
||||
$this->sDsn = $sDsn;
|
||||
$this->sUser = $sUser;
|
||||
$this->sPassword = $sPassword;
|
||||
|
||||
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\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('Mailcow: 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, username FROM mailbox WHERE username = ? LIMIT 1');
|
||||
if ($oStmt->execute(array($oAccount->IncLogin())))
|
||||
{
|
||||
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetchResult) && isset($aFetchResult[0]['password'], $aFetchResult[0]['username']))
|
||||
{
|
||||
$sDbPassword = $aFetchResult[0]['password'];
|
||||
if (\substr($sDbPassword, 0, 14) === '{SHA512-CRYPT}') {
|
||||
$sDbSalt = \substr($sDbPassword, 17, 16);
|
||||
} else {
|
||||
$sDbSalt = \substr($sDbPassword, 3, 16);
|
||||
}
|
||||
|
||||
if ('{SHA512-CRYPT}'.\crypt($sPrevPassword, '$6$'.$sDbSalt) === $sDbPassword)
|
||||
{
|
||||
$oStmt = $oPdo->prepare('UPDATE mailbox SET password = ? WHERE username = ?');
|
||||
if ($oStmt->execute(array($this->cryptPassword($sNewPassword), $aFetchResult[0]['username']))) {
|
||||
$oStmt = $oPdo ->prepare('UPDATE users SET digesta1=MD5(CONCAT(?, ":SabreDAV:", ?)) WHERE username=?');
|
||||
if ($oStmt->execute(array($aFetchResult[0]['username'],$sNewPassword,$aFetchResult[0]['username']))) {
|
||||
//the MailCow & SabreDav have been updated, now update the doveadm password
|
||||
exec("/usr/bin/doveadm pw -s SHA512-CRYPT -p $sNewPassword", $hash, $return);
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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 < 16; $iIndex++)
|
||||
{
|
||||
$sSalt .= $sBase64[\rand(0, 63)];
|
||||
}
|
||||
|
||||
$crypted = \crypt($sPassword, '$6$'.$sSalt);
|
||||
return '{SHA512-CRYPT}'.$crypted;
|
||||
}
|
||||
}
|
|
@ -1,5 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password with the email frontend [mailcow](https://github.com/andryyy/mailcow).
|
||||
|
||||
Changes the SQL password (for the default ui for users), the dovecot password, and the SabreDAV password. Essentially does what their own PHP script does. It also ensures the old password matches the actual old password (something their Roundcube plugin does not do).
|
||||
|
||||
This plugin is a modification of the [ispconfig-change-password](https://github.com/RainLoop/rainloop-webmail/tree/master/plugins/ipsconfig-change-password) plugin.
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,76 +0,0 @@
|
|||
<?php
|
||||
|
||||
class MailcowChangePasswordPlugin 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 extension PDO (mysql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || !in_array('mysql', $aDrivers))
|
||||
{
|
||||
return 'The PHP extension 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__.'/MailcowChangePasswordDriver.php';
|
||||
|
||||
$oProvider = new MailcowChangePasswordDriver();
|
||||
$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('Mailcow PDO dsn')
|
||||
->SetDefaultValue('mysql:host=127.0.0.1;dbname=mailcow'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('DB User')
|
||||
->SetDefaultValue('mailcow'),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2017 Marius Gripsgard <marius@ubports.com>
|
||||
|
||||
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.
|
|
@ -1,157 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Mail-in-a-box Password Change Plugin
|
||||
*
|
||||
* Based on VirtualminChangePasswordDriver
|
||||
*
|
||||
* Author: Marius Gripsgard
|
||||
*/
|
||||
class MailInABoxChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdminUser = '';
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAdminPassword = '';
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
/**
|
||||
* @param string $sHost
|
||||
* @param string $sAdminUser
|
||||
* @param string $sAdminPassword
|
||||
*
|
||||
* @return \MailInABoxChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sHost, $sAdminUser, $sAdminPassword)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (Mail-in-a-Box).
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,54 +0,0 @@
|
|||
<?php
|
||||
/*
|
||||
* Mail-in-a-box Password Change Plugin
|
||||
*
|
||||
* Based on VirtualminChangePassword
|
||||
*
|
||||
* Author: Marius Gripsgard
|
||||
*/
|
||||
class MailInABoxChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Embed Piwik Analytics (Open source web analytics platform) code into your webmail installation pages.
|
|
@ -1 +0,0 @@
|
|||
1.0
|
|
@ -1,36 +0,0 @@
|
|||
<?php
|
||||
|
||||
class PiwikAnalyticsPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
if ('' !== $this->Config()->Get('plugin', 'piwik_url', '') &&
|
||||
'' !== $this->Config()->Get('plugin', 'site_id', ''))
|
||||
{
|
||||
$this->addJs('js/include.js');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
$oUrl = \RainLoop\Plugins\Property::NewInstance('piwik_url')->SetLabel('Piwik URL')
|
||||
->SetAllowedInJs(true);
|
||||
|
||||
$oSiteID = \RainLoop\Plugins\Property::NewInstance('site_id')->SetLabel('Site ID')
|
||||
->SetAllowedInJs(true);
|
||||
|
||||
if (\method_exists($oUrl, 'SetPlaceholder'))
|
||||
{
|
||||
$oUrl->SetPlaceholder('http://');
|
||||
$oSiteID->SetPlaceholder('');
|
||||
}
|
||||
|
||||
return array($oUrl, $oSiteID);
|
||||
}
|
||||
}
|
|
@ -1,37 +0,0 @@
|
|||
|
||||
$(function () {
|
||||
|
||||
if (!window.rl)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var
|
||||
sPiwikURL = '' + window.rl.pluginSettingsGet('piwik-analytics', 'piwik_url'),
|
||||
sSiteID = '' + window.rl.pluginSettingsGet('piwik-analytics', 'site_id')
|
||||
;
|
||||
|
||||
if ('' !== sPiwikURL && '' !== sSiteID)
|
||||
{
|
||||
sPiwikURL = sPiwikURL.replace(/[\\\/\s]+$/, '') + '/';
|
||||
if (!/^https?:/i.test(sPiwikURL))
|
||||
{
|
||||
sPiwikURL = 'http://' + sPiwikURL;
|
||||
}
|
||||
|
||||
window._paq = window._paq || [];
|
||||
(function(window){
|
||||
window._paq.push(['setSiteId', sSiteID]);
|
||||
window._paq.push(['setTrackerUrl', sPiwikURL + 'piwik.php']);
|
||||
window._paq.push(['trackPageView']);
|
||||
window.setInterval(function () {
|
||||
window._paq.push(['trackPageView']);
|
||||
}, 1000 * 60 * 2);
|
||||
var d = window.document, g = d.createElement('script'), s = d.getElementsByTagName('script')[0];
|
||||
g.type = 'text/javascript'; g.defer = true; g.async = true; g.src = sPiwikURL + 'piwik.js';
|
||||
if (s && s.parentNode) {
|
||||
s.parentNode.insertBefore(g, s);
|
||||
}
|
||||
}(window));
|
||||
}
|
||||
});
|
|
@ -1,119 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordPoppassdDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPort = 106;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
*
|
||||
* @return \ChangePasswordPoppassdDriver
|
||||
*/
|
||||
public function SetHost($sHost)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return \ChangePasswordPoppassdDriver
|
||||
*/
|
||||
public function SetPort($iPort)
|
||||
{
|
||||
$this->iPort = (int) $iPort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \ChangePasswordPoppassdDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordPoppassdDriver
|
||||
*/
|
||||
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)
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
try
|
||||
{
|
||||
$oPoppassdClient = \MailSo\Poppassd\PoppassdClient::NewInstance();
|
||||
if ($this->oLogger instanceof \MailSo\Log\Logger)
|
||||
{
|
||||
$oPoppassdClient->SetLogger($this->oLogger);
|
||||
}
|
||||
|
||||
$oPoppassdClient
|
||||
->Connect($this->sHost, $this->iPort)
|
||||
->Login($oAccount->Login(), $oAccount->Password())
|
||||
->NewPass($sNewPassword)
|
||||
->LogoutAndDisconnect()
|
||||
;
|
||||
|
||||
$bResult = true;
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
$bResult = false;
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (POPPASSD).
|
|
@ -1 +0,0 @@
|
|||
1.1
|
|
@ -1,52 +0,0 @@
|
|||
<?php
|
||||
|
||||
class PoppassdChangePasswordPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
public function Init()
|
||||
{
|
||||
$this->addHook('main.fabrica', 'MainFabrica');
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordPoppassdDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordPoppassdDriver();
|
||||
|
||||
$oProvider
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 106))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('POPPASSD Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('POPPASSD Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(106),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,342 +0,0 @@
|
|||
<?php
|
||||
|
||||
class ChangePasswordPostfixAdminDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEngine = 'MySQL';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sHost = '127.0.0.1';
|
||||
|
||||
/**
|
||||
* @var int
|
||||
*/
|
||||
private $iPort = 3306;
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sDatabase = 'postfixadmin';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sTable = 'mailbox';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUsercol = 'username';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPasscol = 'password';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUser = 'postfixadmin';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sPassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sEncrypt = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sEngine
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetEngine($sEngine)
|
||||
{
|
||||
$this->sEngine = $sEngine;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetHost($sHost)
|
||||
{
|
||||
$this->sHost = $sHost;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetPort($iPort)
|
||||
{
|
||||
$this->iPort = (int) $iPort;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sDatabase
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetDatabase($sDatabase)
|
||||
{
|
||||
$this->sDatabase = $sDatabase;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sTable
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetTable($sTable)
|
||||
{
|
||||
$this->sTable = $sTable;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUsercol
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetUserColumn($sUsercol)
|
||||
{
|
||||
$this->sUsercol = $sUsercol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPasscol
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetPasswordColumn($sPasscol)
|
||||
{
|
||||
$this->sPasscol = $sPasscol;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sUser
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetUser($sUser)
|
||||
{
|
||||
$this->sUser = $sUser;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetPassword($sPassword)
|
||||
{
|
||||
$this->sPassword = $sPassword;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sEncrypt
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetEncrypt($sEncrypt)
|
||||
{
|
||||
$this->sEncrypt = $sEncrypt;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAllowedEmails
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
public function SetAllowedEmails($sAllowedEmails)
|
||||
{
|
||||
$this->sAllowedEmails = $sAllowedEmails;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \MailSo\Log\Logger $oLogger
|
||||
*
|
||||
* @return \ChangePasswordPostfixAdminDriver
|
||||
*/
|
||||
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('Postfix: Try to change password for '.$oAccount->Email());
|
||||
}
|
||||
|
||||
unset($sPrevPassword);
|
||||
|
||||
$bResult = false;
|
||||
|
||||
if (0 < \strlen($sNewPassword))
|
||||
{
|
||||
try
|
||||
{
|
||||
$sDsn = '';
|
||||
switch($this->sEngine){
|
||||
case 'MySQL':
|
||||
$sDsn = 'mysql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase;
|
||||
break;
|
||||
case 'PostgreSQL':
|
||||
$sDsn = 'pgsql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase;
|
||||
break;
|
||||
default:
|
||||
$sDsn = 'mysql:host='.$this->sHost.';port='.$this->iPort.';dbname='.$this->sDatabase;
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
$oPdo = new \PDO($sDsn, $this->sUser, $this->sPassword);
|
||||
$oPdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
|
||||
|
||||
$sUpdatePassword = $this->cryptPassword($sNewPassword, $oPdo);
|
||||
if (0 < \strlen($sUpdatePassword))
|
||||
{
|
||||
$oStmt = $oPdo->prepare("UPDATE {$this->sTable} SET {$this->sPasscol} = ? WHERE {$this->sUsercol} = ?");
|
||||
$bResult = (bool) $oStmt->execute(array($sUpdatePassword, $oAccount->Email()));
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->Write('Postfix: Encrypted password is empty',
|
||||
\MailSo\Log\Enumerations\Type::ERROR);
|
||||
}
|
||||
}
|
||||
|
||||
$oPdo = null;
|
||||
}
|
||||
catch (\Exception $oException)
|
||||
{
|
||||
if ($this->oLogger)
|
||||
{
|
||||
$this->oLogger->WriteException($oException);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $bResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sPassword
|
||||
* @param \PDO $oPdo
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function cryptPassword($sPassword, $oPdo)
|
||||
{
|
||||
$sResult = '';
|
||||
if (function_exists('random_bytes')) {
|
||||
$sSalt = substr(base64_encode(random_bytes(32)), 0, 16);
|
||||
} else {
|
||||
$sSalt = substr(str_shuffle('./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789'), 0, 16);
|
||||
}
|
||||
switch (strtolower($this->sEncrypt))
|
||||
{
|
||||
default:
|
||||
case 'plain':
|
||||
case 'cleartext':
|
||||
$sResult = '{PLAIN}' . $sPassword;
|
||||
break;
|
||||
|
||||
case 'md5crypt':
|
||||
include_once __DIR__.'/md5crypt.php';
|
||||
$sResult = '{MD5-CRYPT}' . md5crypt($sPassword);
|
||||
break;
|
||||
|
||||
case 'md5':
|
||||
$sResult = '{PLAIN-MD5}' . md5($sPassword);
|
||||
break;
|
||||
|
||||
case 'system':
|
||||
$sResult = '{CRYPT}' . crypt($sPassword);
|
||||
break;
|
||||
|
||||
case 'sha256-crypt':
|
||||
$sResult = '{SHA256-CRYPT}' . crypt($sPassword,'$5$'.$sSalt);
|
||||
break;
|
||||
|
||||
case 'sha512-crypt':
|
||||
$sResult = '{SHA512-CRYPT}' . crypt($sPassword,'$6$'.$sSalt);
|
||||
break;
|
||||
|
||||
case 'mysql_encrypt':
|
||||
if($this->sEngine == 'MySQL'){
|
||||
$oStmt = $oPdo->prepare('SELECT ENCRYPT(?) AS encpass');
|
||||
if ($oStmt->execute(array($sPassword)))
|
||||
{
|
||||
$aFetchResult = $oStmt->fetchAll(\PDO::FETCH_ASSOC);
|
||||
if (\is_array($aFetchResult) && isset($aFetchResult[0]['encpass']))
|
||||
{
|
||||
$sResult = $aFetchResult[0]['encpass'];
|
||||
}
|
||||
}
|
||||
}else{
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CouldNotSaveNewPassword);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return $sResult;
|
||||
}
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 RainLoop Team, @zaffkea
|
||||
|
||||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (PostfixAdmin).
|
|
@ -1 +0,0 @@
|
|||
1.3
|
|
@ -1,100 +0,0 @@
|
|||
<?php
|
||||
|
||||
class PostfixadminChangePasswordPlugin 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 extension PDO must be installed to use this plugin';
|
||||
}
|
||||
|
||||
$aDrivers = \PDO::getAvailableDrivers();
|
||||
if (!is_array($aDrivers) || (!in_array('mysql', $aDrivers) && !in_array('pgsql', $aDrivers)))
|
||||
{
|
||||
return 'The PHP extension PDO (mysql or pgsql) must be installed to use this plugin';
|
||||
}
|
||||
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sName
|
||||
* @param mixed $oProvider
|
||||
*/
|
||||
public function MainFabrica($sName, &$oProvider)
|
||||
{
|
||||
switch ($sName)
|
||||
{
|
||||
case 'change-password':
|
||||
|
||||
include_once __DIR__.'/ChangePasswordPostfixAdminDriver.php';
|
||||
|
||||
$oProvider = new ChangePasswordPostfixAdminDriver();
|
||||
|
||||
$oProvider
|
||||
->SetEngine($this->Config()->Get('plugin', 'engine',''))
|
||||
->SetHost($this->Config()->Get('plugin', 'host', ''))
|
||||
->SetPort((int) $this->Config()->Get('plugin', 'port', 3306))
|
||||
->SetDatabase($this->Config()->Get('plugin', 'database', ''))
|
||||
->SetTable($this->Config()->Get('plugin', 'table', ''))
|
||||
->SetUserColumn($this->Config()->Get('plugin', 'usercol', ''))
|
||||
->SetPasswordColumn($this->Config()->Get('plugin', 'passcol', ''))
|
||||
->SetUser($this->Config()->Get('plugin', 'user', ''))
|
||||
->SetPassword($this->Config()->Get('plugin', 'password', ''))
|
||||
->SetEncrypt($this->Config()->Get('plugin', 'encrypt', ''))
|
||||
->SetAllowedEmails(\strtolower(\trim($this->Config()->Get('plugin', 'allowed_emails', ''))))
|
||||
->SetLogger($this->Manager()->Actions()->Logger())
|
||||
;
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('engine')->SetLabel('Engine')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('MySQL', 'PostgreSQL'))
|
||||
->SetDescription('Database Engine'),
|
||||
\RainLoop\Plugins\Property::NewInstance('host')->SetLabel('Host')
|
||||
->SetDefaultValue('127.0.0.1'),
|
||||
\RainLoop\Plugins\Property::NewInstance('port')->SetLabel('Port')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::INT)
|
||||
->SetDefaultValue(3306),
|
||||
\RainLoop\Plugins\Property::NewInstance('database')->SetLabel('Database')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('table')->SetLabel('table')
|
||||
->SetDefaultValue('mailbox'),
|
||||
\RainLoop\Plugins\Property::NewInstance('usercol')->SetLabel('username column')
|
||||
->SetDefaultValue('username'),
|
||||
\RainLoop\Plugins\Property::NewInstance('passcol')->SetLabel('password column')
|
||||
->SetDefaultValue('password'),
|
||||
\RainLoop\Plugins\Property::NewInstance('user')->SetLabel('User')
|
||||
->SetDefaultValue('postfixadmin'),
|
||||
\RainLoop\Plugins\Property::NewInstance('password')->SetLabel('Password')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::PASSWORD)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('encrypt')->SetLabel('Encrypt')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('md5crypt', 'md5', 'system', 'cleartext', 'mysql_encrypt', 'SHA256-CRYPT', 'SHA512-CRYPT'))
|
||||
->SetDescription('In what way do you want the passwords to be crypted ?'),
|
||||
\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('*')
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,139 +0,0 @@
|
|||
<?php
|
||||
|
||||
// md5crypt
|
||||
// Action: Creates MD5 encrypted password
|
||||
// Call: md5crypt (string cleartextpassword)
|
||||
|
||||
function md5crypt($pw, $salt = "", $magic = "")
|
||||
{
|
||||
$MAGIC = "$1$";
|
||||
|
||||
if ($magic == "")
|
||||
{
|
||||
$magic = $MAGIC;
|
||||
}
|
||||
|
||||
if ($salt == "")
|
||||
{
|
||||
$salt = create_salt();
|
||||
}
|
||||
|
||||
$slist = explode("$", $salt);
|
||||
if (isset($slist[0]) && $slist[0] == "1")
|
||||
{
|
||||
$salt = $slist[1];
|
||||
}
|
||||
|
||||
$salt = substr($salt, 0, 8);
|
||||
$ctx = $pw.$magic.$salt;
|
||||
$final = hex2bin(md5($pw.$salt.$pw));
|
||||
|
||||
for ($i = strlen($pw); $i > 0; $i -= 16)
|
||||
{
|
||||
if ($i > 16)
|
||||
{
|
||||
$ctx .= substr($final,0,16);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctx .= substr($final,0,$i);
|
||||
}
|
||||
}
|
||||
|
||||
$i = strlen($pw);
|
||||
|
||||
while ($i > 0)
|
||||
{
|
||||
if ($i & 1)
|
||||
{
|
||||
$ctx .= chr(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctx .= $pw[0];
|
||||
}
|
||||
|
||||
$i = $i >> 1;
|
||||
}
|
||||
|
||||
$final = hex2bin(md5($ctx));
|
||||
|
||||
for ($i=0; $i<1000; $i++)
|
||||
{
|
||||
$ctx1 = "";
|
||||
if ($i & 1)
|
||||
{
|
||||
$ctx1 .= $pw;
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctx1 .= substr($final,0,16);
|
||||
}
|
||||
if ($i % 3)
|
||||
{
|
||||
$ctx1 .= $salt;
|
||||
}
|
||||
if ($i % 7)
|
||||
{
|
||||
$ctx1 .= $pw;
|
||||
}
|
||||
if ($i & 1)
|
||||
{
|
||||
$ctx1 .= substr($final, 0, 16);
|
||||
}
|
||||
else
|
||||
{
|
||||
$ctx1 .= $pw;
|
||||
}
|
||||
|
||||
$final = hex2bin(md5($ctx1));
|
||||
}
|
||||
|
||||
$passwd = "";
|
||||
$passwd .= to64(((ord($final[0]) << 16) | (ord($final[6]) << 8) | (ord($final[12]))), 4);
|
||||
$passwd .= to64(((ord($final[1]) << 16) | (ord($final[7]) << 8) | (ord($final[13]))), 4);
|
||||
$passwd .= to64(((ord($final[2]) << 16) | (ord($final[8]) << 8) | (ord($final[14]))), 4);
|
||||
$passwd .= to64(((ord($final[3]) << 16) | (ord($final[9]) << 8) | (ord($final[15]))), 4);
|
||||
$passwd .= to64(((ord($final[4]) << 16) | (ord($final[10]) << 8) | (ord($final[5]))), 4);
|
||||
$passwd .= to64(ord($final[11]), 2);
|
||||
|
||||
return $magic.$salt.'$'.$passwd;
|
||||
}
|
||||
|
||||
function create_salt()
|
||||
{
|
||||
srand((double) microtime() * 1000000);
|
||||
return substr(md5(rand(0,9999999)), 0, 8);
|
||||
}
|
||||
|
||||
// PHP around 5.3.8 includes hex2bin as native function - http://php.net/hex2bin
|
||||
if (!function_exists('hex2bin'))
|
||||
{
|
||||
function hex2bin($str)
|
||||
{
|
||||
$len = strlen($str);
|
||||
$nstr = "";
|
||||
for ($i = 0; $i < $len; $i += 2)
|
||||
{
|
||||
$num = sscanf(substr($str, $i, 2), "%x");
|
||||
$nstr .= chr($num[0]);
|
||||
}
|
||||
|
||||
return $nstr;
|
||||
}
|
||||
}
|
||||
|
||||
function to64($v, $n)
|
||||
{
|
||||
$ITOA64 = "./0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
|
||||
$ret = "";
|
||||
|
||||
while (($n - 1) >= 0)
|
||||
{
|
||||
$n--;
|
||||
$ret .= $ITOA64[$v & 0x3f];
|
||||
$v = $v >> 6;
|
||||
}
|
||||
|
||||
return $ret;
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Copyright (c) 2015 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.
|
|
@ -1,3 +0,0 @@
|
|||
A CAPTCHA (v2) is a program that can generate and grade tests that humans can pass but current computer programs cannot.
|
||||
For example, humans can read distorted text as the one shown below, but current computer programs can't.
|
||||
More info at http://www.google.com/recaptcha
|
|
@ -1 +0,0 @@
|
|||
2.2
|
|
@ -1,151 +0,0 @@
|
|||
<?php
|
||||
|
||||
class RecaptchaPlugin extends \RainLoop\Plugins\AbstractPlugin
|
||||
{
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function Init()
|
||||
{
|
||||
$this->UseLangs(true);
|
||||
|
||||
$this->addJs('js/recaptcha.js');
|
||||
|
||||
$this->addHook('ajax.action-pre-call', 'AjaxActionPreCall');
|
||||
$this->addHook('filter.ajax-response', 'FilterAjaxResponse');
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function configMapping()
|
||||
{
|
||||
return array(
|
||||
\RainLoop\Plugins\Property::NewInstance('public_key')->SetLabel('Site key')
|
||||
->SetAllowedInJs(true)
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('private_key')->SetLabel('Secret key')
|
||||
->SetDefaultValue(''),
|
||||
\RainLoop\Plugins\Property::NewInstance('theme')->SetLabel('Theme')
|
||||
->SetAllowedInJs(true)
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array('light', 'dark')),
|
||||
\RainLoop\Plugins\Property::NewInstance('error_limit')->SetLabel('Limit')
|
||||
->SetType(\RainLoop\Enumerations\PluginPropertyType::SELECTION)
|
||||
->SetDefaultValue(array(0, 1, 2, 3, 4, 5))
|
||||
->SetDescription('')
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function getCaptchaCacherKey()
|
||||
{
|
||||
return 'CaptchaNew/Login/'.\RainLoop\Utils::GetConnectionToken();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
private function getLimit()
|
||||
{
|
||||
$iConfigLimit = $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
if (0 < $iConfigLimit)
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$sLimit = $oCacher && $oCacher->IsInited() ? $oCacher->Get($this->getCaptchaCacherKey()) : '0';
|
||||
|
||||
if (0 < \strlen($sLimit) && \is_numeric($sLimit))
|
||||
{
|
||||
$iConfigLimit -= (int) $sLimit;
|
||||
}
|
||||
}
|
||||
|
||||
return $iConfigLimit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return void
|
||||
*/
|
||||
public function FilterAppDataPluginSection($bAdmin, $bAuth, &$aData)
|
||||
{
|
||||
if (!$bAdmin && !$bAuth && \is_array($aData))
|
||||
{
|
||||
$aData['show_captcha_on_login'] = 1 > $this->getLimit();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
*/
|
||||
public function AjaxActionPreCall($sAction)
|
||||
{
|
||||
if ('Login' === $sAction && 0 >= $this->getLimit())
|
||||
{
|
||||
$bResult = false;
|
||||
|
||||
$sResult = $this->Manager()->Actions()->Http()->SendPostRequest(
|
||||
'https://www.google.com/recaptcha/api/siteverify',
|
||||
array(
|
||||
'secret' => $this->Config()->Get('plugin', 'private_key', ''),
|
||||
'response' => $this->Manager()->Actions()->GetActionParam('RecaptchaResponse', '')
|
||||
)
|
||||
);
|
||||
|
||||
if ($sResult)
|
||||
{
|
||||
$aResp = @\json_decode($sResult, true);
|
||||
if (\is_array($aResp) && isset($aResp['success']) && $aResp['success'])
|
||||
{
|
||||
$bResult = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$bResult)
|
||||
{
|
||||
$this->Manager()->Actions()->Logger()->Write('RecaptchaResponse:'.$sResult);
|
||||
throw new \RainLoop\Exceptions\ClientException(\RainLoop\Notifications::CaptchaError);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $sAction
|
||||
* @param array $aResponseItem
|
||||
*/
|
||||
public function FilterAjaxResponse($sAction, &$aResponseItem)
|
||||
{
|
||||
if ('Login' === $sAction && $aResponseItem && isset($aResponseItem['Result']))
|
||||
{
|
||||
$oCacher = $this->Manager()->Actions()->Cacher();
|
||||
$iConfigLimit = (int) $this->Config()->Get('plugin', 'error_limit', 0);
|
||||
|
||||
$sKey = $this->getCaptchaCacherKey();
|
||||
|
||||
if (0 < $iConfigLimit && $oCacher && $oCacher->IsInited())
|
||||
{
|
||||
if (false === $aResponseItem['Result'])
|
||||
{
|
||||
$iLimit = 0;
|
||||
$sLimut = $oCacher->Get($sKey);
|
||||
if (0 < \strlen($sLimut) && \is_numeric($sLimut))
|
||||
{
|
||||
$iLimit = (int) $sLimut;
|
||||
}
|
||||
|
||||
$oCacher->Set($sKey, ++$iLimit);
|
||||
|
||||
if ($iConfigLimit <= $iLimit)
|
||||
{
|
||||
$aResponseItem['Captcha'] = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
$oCacher->Delete($sKey);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
(function ($, window) {
|
||||
|
||||
$(function () {
|
||||
|
||||
var
|
||||
nId = null,
|
||||
bStarted = false
|
||||
;
|
||||
|
||||
function ShowRecaptcha()
|
||||
{
|
||||
if (window.grecaptcha && window.rl)
|
||||
{
|
||||
if (null === nId)
|
||||
{
|
||||
var
|
||||
oEl = null,
|
||||
oLink = $('.plugin-mark-Login-BottomControlGroup')
|
||||
;
|
||||
|
||||
if (oLink && oLink[0])
|
||||
{
|
||||
oEl = $('<div class="controls"></div>');
|
||||
|
||||
$(oLink[0]).after(oEl);
|
||||
|
||||
nId = window.grecaptcha.render(oEl[0], {
|
||||
'sitekey': window.rl.pluginSettingsGet('recaptcha', 'public_key'),
|
||||
'theme': window.rl.pluginSettingsGet('recaptcha', 'theme')
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
window.__globalShowRecaptcha = ShowRecaptcha;
|
||||
|
||||
function StartRecaptcha()
|
||||
{
|
||||
if (!window.grecaptcha && window.rl)
|
||||
{
|
||||
$.getScript('https://www.google.com/recaptcha/api.js?onload=__globalShowRecaptcha&render=explicit&hl=' + window.rl.settingsGet('Language'));
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowRecaptcha();
|
||||
}
|
||||
}
|
||||
|
||||
if (window.rl)
|
||||
{
|
||||
window.rl.addHook('user-login-submit', function (fSubmitResult) {
|
||||
if (null !== nId && !window.grecaptcha.getResponse(nId))
|
||||
{
|
||||
fSubmitResult(105);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('view-model-on-show', function (sName, oViewModel) {
|
||||
if (!bStarted && oViewModel &&
|
||||
('View:RainLoop:Login' === sName || 'View/App/Login' === sName || 'LoginViewModel' === sName || 'LoginAppView' === sName) &&
|
||||
window.rl.pluginSettingsGet('recaptcha', 'show_captcha_on_login'))
|
||||
{
|
||||
bStarted = true;
|
||||
StartRecaptcha();
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-request', function (sAction, oParameters) {
|
||||
if ('Login' === sAction && oParameters && null !== nId && window.grecaptcha)
|
||||
{
|
||||
oParameters['RecaptchaResponse'] = window.grecaptcha.getResponse(nId);
|
||||
}
|
||||
});
|
||||
|
||||
window.rl.addHook('ajax-default-response', function (sAction, oData, sType) {
|
||||
if ('Login' === sAction)
|
||||
{
|
||||
if (!oData || 'success' !== sType || !oData['Result'])
|
||||
{
|
||||
if (null !== nId && window.grecaptcha)
|
||||
{
|
||||
window.grecaptcha.reset(nId);
|
||||
}
|
||||
else if (oData && oData['Captcha'])
|
||||
{
|
||||
StartRecaptcha();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
}($, window));
|
|
@ -1,20 +0,0 @@
|
|||
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.
|
|
@ -1 +0,0 @@
|
|||
Plugin that adds functionality to change the email account password (Generic REST).
|
|
@ -1,172 +0,0 @@
|
|||
<?php
|
||||
|
||||
class RestChangePasswordDriver implements \RainLoop\Providers\ChangePassword\ChangePasswordInterface
|
||||
{
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sUrl = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sKey = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFieldEmail = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFieldOldpassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sFieldNewpassword = '';
|
||||
|
||||
/**
|
||||
* @var string
|
||||
*/
|
||||
private $sAllowedEmails = '';
|
||||
|
||||
/**
|
||||
* @var \MailSo\Log\Logger
|
||||
*/
|
||||
private $oLogger = null;
|
||||
|
||||
/**
|
||||
* @param string $sHost
|
||||
* @param int $iPort
|
||||
*
|
||||
* @return \RestChangePasswordDriver
|
||||
*/
|
||||
public function SetConfig($sUrl, $sKey)
|
||||
{
|
||||
$this->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;
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
1.0
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue