mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-09-07 08:27:03 +03:00
Resolve #898
This commit is contained in:
parent
8cf8823d56
commit
a7081660f0
4 changed files with 147 additions and 132 deletions
|
|
@ -26,7 +26,7 @@ class FetchController extends Controller {
|
||||||
$error = 'Upgrade failed';
|
$error = 'Upgrade failed';
|
||||||
try {
|
try {
|
||||||
SnappyMailHelper::loadApp();
|
SnappyMailHelper::loadApp();
|
||||||
if (SnappyMail\Upgrade::core()) {
|
if (\SnappyMail\Upgrade::core()) {
|
||||||
return new JSONResponse([
|
return new JSONResponse([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'Message' => $this->l->t('Upgraded successfully')
|
'Message' => $this->l->t('Upgraded successfully')
|
||||||
|
|
@ -60,10 +60,9 @@ class FetchController extends Controller {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!empty($_POST['import-rainloop'])) {
|
if (!empty($_POST['import-rainloop'])) {
|
||||||
$result = SnappyMailHelper::importRainLoop();
|
|
||||||
return new JSONResponse([
|
return new JSONResponse([
|
||||||
'status' => 'success',
|
'status' => 'success',
|
||||||
'Message' => \implode("\n", $result)
|
'Message' => \implode("\n", \OCA\SnappyMail\Util\RainLoop::import())
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,22 +91,18 @@ class FetchController extends Controller {
|
||||||
*/
|
*/
|
||||||
public function setPersonal(): JSONResponse {
|
public function setPersonal(): JSONResponse {
|
||||||
try {
|
try {
|
||||||
|
$sEmail = '';
|
||||||
if (isset($_POST['appname'], $_POST['snappymail-password'], $_POST['snappymail-email']) && 'snappymail' === $_POST['appname']) {
|
if (isset($_POST['appname'], $_POST['snappymail-password'], $_POST['snappymail-email']) && 'snappymail' === $_POST['appname']) {
|
||||||
$sUser = \OC::$server->getUserSession()->getUser()->getUID();
|
$sUser = \OC::$server->getUserSession()->getUser()->getUID();
|
||||||
|
|
||||||
$sPostEmail = $_POST['snappymail-email'];
|
$sEmail = $_POST['snappymail-email'];
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sPostEmail);
|
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail);
|
||||||
|
|
||||||
$sPass = $_POST['snappymail-password'];
|
$sPass = $_POST['snappymail-password'];
|
||||||
if ('******' !== $sPass) {
|
if ('******' !== $sPass) {
|
||||||
require_once $this->appManager->getAppPath('snappymail').'/lib/Util/SnappyMailHelper.php';
|
|
||||||
|
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password',
|
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password',
|
||||||
$sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sPostEmail)) : '');
|
$sPass ? SnappyMailHelper::encodePassword($sPass, \md5($sEmail)) : '');
|
||||||
}
|
}
|
||||||
|
|
||||||
$sEmail = $this->config->getUserValue($sUser, 'snappymail', 'snappymail-email', '');
|
|
||||||
} else {
|
} else {
|
||||||
return new JSONResponse([
|
return new JSONResponse([
|
||||||
'status' => 'error',
|
'status' => 'error',
|
||||||
|
|
|
||||||
|
|
@ -1,8 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
namespace OCA\SnappyMail\Settings;
|
namespace OCA\SnappyMail\Settings;
|
||||||
|
|
||||||
use OCA\SnappyMail\Util\SnappyMailHelper;
|
|
||||||
|
|
||||||
use OCP\AppFramework\Http\TemplateResponse;
|
use OCP\AppFramework\Http\TemplateResponse;
|
||||||
use OCP\IConfig;
|
use OCP\IConfig;
|
||||||
use OCP\Settings\ISettings;
|
use OCP\Settings\ISettings;
|
||||||
|
|
@ -21,16 +19,14 @@ class PersonalSettings implements ISettings
|
||||||
$uid = \OC::$server->getUserSession()->getUser()->getUID();
|
$uid = \OC::$server->getUserSession()->getUser()->getUID();
|
||||||
$sEmail = $this->config->getUserValue($uid, 'snappymail', 'snappymail-email');
|
$sEmail = $this->config->getUserValue($uid, 'snappymail', 'snappymail-email');
|
||||||
if (!$sEmail) {
|
if (!$sEmail) {
|
||||||
$sEmail = $this->config->getUserValue($uid, 'rainloop', 'rainloop-email');
|
$aRainLoop = \OCA\SnappyMail\Util\RainLoop::getLoginCredentials($uid, $this->config);
|
||||||
if ($sEmail) {
|
if ($aRainLoop) {
|
||||||
$this->config->setUserValue($uid, 'rainloop', 'rainloop-email'. $sEmail);
|
$sEmail = $aRainLoop[0];
|
||||||
$sPassword = $this->config->getUserValue($uid, 'rainloop', 'rainloop-password');
|
$this->config->setUserValue($uid, 'snappymail', 'snappymail-email', $sEmail);
|
||||||
if ($sPassword) {
|
if ($aRainLoop[1]) {
|
||||||
require_once \dirname(__DIR__) . '/Util/SnappyMailHelper.php';
|
$this->config->setUserValue($uid, 'snappymail', 'snappymail-password',
|
||||||
$sPassword = SnappyMailHelper::decodeRainLoopPassword($sPassword, md5($sEmail));
|
\OCA\SnappyMail\Util\SnappyMailHelper::encodePassword($aRainLoop[1], \md5($sEmail))
|
||||||
}
|
);
|
||||||
if ($sPassword) {
|
|
||||||
$this->config->setUserValue($uid, 'snappymail', 'snappymail-password', SnappyMailHelper::encodePassword($sPassword, \md5($sEmail)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
128
integrations/nextcloud/snappymail/lib/Util/RainLoop.php
Normal file
128
integrations/nextcloud/snappymail/lib/Util/RainLoop.php
Normal file
|
|
@ -0,0 +1,128 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
namespace OCA\SnappyMail\Util;
|
||||||
|
|
||||||
|
class RainLoop
|
||||||
|
{
|
||||||
|
|
||||||
|
public static function getLoginCredentials($sUID, $config) : ?array
|
||||||
|
{
|
||||||
|
$sEmail = \trim($config->getUserValue($sUID, 'rainloop', 'rainloop-email'));
|
||||||
|
if ($sEmail) {
|
||||||
|
$sPassword = $config->getUserValue($sUID, 'rainloop', 'rainloop-password', '');
|
||||||
|
return [
|
||||||
|
$sEmail,
|
||||||
|
$sPassword ? static::decodePassword($sPassword, \md5($sEmail)) : ''
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Imports data from RainLoop
|
||||||
|
* skips: /data/rainloop-storage/_data_/_default_/configs/application.ini
|
||||||
|
* skips: /data/rainloop-storage/_data_/_default_/domains/disabled
|
||||||
|
* skips: /data/rainloop-storage/SALT.php
|
||||||
|
* skips: /data/rainloop-storage/index.html
|
||||||
|
* skips: /data/rainloop-storage/INSTALLED
|
||||||
|
* skips: /data/rainloop-storage/index.php
|
||||||
|
*/
|
||||||
|
public static function import() : array
|
||||||
|
{
|
||||||
|
$dir = \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/');
|
||||||
|
$dir_snappy = $dir . '/appdata_snappymail/';
|
||||||
|
$dir_rainloop = $dir . '/rainloop-storage';
|
||||||
|
$result = [];
|
||||||
|
$rainloop_plugins = [];
|
||||||
|
if (\is_dir($dir_rainloop)) {
|
||||||
|
\is_dir($dir_snappy) || \mkdir($dir_snappy, 0755, true);
|
||||||
|
$iterator = new \RecursiveIteratorIterator(
|
||||||
|
new \RecursiveDirectoryIterator($dir_rainloop, \RecursiveDirectoryIterator::SKIP_DOTS),
|
||||||
|
\RecursiveIteratorIterator::SELF_FIRST
|
||||||
|
);
|
||||||
|
foreach ($iterator as $item) {
|
||||||
|
$target = $dir_snappy . $iterator->getSubPathname();
|
||||||
|
if (\preg_match('@/plugins/([^/]+)@', $target, $match)) {
|
||||||
|
$rainloop_plugins[$match[1]] = $match[1];
|
||||||
|
} else if (!\strpos($target, '/cache/')) {
|
||||||
|
if ($item->isDir()) {
|
||||||
|
\is_dir($target) || \mkdir($target, 0755, true);
|
||||||
|
} else if (\file_exists($target)) {
|
||||||
|
$result[] = "skipped: {$target}";
|
||||||
|
} else {
|
||||||
|
\copy($item, $target);
|
||||||
|
$result[] = "copied : {$target}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// $password = APP_PRIVATE_DATA . 'admin_password.txt';
|
||||||
|
// \is_file($password) && \unlink($password);
|
||||||
|
|
||||||
|
SnappyMailHelper::loadApp();
|
||||||
|
|
||||||
|
// Attempt to install same plugins as RainLoop
|
||||||
|
if ($rainloop_plugins) {
|
||||||
|
foreach (\SnappyMail\Repository::getPackagesList()['List'] as $plugin) {
|
||||||
|
if (\in_array($plugin['id'], $rainloop_plugins)) {
|
||||||
|
$result[] = "install plugin : {$plugin['id']}";
|
||||||
|
\SnappyMail\Repository::installPackage('plugin', $plugin['id']);
|
||||||
|
unset($rainloop_plugins[$plugin['id']]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
foreach ($rainloop_plugins as $plugin) {
|
||||||
|
$result[] = "skipped plugin : {$plugin}";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$oConfig = \RainLoop\Api::Config();
|
||||||
|
$oConfig->Set('webmail', 'theme', 'Nextcloud@custom');
|
||||||
|
$oConfig->Save();
|
||||||
|
|
||||||
|
return $result;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sPassword
|
||||||
|
* @param string $sSalt
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function decodePassword($sPassword, $sSalt)
|
||||||
|
{
|
||||||
|
$sPassword = \base64_decode(\trim($sPassword));
|
||||||
|
|
||||||
|
$method = 'AES-256-CBC';
|
||||||
|
if (\function_exists('openssl_encrypt')
|
||||||
|
&& \function_exists('openssl_decrypt')
|
||||||
|
&& \function_exists('openssl_random_pseudo_bytes')
|
||||||
|
&& \function_exists('openssl_cipher_iv_length')
|
||||||
|
&& \function_exists('openssl_get_cipher_methods')
|
||||||
|
&& \defined('OPENSSL_RAW_DATA')
|
||||||
|
&& \defined('OPENSSL_ZERO_PADDING')
|
||||||
|
&& \in_array($method, \openssl_get_cipher_methods())
|
||||||
|
) {
|
||||||
|
$aParts = \explode('|', $sPassword, 2);
|
||||||
|
if (\is_array($aParts) && !empty($aParts[0]) && !empty($aParts[1])) {
|
||||||
|
$sData = \base64_decode($aParts[0]);
|
||||||
|
$iv = \base64_decode($aParts[1]);
|
||||||
|
return \base64_decode(\trim(
|
||||||
|
\openssl_decrypt($sData, $method, \md5($sSalt), OPENSSL_RAW_DATA, $iv)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (\function_exists('mcrypt_encrypt')
|
||||||
|
&& \function_exists('mcrypt_decrypt')
|
||||||
|
&& \defined('MCRYPT_RIJNDAEL_256')
|
||||||
|
&& \defined('MCRYPT_MODE_ECB')
|
||||||
|
) {
|
||||||
|
return \base64_decode(\trim(
|
||||||
|
\mcrypt_decrypt(MCRYPT_RIJNDAEL_256, \md5($sSalt), $sPassword, MCRYPT_MODE_ECB)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sPassword;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -123,16 +123,11 @@ class SnappyMailHelper
|
||||||
if ($sPassword) {
|
if ($sPassword) {
|
||||||
$sPassword = static::decodePassword($sPassword, \md5($sEmail));
|
$sPassword = static::decodePassword($sPassword, \md5($sEmail));
|
||||||
}
|
}
|
||||||
} else if ($sCustomEmail = $config->getUserValue($sUID, 'rainloop', 'rainloop-email')) {
|
} else if ($aRainLoop = RainLoop::getLoginCredentials($sUID, $config)) {
|
||||||
$sEmail = $sCustomEmail;
|
$sEmail = $aRainLoop[0];
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail);
|
$config->setUserValue($sUser, 'snappymail', 'snappymail-email', $sEmail);
|
||||||
|
if ($aRainLoop[1]) {
|
||||||
$sPassword = $config->getUserValue($sUID, 'rainloop', 'rainloop-password', '');
|
$config->setUserValue($sUser, 'snappymail', 'snappymail-password', static::encodePassword($aRainLoop[1], \md5($sEmail)));
|
||||||
if ($sPassword) {
|
|
||||||
$sPassword = static::decodeRainLoopPassword($sPassword, md5($sEmail));
|
|
||||||
}
|
|
||||||
if ($sPassword) {
|
|
||||||
$this->config->setUserValue($sUser, 'snappymail', 'snappymail-password', static::encodePassword($sPassword, \md5($sEmail)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return [$sUID, $sEmail, $sPassword ?: ''];
|
return [$sUID, $sEmail, $sPassword ?: ''];
|
||||||
|
|
@ -164,103 +159,4 @@ class SnappyMailHelper
|
||||||
static::loadApp();
|
static::loadApp();
|
||||||
return \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt);
|
return \SnappyMail\Crypt::DecryptUrlSafe($sPassword, $sSalt);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Imports data from RainLoop
|
|
||||||
public static function importRainLoop() : array
|
|
||||||
{
|
|
||||||
$result = [];
|
|
||||||
|
|
||||||
$dir = \rtrim(\trim(\OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/');
|
|
||||||
$dir_snappy = $dir . '/appdata_snappymail/';
|
|
||||||
$dir_rainloop = $dir . '/rainloop-storage';
|
|
||||||
$rainloop_plugins = [];
|
|
||||||
if (\is_dir($dir_rainloop)) {
|
|
||||||
\is_dir($dir_snappy) || \mkdir($dir_snappy, 0755, true);
|
|
||||||
$iterator = new \RecursiveIteratorIterator(
|
|
||||||
new \RecursiveDirectoryIterator($dir_rainloop, \RecursiveDirectoryIterator::SKIP_DOTS),
|
|
||||||
\RecursiveIteratorIterator::SELF_FIRST
|
|
||||||
);
|
|
||||||
foreach ($iterator as $item) {
|
|
||||||
$target = $dir_snappy . $iterator->getSubPathname();
|
|
||||||
if (\preg_match('@/plugins/([^/])@', $target, $match)) {
|
|
||||||
$rainloop_plugins[$match[1]] = $match[1];
|
|
||||||
} else if (!\strpos($target, '/cache/')) {
|
|
||||||
if ($item->isDir()) {
|
|
||||||
\is_dir($target) || \mkdir($target, 0755, true);
|
|
||||||
} else if (\file_exists($target)) {
|
|
||||||
$result[] = "skipped: {$target}";
|
|
||||||
} else {
|
|
||||||
\copy($item, $target);
|
|
||||||
$result[] = "copied : {$target}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// $password = APP_PRIVATE_DATA . 'admin_password.txt';
|
|
||||||
// \is_file($password) && \unlink($password);
|
|
||||||
|
|
||||||
static::loadApp();
|
|
||||||
|
|
||||||
// Attempt to install same plugins as RainLoop
|
|
||||||
if ($rainloop_plugins) {
|
|
||||||
foreach (\SnappyMail\Repository::getPackagesList()['List'] as $plugin) {
|
|
||||||
if (\in_array($plugin['id'], $rainloop_plugins)) {
|
|
||||||
$result[] = "install plugin : {$plugin['id']}";
|
|
||||||
\SnappyMail\Repository::installPackage('plugin', $plugin['id']);
|
|
||||||
unset($rainloop_plugins[$plugin['id']]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
foreach ($rainloop_plugins as $plugin) {
|
|
||||||
$result[] = "skipped plugin : {$plugin}";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
$oConfig = \RainLoop\Api::Config();
|
|
||||||
$oConfig->Set('webmail', 'theme', 'Nextcloud@custom');
|
|
||||||
$oConfig->Save();
|
|
||||||
|
|
||||||
return $result;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @param string $sPassword
|
|
||||||
* @param string $sSalt
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
public static function decodeRainLoopPassword($sPassword, $sSalt)
|
|
||||||
{
|
|
||||||
$method = 'AES-256-CBC';
|
|
||||||
if (\function_exists('openssl_encrypt') &&
|
|
||||||
\function_exists('openssl_decrypt') &&
|
|
||||||
\function_exists('openssl_random_pseudo_bytes') &&
|
|
||||||
\function_exists('openssl_cipher_iv_length') &&
|
|
||||||
\function_exists('openssl_get_cipher_methods') &&
|
|
||||||
\defined('OPENSSL_RAW_DATA') && \defined('OPENSSL_ZERO_PADDING') &&
|
|
||||||
\in_array($method, openssl_get_cipher_methods())
|
|
||||||
) {
|
|
||||||
$sLine = base64_decode(trim($sPassword));
|
|
||||||
$aParts = explode('|', $sLine, 2);
|
|
||||||
if (is_array($aParts) && !empty($aParts[0]) && !empty($aParts[1])) {
|
|
||||||
$sData = @base64_decode($aParts[0]);
|
|
||||||
$iv = @base64_decode($aParts[1]);
|
|
||||||
return @base64_decode(trim(
|
|
||||||
@openssl_decrypt($sData, $method, md5($sSalt), OPENSSL_RAW_DATA, $iv)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (\function_exists('mcrypt_encrypt') &&
|
|
||||||
\function_exists('mcrypt_decrypt') &&
|
|
||||||
\defined('MCRYPT_RIJNDAEL_256') &&
|
|
||||||
\defined('MCRYPT_MODE_ECB')
|
|
||||||
) {
|
|
||||||
return @base64_decode(trim(
|
|
||||||
@mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_decode(trim($sPassword)), MCRYPT_MODE_ECB)
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
return @base64_decode(trim($sPassword));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue