mirror of
https://github.com/the-djmaze/snappymail.git
synced 2026-07-13 03:27:39 +03:00
Trying different sso type (PHP) for ownCloud package
This commit is contained in:
parent
777d014403
commit
1d39879765
12 changed files with 81 additions and 70 deletions
|
|
@ -10,7 +10,7 @@
|
||||||
************************************************************************
|
************************************************************************
|
||||||
|
|
||||||
REQUIREMENTS:
|
REQUIREMENTS:
|
||||||
- Installed and configured RainLoop Webmail
|
- Installed and configured RainLoop Webmail (standalone)
|
||||||
- ownCloud version 6 or higher
|
- ownCloud version 6 or higher
|
||||||
- Both apps (RainLoop & ownCloud) running on the same domain
|
- Both apps (RainLoop & ownCloud) running on the same domain
|
||||||
|
|
||||||
|
|
@ -20,17 +20,7 @@ INSTALL:
|
||||||
|
|
||||||
|
|
||||||
CONFIGURATION:
|
CONFIGURATION:
|
||||||
|
|
||||||
- RainLoop:
|
|
||||||
1) Open ../_default_/configs/application.ini
|
|
||||||
2) Find:
|
|
||||||
|
|
||||||
[labs]
|
|
||||||
allow_external_sso = On
|
|
||||||
external_sso_key = "super-secret-key"
|
|
||||||
|
|
||||||
- ownCloud:
|
- ownCloud:
|
||||||
1) In the Apps > Enable 'RainLoop' plugin
|
1) In the Apps > Enable 'RainLoop' plugin
|
||||||
2) In the Settings > Admin > Enter "RainLoop Webmail URL" and "SSO key"
|
2) In the Settings > Admin > Enter "RainLoop Webmail URL" and "Absolute file path to RainLoop Webmail installation"
|
||||||
3) In the Settings > Personal > Type your mail server email (login) and password
|
3) In the Settings > Personal > Type your mail server email (login) and password
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,5 +15,5 @@ OCP\Util::addScript('rainloop', 'admin');
|
||||||
|
|
||||||
$oTemplate = new OCP\Template('rainloop', 'admin');
|
$oTemplate = new OCP\Template('rainloop', 'admin');
|
||||||
$oTemplate->assign('rainloop-url', OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
$oTemplate->assign('rainloop-url', OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
||||||
$oTemplate->assign('rainloop-sso-key', OCP\Config::getAppValue('rainloop', 'rainloop-sso-key', ''));
|
$oTemplate->assign('rainloop-path', OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
|
||||||
return $oTemplate->fetchPage();
|
return $oTemplate->fetchPage();
|
||||||
|
|
|
||||||
|
|
@ -14,20 +14,21 @@ OCP\JSON::checkAppEnabled('rainloop');
|
||||||
OCP\JSON::callCheck();
|
OCP\JSON::callCheck();
|
||||||
|
|
||||||
$sUrl = '';
|
$sUrl = '';
|
||||||
$sSsoKey = '';
|
$sPath = '';
|
||||||
if (isset($_POST['appname'], $_POST['rainloop-url'], $_POST['rainloop-sso-key']) && 'rainloop' === $_POST['appname'])
|
|
||||||
|
if (isset($_POST['appname'], $_POST['rainloop-url'], $_POST['rainloop-path']) && 'rainloop' === $_POST['appname'])
|
||||||
{
|
{
|
||||||
OCP\Config::setAppValue('rainloop', 'rainloop-url', $_POST['rainloop-url']);
|
OCP\Config::setAppValue('rainloop', 'rainloop-url', $_POST['rainloop-url']);
|
||||||
OCP\Config::setAppValue('rainloop', 'rainloop-sso-key', $_POST['rainloop-sso-key']);
|
OCP\Config::setAppValue('rainloop', 'rainloop-path', $_POST['rainloop-path']);
|
||||||
|
|
||||||
$sUrl = OCP\Config::getAppValue('rainloop', 'rainloop-url', '');
|
$sUrl = OCP\Config::getAppValue('rainloop', 'rainloop-url', '');
|
||||||
$sSsoKey = OCP\Config::getAppValue('rainloop', 'rainloop-sso-key', '');
|
$sPath = OCP\Config::getAppValue('rainloop', 'rainloop-path', '');
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
OC_JSON::error(array('Message' => 'Invalid Argument(s)', 'Url' => $sUrl, 'SsoKey' => $sSsoKey));
|
OC_JSON::error(array('Message' => 'Invalid Argument(s)', 'Url' => $sUrl, 'Path' => $sPath));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
OCP\JSON::success(array('Message' => 'Saved successfully', 'Url' => $sUrl, 'SsoKey' => $sSsoKey));
|
OCP\JSON::success(array('Message' => 'Saved successfully', 'Url' => $sUrl, 'Path' => $sPath));
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ OCP\App::checkAppEnabled('rainloop');
|
||||||
OCP\App::setActiveNavigationEntry('rainloop_index');
|
OCP\App::setActiveNavigationEntry('rainloop_index');
|
||||||
|
|
||||||
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
||||||
$sSsoKey = trim(OCP\Config::getAppValue('rainloop', 'rainloop-sso-key', ''));
|
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
|
||||||
|
|
||||||
if ('' === $sUrl || '' === $sSsoKey)
|
if ('' === $sUrl || '' === $sPath)
|
||||||
{
|
{
|
||||||
$oTemplate = new OCP\Template('rainloop', 'index-empty', 'user');
|
$oTemplate = new OCP\Template('rainloop', 'index-empty', 'user');
|
||||||
}
|
}
|
||||||
|
|
@ -27,19 +27,14 @@ else
|
||||||
$sUser = OCP\User::getUser();
|
$sUser = OCP\User::getUser();
|
||||||
|
|
||||||
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
|
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
|
||||||
$sLogin = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-login', '');
|
|
||||||
$sPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
|
$sPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
|
||||||
|
|
||||||
$sUrl = \rtrim($sUrl, '/\\');
|
|
||||||
if ('.php' !== \strtolower(\substr($sUrl), -4))
|
|
||||||
{
|
|
||||||
$sUrl .= '/';
|
|
||||||
}
|
|
||||||
|
|
||||||
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
|
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
|
||||||
$sPassword = OC_RainLoop_Helper::decodePassword($sPassword, md5($sEmail.$sLogin));
|
$sPassword = OC_RainLoop_Helper::decodePassword($sPassword, md5($sEmail));
|
||||||
$sSsoHash = OC_RainLoop_Helper::getSsoHash($sUrl, $sSsoKey, $sEmail, $sPassword, $sLogin);
|
$sSsoHash = OC_RainLoop_Helper::getSsoHash($sPath, $sEmail, $sPassword);
|
||||||
|
|
||||||
|
$sUrl = OC_RainLoop_Helper::normalizeUrl($sUrl);
|
||||||
$sResultUrl = empty($sSsoHash) ? $sUrl.'?sso' : $sUrl.'?sso&hash='.$sSsoHash;
|
$sResultUrl = empty($sSsoHash) ? $sUrl.'?sso' : $sUrl.'?sso&hash='.$sSsoHash;
|
||||||
|
|
||||||
$oTemplate = new OCP\Template('rainloop', 'index', 'user');
|
$oTemplate = new OCP\Template('rainloop', 'index', 'user');
|
||||||
|
|
|
||||||
|
|
@ -2,37 +2,47 @@
|
||||||
|
|
||||||
class OC_RainLoop_Helper
|
class OC_RainLoop_Helper
|
||||||
{
|
{
|
||||||
public static function getSsoHash($sUrl, $sSsoKey, $sEmail, $sPassword)
|
/**
|
||||||
|
* @param string $sPath
|
||||||
|
* @param string $sEmail
|
||||||
|
* @param string $sPassword
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function getSsoHash($sPath, $sEmail, $sPassword)
|
||||||
{
|
{
|
||||||
if (!function_exists('curl_init'))
|
$SsoHash = '';
|
||||||
|
|
||||||
|
$sPath = rtrim(trim($sPath), '\\/').'/index.php';
|
||||||
|
if (file_exists($sPath))
|
||||||
{
|
{
|
||||||
return '';
|
$_ENV['RAINLOOP_INCLUDE_AS_API'] = false;
|
||||||
|
include $sPath;
|
||||||
|
|
||||||
|
if (class_exists($sPath))
|
||||||
|
{
|
||||||
|
|
||||||
|
$SsoHash = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$oCurl = curl_init();
|
return $SsoHash;
|
||||||
curl_setopt_array($oCurl, array(
|
|
||||||
CURLOPT_URL => $sUrl.'?ExternalSso',
|
|
||||||
CURLOPT_HEADER => false,
|
|
||||||
CURLOPT_FAILONERROR => true,
|
|
||||||
CURLOPT_SSL_VERIFYPEER => false,
|
|
||||||
CURLOPT_RETURNTRANSFER => true,
|
|
||||||
CURLOPT_POST => true,
|
|
||||||
CURLOPT_USERAGENT => 'RainLoop SSO User Agent (ownCloud)',
|
|
||||||
CURLOPT_POSTFIELDS => http_build_query(array(
|
|
||||||
'SsoKey' => $sSsoKey,
|
|
||||||
'Email' => $sEmail,
|
|
||||||
'Password' => $sPassword
|
|
||||||
), '', '&'),
|
|
||||||
CURLOPT_TIMEOUT => 5
|
|
||||||
));
|
|
||||||
|
|
||||||
$mResult = curl_exec($oCurl);
|
|
||||||
if (is_resource($oCurl))
|
|
||||||
{
|
|
||||||
curl_close($oCurl);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return is_string($mResult) ? $mResult : '';
|
/**
|
||||||
|
* @param string $sUrl
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function normalizeUrl($sUrl)
|
||||||
|
{
|
||||||
|
$sUrl = \rtrim($sUrl, '/\\');
|
||||||
|
if ('.php' !== \strtolower(\substr($sUrl), -4))
|
||||||
|
{
|
||||||
|
$sUrl .= '/';
|
||||||
|
}
|
||||||
|
|
||||||
|
return $sUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static function encodePassword($sPassword, $sSalt)
|
public static function encodePassword($sPassword, $sSalt)
|
||||||
|
|
|
||||||
|
|
@ -15,9 +15,9 @@ OCP\App::checkAppEnabled('rainloop');
|
||||||
OCP\Util::addScript('rainloop', 'personal');
|
OCP\Util::addScript('rainloop', 'personal');
|
||||||
|
|
||||||
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
|
||||||
$sSsoKey = trim(OCP\Config::getAppValue('rainloop', 'rainloop-sso-key', ''));
|
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
|
||||||
|
|
||||||
if ('' === $sUrl || '' === $sSsoKey)
|
if ('' === $sUrl || '' === $sPath)
|
||||||
{
|
{
|
||||||
$oTemplate = new OCP\Template('rainloop', 'empty');
|
$oTemplate = new OCP\Template('rainloop', 'empty');
|
||||||
}
|
}
|
||||||
|
|
@ -28,10 +28,9 @@ else
|
||||||
$oTemplate = new OCP\Template('rainloop', 'personal');
|
$oTemplate = new OCP\Template('rainloop', 'personal');
|
||||||
|
|
||||||
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
|
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
|
||||||
|
$sPass = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
|
||||||
|
|
||||||
$oTemplate->assign('rainloop-email', $sEmail);
|
$oTemplate->assign('rainloop-email', $sEmail);
|
||||||
|
|
||||||
$sPass = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
|
|
||||||
$oTemplate->assign('rainloop-password', 0 === strlen($sPass) && 0 === strlen($sEmail) ? '' : '******');
|
$oTemplate->assign('rainloop-password', 0 === strlen($sPass) && 0 === strlen($sEmail) ? '' : '******');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
<input type="text" style="width:300px;" id="rainloop-url" name="rainloop-url" value="<?php echo $_['rainloop-url']; ?>" placeholder="https://" />
|
<input type="text" style="width:300px;" id="rainloop-url" name="rainloop-url" value="<?php echo $_['rainloop-url']; ?>" placeholder="https://" />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<?php p($l->t('SSO key')); ?>:
|
<?php p($l->t('Absolute file path to RainLoop Webmail installation')); ?>:
|
||||||
<br />
|
<br />
|
||||||
<input type="text" style="width:300px;" id="rainloop-url" name="rainloop-sso-key" value="<?php echo $_['rainloop-sso-key']; ?>" />
|
<input type="text" style="width:300px;" id="rainloop-path" name="rainloop-path" value="<?php echo $_['rainloop-path']; ?>" />
|
||||||
<br />
|
<br />
|
||||||
<br />
|
<br />
|
||||||
<input type="button" id="rainloop-save-button" name="rainloop-save-button" value="<?php p($l->t('Save')); ?>" />
|
<input type="button" id="rainloop-save-button" name="rainloop-save-button" value="<?php p($l->t('Save')); ?>" />
|
||||||
|
|
|
||||||
|
|
@ -36,7 +36,7 @@
|
||||||
"plugins"
|
"plugins"
|
||||||
],
|
],
|
||||||
"readmeFilename": "README.md",
|
"readmeFilename": "README.md",
|
||||||
"ownCloudPackageVersion": "1.5",
|
"ownCloudPackageVersion": "1.6",
|
||||||
"engines": {
|
"engines": {
|
||||||
"node": ">= 0.10.0"
|
"node": ">= 0.10.0"
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -703,6 +703,7 @@ class Utils
|
||||||
'sql' => 'text/plain',
|
'sql' => 'text/plain',
|
||||||
'cfg' => 'text/plain',
|
'cfg' => 'text/plain',
|
||||||
'conf' => 'text/plain',
|
'conf' => 'text/plain',
|
||||||
|
'asc' => 'text/plain',
|
||||||
'rtx' => 'text/richtext',
|
'rtx' => 'text/richtext',
|
||||||
'vcard' => 'text/vcard',
|
'vcard' => 'text/vcard',
|
||||||
'vcf' => 'text/vcard',
|
'vcf' => 'text/vcard',
|
||||||
|
|
|
||||||
|
|
@ -58,10 +58,11 @@ class CacheClient
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sKey
|
* @param string $sKey
|
||||||
|
* @param string $bClearAfterGet = false
|
||||||
*
|
*
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
public function Get($sKey)
|
public function Get($sKey, $bClearAfterGet = false)
|
||||||
{
|
{
|
||||||
$sValue = '';
|
$sValue = '';
|
||||||
|
|
||||||
|
|
@ -70,6 +71,11 @@ class CacheClient
|
||||||
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
$sValue = $this->oDriver->Get($sKey.$this->sCacheIndex);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ($bClearAfterGet)
|
||||||
|
{
|
||||||
|
$this->Delete($sKey);
|
||||||
|
}
|
||||||
|
|
||||||
return $sValue;
|
return $sValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1620,18 +1620,16 @@ class Actions
|
||||||
$oLogger = $this->Logger();
|
$oLogger = $this->Logger();
|
||||||
$oLogger->Write('Trying to decode encrypted data', \MailSo\Log\Enumerations\Type::INFO, 'RSA');
|
$oLogger->Write('Trying to decode encrypted data', \MailSo\Log\Enumerations\Type::INFO, 'RSA');
|
||||||
|
|
||||||
$sPrivateKey = $this->Cacher()->Get('/Key/RSA/'.$aMatch[1].'/');
|
$sPrivateKey = $this->Cacher()->Get(\RainLoop\KeyPathHelper::RsaCacherKey($aMatch[1]), true);
|
||||||
if (!empty($sPrivateKey))
|
if (!empty($sPrivateKey))
|
||||||
{
|
{
|
||||||
$this->Cacher()->Delete('/Key/RSA/'.$aMatch[1].'/');
|
|
||||||
|
|
||||||
$sData = \trim(\substr($sEncryptedData, 37));
|
$sData = \trim(\substr($sEncryptedData, 37));
|
||||||
|
|
||||||
if (!\class_exists('Crypt_RSA'))
|
if (!\class_exists('Crypt_RSA'))
|
||||||
{
|
{
|
||||||
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
||||||
include_once 'Crypt/RSA.php';
|
|
||||||
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
|
include_once 'Crypt/RSA.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
\RainLoop\Service::$__HIDE_ERROR_NOTICES = true;
|
\RainLoop\Service::$__HIDE_ERROR_NOTICES = true;
|
||||||
|
|
@ -1677,8 +1675,8 @@ class Actions
|
||||||
if (!\class_exists('Crypt_RSA'))
|
if (!\class_exists('Crypt_RSA'))
|
||||||
{
|
{
|
||||||
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
\set_include_path(\get_include_path().PATH_SEPARATOR.APP_VERSION_ROOT_PATH.'app/libraries/phpseclib');
|
||||||
include_once 'Crypt/RSA.php';
|
|
||||||
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
\defined('CRYPT_RSA_MODE') || \define('CRYPT_RSA_MODE', CRYPT_RSA_MODE_INTERNAL);
|
||||||
|
include_once 'Crypt/RSA.php';
|
||||||
}
|
}
|
||||||
|
|
||||||
$oRsa = new \Crypt_RSA();
|
$oRsa = new \Crypt_RSA();
|
||||||
|
|
@ -1694,7 +1692,8 @@ class Actions
|
||||||
|
|
||||||
\RainLoop\Service::$__HIDE_ERROR_NOTICES = false;
|
\RainLoop\Service::$__HIDE_ERROR_NOTICES = false;
|
||||||
return $this->DefaultResponse(__FUNCTION__,
|
return $this->DefaultResponse(__FUNCTION__,
|
||||||
$this->Cacher()->Set('/Key/RSA/'.$sHash.'/', $aKeys['privatekey']) ? array($sHash, $e->toHex(), $n->toHex()) : false);
|
$this->Cacher()->Set(\RainLoop\KeyPathHelper::RsaCacherKey($sHash), $aKeys['privatekey']) ?
|
||||||
|
array($sHash, $e->toHex(), $n->toHex()) : false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,16 @@ class KeyPathHelper
|
||||||
return '/Sso/Data/'.$sSsoHash.'/Login/';
|
return '/Sso/Data/'.$sSsoHash.'/Login/';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $sHash
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
static public function RsaCacherKey($sHash)
|
||||||
|
{
|
||||||
|
return '/Rsa/Data/'.$sHash.'/';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param string $sSignMeToken
|
* @param string $sSignMeToken
|
||||||
*
|
*
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue