Merge pull request #273 from mporcheron/master

Automatic login with ownCloud user credentials
This commit is contained in:
RainLoop Team 2014-08-11 00:06:22 +04:00
commit 7d030583c5
21 changed files with 259 additions and 152 deletions

52
build/owncloud/rainloop-app/INSTALL Normal file → Executable file
View file

@ -1,26 +1,26 @@
************************************************************************ ************************************************************************
* *
* ownCloud - RainLoop Webmail mail plugin * ownCloud - RainLoop Webmail mail plugin
* *
* @author RainLoop Team * @author RainLoop Team
* @copyright 2014 RainLoop Team * @copyright 2014 RainLoop Team
* *
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
* *
************************************************************************ ************************************************************************
REQUIREMENTS: REQUIREMENTS:
- Installed and configured RainLoop Webmail (standalone) - 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
INSTALL: INSTALL:
- Unpack the RainLoop Webmail application package in the apps directory of your OwnCloud instance - Unpack the RainLoop Webmail application package in the apps directory of your OwnCloud instance
CONFIGURATION: CONFIGURATION:
- 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 "Absolute (full) path to RainLoop Webmail installation" 2) In the Settings > Admin > Enter "RainLoop Webmail URL" and "Absolute (full) 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

2
build/owncloud/rainloop-app/VERSION Normal file → Executable file
View file

@ -1 +1 @@
0.0 2.0

View file

@ -16,4 +16,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-path', OCP\Config::getAppValue('rainloop', 'rainloop-path', '')); $oTemplate->assign('rainloop-path', OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$oTemplate->assign('rainloop-autologin', OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false));
return $oTemplate->fetchPage(); return $oTemplate->fetchPage();

View file

@ -15,14 +15,17 @@ OCP\JSON::callCheck();
$sUrl = ''; $sUrl = '';
$sPath = ''; $sPath = '';
$bAutologin = false;
if (isset($_POST['appname'], $_POST['rainloop-url'], $_POST['rainloop-path']) && '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-path', $_POST['rainloop-path']); OCP\Config::setAppValue('rainloop', 'rainloop-path', $_POST['rainloop-path']);
OCP\Config::setAppValue('rainloop', 'rainloop-autologin', $_POST['rainloop-autologin']);
$sUrl = OCP\Config::getAppValue('rainloop', 'rainloop-url', ''); $sUrl = OCP\Config::getAppValue('rainloop', 'rainloop-url', '');
$sPath = OCP\Config::getAppValue('rainloop', 'rainloop-path', ''); $sPath = OCP\Config::getAppValue('rainloop', 'rainloop-path', '');
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
} }
else else
{ {

0
build/owncloud/rainloop-app/ajax/personal.php Normal file → Executable file
View file

View file

@ -9,9 +9,19 @@
* https://github.com/RainLoop/owncloud * https://github.com/RainLoop/owncloud
*/ */
OC::$CLASSPATH['OC_RainLoop_Helper'] = OC_App::getAppPath('rainloop') . '/lib/RainLoopHelper.php';
OCP\App::registerAdmin('rainloop', 'admin'); OCP\App::registerAdmin('rainloop', 'admin');
OCP\App::registerPersonal('rainloop', 'personal'); OCP\App::registerPersonal('rainloop', 'personal');
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
if ('on' === $bAutologin)
{
OCP\Util::connectHook('OC_User', 'post_login', 'OC_RainLoop_Helper', 'login');
OCP\Util::connectHook('OC_User', 'logout', 'OC_RainLoop_Helper', 'logout');
OCP\Util::connectHook('OC_User', 'post_setPassword', 'OC_RainLoop_Helper', 'changePassword');
}
OCP\Util::addScript('rainloop', 'rainloop'); OCP\Util::addScript('rainloop', 'rainloop');
OCP\App::addNavigationEntry(array( OCP\App::addNavigationEntry(array(
@ -19,5 +29,5 @@ OCP\App::addNavigationEntry(array(
'order' => 10, 'order' => 10,
'href' => OCP\Util::linkTo('rainloop', 'index.php'), 'href' => OCP\Util::linkTo('rainloop', 'index.php'),
'icon' => OCP\Util::imagePath('rainloop', 'mail.png'), 'icon' => OCP\Util::imagePath('rainloop', 'mail.png'),
'name' => 'RainLoop' 'name' => 'Email'
)); ));

18
build/owncloud/rainloop-app/appinfo/info.xml Normal file → Executable file
View file

@ -1,10 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>rainloop</id> <id>rainloop</id>
<name>RainLoop</name> <name>RainLoop</name>
<description>RainLoop Webmail</description> <description>RainLoop Webmail</description>
<version>0.0</version> <version>2.0</version>
<licence>CC BY-NC-SA 3.0</licence> <licence>CC BY-NC-SA 3.0</licence>
<author>RainLoop Team</author> <author>RainLoop Team</author>
<require>6.0</require> <require>6.0</require>
</info> </info>

0
build/owncloud/rainloop-app/img/logo-64x64.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 832 B

After

Width:  |  Height:  |  Size: 832 B

Before After
Before After

0
build/owncloud/rainloop-app/img/mail.png Normal file → Executable file
View file

Before

Width:  |  Height:  |  Size: 478 B

After

Width:  |  Height:  |  Size: 478 B

Before After
Before After

View file

@ -1,44 +1,56 @@
<?php <?php
/** /**
* ownCloud - RainLoop mail plugin * ownCloud - RainLoop mail plugin
* *
* @author RainLoop Team * @author RainLoop Team
* @copyright 2014 RainLoop Team * @copyright 2014 RainLoop Team
* *
* https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud * https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud
*/ */
OCP\User::checkLoggedIn(); OCP\User::checkLoggedIn();
OCP\App::checkAppEnabled('rainloop'); 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', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', '')); $sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
if ('' === $sUrl || '' === $sPath)
{
$oTemplate = new OCP\Template('rainloop', 'index-empty', 'user'); if ('' === $sUrl || '' === $sPath)
} {
else $oTemplate = new OCP\Template('rainloop', 'index-empty', 'user');
{ }
OC_Config::setValue('xframe_restriction', false); else
{
$sUser = OCP\User::getUser(); include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php';
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', ''); OC_Config::setValue('xframe_restriction', false);
$sPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
$sUser = OCP\User::getUser();
include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; if ($bAutologin)
$sPassword = OC_RainLoop_Helper::decodePassword($sPassword, md5($sEmail)); {
$sSsoHash = OC_RainLoop_Helper::getSsoHash($sPath, $sEmail, $sPassword); $sEmail = $sUser;
}
$sUrl = OC_RainLoop_Helper::normalizeUrl($sUrl); else
$sResultUrl = empty($sSsoHash) ? $sUrl.'?sso' : $sUrl.'?sso&hash='.$sSsoHash; {
$sEmail = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-email', '');
$oTemplate = new OCP\Template('rainloop', 'index', 'user'); }
$oTemplate->assign('rainloop-url', $sResultUrl);
} $sPassword = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-password', '');
$oTemplate->printpage(); $sPassword = OC_RainLoop_Helper::decodePassword($sPassword, md5($sEmail));
$sSsoHash = OC_RainLoop_Helper::getSsoHash($sPath, $sEmail, $sPassword);
OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-ssohash', $sSsoHash);
$sUrl = OC_RainLoop_Helper::normalizeUrl($sUrl);
$sResultUrl = empty($sSsoHash) ? $sUrl.'?sso' : $sUrl.'?sso&hash='.$sSsoHash;
$oTemplate = new OCP\Template('rainloop', 'index', 'user');
$oTemplate->assign('rainloop-url', $sResultUrl);
}
$oTemplate->printpage();

0
build/owncloud/rainloop-app/js/admin.js Normal file → Executable file
View file

0
build/owncloud/rainloop-app/js/personal.js Normal file → Executable file
View file

0
build/owncloud/rainloop-app/js/rainloop.js Normal file → Executable file
View file

50
build/owncloud/rainloop-app/js/resize.js Normal file → Executable file
View file

@ -1,26 +1,26 @@
$(function (window, document) { $(function (window, document) {
var var
buffer = 5, buffer = 5,
ifr = document.getElementById('rliframe') ifr = document.getElementById('rliframe')
; ;
function pageY(elem) { function pageY(elem) {
return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop; return elem.offsetParent ? (elem.offsetTop + pageY(elem.offsetParent)) : elem.offsetTop;
} }
function resizeIframe() { function resizeIframe() {
var height = document.documentElement.clientHeight; var height = document.documentElement.clientHeight;
height -= pageY(ifr) + buffer; height -= pageY(ifr) + buffer;
height = (height < 0) ? 0 : height; height = (height < 0) ? 0 : height;
ifr.style.height = height + 'px'; ifr.style.height = height + 'px';
} }
if (ifr) if (ifr)
{ {
ifr.onload = resizeIframe; ifr.onload = resizeIframe;
window.onresize = resizeIframe; window.onresize = resizeIframe;
} }
}(window, document)); }(window, document));

View file

@ -28,6 +28,30 @@ class OC_RainLoop_Helper
return $SsoHash; return $SsoHash;
} }
/**
* @param string $sSsoHash
*
* @return boolean
*/
public static function clearUserSsoHash($sSsoHash)
{
$result = false;
$sPath = rtrim(trim($sPath), '\\/').'/index.php';
if (file_exists($sPath))
{
$_ENV['RAINLOOP_INCLUDE_AS_API'] = true;
include $sPath;
if (class_exists('\\RainLoop\\Api'))
{
$result = \RainLoop\Api::ClearUserSsoHash($sSsoHash);
}
}
return $result;
}
/** /**
* @param string $sUrl * @param string $sUrl
* *
@ -67,4 +91,57 @@ class OC_RainLoop_Helper
return @base64_decode(trim($sPassword)); return @base64_decode(trim($sPassword));
} }
public static function login($params)
{
$sUser = $params['uid'];
$sEmail = $sUser;
$sPassword = $params['password'];
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
if ('' !== $sUrl && '' !== $sPath)
{
$sPassword = self::encodePassword($sPassword, md5($sEmail));
return OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password', $sPassword);
}
return false;
}
public static function logout($params)
{
$sUser = OCP\User::getUser();
$sSsoHash = OCP\Config::getUserValue($sUser, 'rainloop', 'rainloop-ssohash', '');
$a = OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password', null);
$b = OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-ssohash', null);
if('' !== $sSsoHash) {
self::clearUserSsoHash($sSsoHash);
}
return $a && $b;
}
public static function changePassword($params)
{
$sUser = $params['uid'];
$sEmail = $sUser;
$sPassword = $params['password'];
OCP\Util::writeLog('rainloop', 'rainloop|login: Setting new RainLoop password for '. $sEmail, OCP\Util::DEBUG);
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
if ('' !== $sUrl && '' !== $sPath)
{
$sPassword = self::encodePassword($sPassword, md5($sEmail));
return OCP\Config::setUserValue($sUser, 'rainloop', 'rainloop-password', $sPassword);
}
return false;
}
} }

View file

@ -16,8 +16,9 @@ OCP\Util::addScript('rainloop', 'personal');
$sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', '')); $sUrl = trim(OCP\Config::getAppValue('rainloop', 'rainloop-url', ''));
$sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', '')); $sPath = trim(OCP\Config::getAppValue('rainloop', 'rainloop-path', ''));
$bAutologin = OCP\Config::getAppValue('rainloop', 'rainloop-autologin', false);
if ('' === $sUrl || '' === $sPath) if ('on' === $bAutologin || '' === $sUrl || '' === $sPath)
{ {
$oTemplate = new OCP\Template('rainloop', 'empty'); $oTemplate = new OCP\Template('rainloop', 'empty');
} }

View file

@ -1,25 +1,28 @@
<div class="section"> <div class="section">
<form id="mail-rainloop-admin-form" action="#" method="post"> <form id="mail-rainloop-admin-form" action="#" method="post">
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken"> <input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
<input type="hidden" name="appname" value="rainloop"> <input type="hidden" name="appname" value="rainloop">
<fieldset class="personalblock"> <fieldset class="personalblock">
<h2><?php p($l->t('RainLoop Webmail')); ?></h2> <h2><?php p($l->t('RainLoop Webmail')); ?></h2>
<br /> <br />
<p> <p>
<?php p($l->t('RainLoop Webmail URL')); ?>: <?php p($l->t('RainLoop Webmail URL')); ?>:
<br /> <br />
<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('Absolute (full) path to RainLoop Webmail installation')); ?>: <?php p($l->t('Absolute (full) path to RainLoop Webmail installation')); ?>:
<br /> <br />
<input type="text" style="width:300px;" id="rainloop-path" name="rainloop-path" value="<?php echo $_['rainloop-path']; ?>" /> <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="checkbox" id="rainloop-autologin" name="rainloop-autologin" <?php if(true == $_['rainloop-autologin']): ?>checked="checked"<?php endif; ?> /><?php p($l->t('Automatically login with ownCloud user credentials')); ?>
&nbsp;&nbsp;<span class="rainloop-result-desc"></span> <br />
</p> <br />
</fieldset> <input type="button" id="rainloop-save-button" name="rainloop-save-button" value="<?php p($l->t('Save')); ?>" />
</form> &nbsp;&nbsp;<span class="rainloop-result-desc"></span>
</p>
</fieldset>
</form>
</div> </div>

0
build/owncloud/rainloop-app/templates/empty.php Normal file → Executable file
View file

0
build/owncloud/rainloop-app/templates/index-empty.php Normal file → Executable file
View file

4
build/owncloud/rainloop-app/templates/index.php Normal file → Executable file
View file

@ -1,3 +1,3 @@
<div style="box-sizing: border-box; width: 100%; height: 100%; padding: 0px; margin: 0px; background-color: #383c43; position: relative; overflow: hidden;" <div style="box-sizing: border-box; width: 100%; height: 100%; padding: 0px; margin: 0px; background-color: #383c43; position: relative; overflow: hidden;"
><iframe id="rliframe" style="border: none; width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px;" tabindex="-1" frameborder="0" ><iframe id="rliframe" style="border: none; width: 100%; height: 100%; position: absolute; top: 0px; left: 0px; right: 0px; bottom: 0px;" tabindex="-1" frameborder="0"
src="<?php echo $_['rainloop-url']; ?>"></iframe></div><?php OCP\Util::addScript('rainloop', 'resize'); src="<?php echo $_['rainloop-url']; ?>"></iframe></div><?php OCP\Util::addScript('rainloop', 'resize');

View file

@ -1,20 +1,20 @@
<div class="section"> <div class="section">
<form id="mail-rainloop-personal-form" action="#" method="post"> <form id="mail-rainloop-personal-form" action="#" method="post">
<input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken"> <input type="hidden" name="requesttoken" value="<?php echo $_['requesttoken'] ?>" id="requesttoken">
<input type="hidden" name="appname" value="rainloop"> <input type="hidden" name="appname" value="rainloop">
<fieldset class="personalblock"> <fieldset class="personalblock">
<h2><?php p($l->t('RainLoop Webmail')); ?></h2> <h2><?php p($l->t('RainLoop Webmail')); ?></h2>
<p> <p>
<input type="text" id="rainloop-email" name="rainloop-email" <input type="text" id="rainloop-email" name="rainloop-email"
value="<?php echo $_['rainloop-email']; ?>" placeholder="<?php p($l->t('Email')); ?>" /> value="<?php echo $_['rainloop-email']; ?>" placeholder="<?php p($l->t('Email')); ?>" />
<input type="password" id="rainloop-password" name="rainloop-password" <input type="password" id="rainloop-password" name="rainloop-password"
value="<?php echo $_['rainloop-password']; ?>" placeholder="<?php p($l->t('Password')); ?>" /> value="<?php echo $_['rainloop-password']; ?>" placeholder="<?php p($l->t('Password')); ?>" />
<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')); ?>" />
&nbsp;&nbsp;<span class="rainloop-result-desc"></span> &nbsp;&nbsp;<span class="rainloop-result-desc"></span>
</p> </p>
</fieldset> </fieldset>
</form> </form>
</div> </div>