diff --git a/rainloop/admin.php b/rainloop/admin.php new file mode 100755 index 00000000..57cc3043 --- /dev/null +++ b/rainloop/admin.php @@ -0,0 +1,19 @@ +assign('rainloop-admin-panel-link', OC_RainLoop_Helper::getAppUrl().'?admin'); +$oTemplate->assign('rainloop-autologin', \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false)); +$oTemplate->assign('rainloop-autologin-with-email', \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin-with-email', false)); +return $oTemplate->fetchPage(); diff --git a/rainloop/ajax/admin.php b/rainloop/ajax/admin.php new file mode 100755 index 00000000..70e90b43 --- /dev/null +++ b/rainloop/ajax/admin.php @@ -0,0 +1,37 @@ +getConfig()->setAppValue('rainloop', 'rainloop-autologin', isset($_POST['rainloop-autologin']) ? + '1' === $_POST['rainloop-autologin'] : false); + \OC::$server->getConfig()->setAppValue('rainloop', 'rainloop-autologin-with-email', isset($_POST['rainloop-autologin']) ? + '2' === $_POST['rainloop-autologin'] : false); + + $bAutologin = \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false); +} +else +{ + sleep(1); + OC_JSON::error(array('Message' => 'Invalid Argument(s)')); + return false; +} + +sleep(1); +\OC_JSON::success(array('Message' => 'Saved successfully')); +return true; diff --git a/rainloop/ajax/personal.php b/rainloop/ajax/personal.php new file mode 100755 index 00000000..4805f8f4 --- /dev/null +++ b/rainloop/ajax/personal.php @@ -0,0 +1,46 @@ +getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-email', $sPostEmail); + + $sPass = $_POST['rainloop-password']; + if ('******' !== $sPass && '' !== $sPass) + { + include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; + + \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-password', + OC_RainLoop_Helper::encodePassword($sPass, md5($sPostEmail))); + } + + $sEmail = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); +} +else +{ + sleep(1); + OC_JSON::error(array('Message' => 'Invalid argument(s)', 'Email' => $sEmail)); + return false; +} + +sleep(1); +\OC_JSON::success(array('Message' => 'Saved successfully', 'Email' => $sEmail)); +return true; diff --git a/rainloop/app.php b/rainloop/app.php new file mode 100755 index 00000000..cd737b7f --- /dev/null +++ b/rainloop/app.php @@ -0,0 +1,68 @@ +getContentSecurityPolicyNonceManager()->getNonce().'\'; ' + . 'style-src \'self\' \'unsafe-inline\'; ' + . 'frame-src *; ' + . 'img-src * data: blob:; ' + . 'font-src \'self\' data:; ' + . 'media-src *; ' + . 'connect-src *; ' + . 'object-src \'self\'; ' + . 'base-uri \'self\'; '; +header('Content-Security-Policy:' . $policy); + +if (@file_exists(__DIR__.'/app/index.php')) +{ + include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; + + OC_RainLoop_Helper::regRainLoopDataFunction(); + + if (isset($_GET['OwnCloudAuth'])) + { + $sEmail = ''; + $sEncodedPassword = ''; + + $sUser = OCP\User::getUser(); + $sPasswordSalt = ''; + + if (\OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false)) + { + $sEmail = $sUser; + $sPasswordSalt = $sUser; + $sEncodedPassword = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); + } + else if (\OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin-with-email', false)) + { + $sEmail = \OC::$server->getConfig()->getUserValue($sUser, 'settings', 'email',''); + $sPasswordSalt = $sUser; + $sEncodedPassword = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); + } + $sIndividualEmail = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); + if (!empty($sIndividualEmail)) + { + $sEmail = $sIndividualEmail; + $sPasswordSalt = $sEmail; + $sEncodedPassword = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-password', ''); + } + + $sDecodedPassword = OC_RainLoop_Helper::decodePassword($sEncodedPassword, md5($sPasswordSalt)); + + $_ENV['___rainloop_owncloud_email'] = $sEmail; + $_ENV['___rainloop_owncloud_password'] = $sDecodedPassword; + } + + include __DIR__.'/app/index.php'; +} diff --git a/rainloop/app/rainloop/v/1.14.0/app/libraries/RainLoop/Utils.php b/rainloop/app/rainloop/v/1.14.0/app/libraries/RainLoop/Utils.php index 4adbb99f..ceb7f687 100644 --- a/rainloop/app/rainloop/v/1.14.0/app/libraries/RainLoop/Utils.php +++ b/rainloop/app/rainloop/v/1.14.0/app/libraries/RainLoop/Utils.php @@ -540,7 +540,7 @@ public static function IsOwnCloud() */ public static function IsOwnCloudLoggedIn() { - return self::IsOwnCloud() && \OC::$server->getUserSession()->isLoggedIn(); + return self::IsOwnCloud() && \class_exists('OCP\User') && \OCP\User::isLoggedIn(); } /** @@ -562,10 +562,10 @@ public static function WebPath() $sAppPath = ''; if (\RainLoop\Utils::IsOwnCloud()) { - $sAppPath = \OC::$server->getURLGenerator()->linkToRoute('rainloop.page.appGet'); - // TODO: Fix this ugly hack. Is there a "modern" way to return - // a URL that doesn't include index.php, which breaks things? - $sAppPath = preg_replace('index\.php\/', '', $sAppPath); + if (\class_exists('OC_App')) + { + $sAppPath = \rtrim(\trim(\OC_App::getAppWebPath('rainloop')), '\\/').'/app/'; + } if (empty($sAppPath)) { @@ -687,4 +687,4 @@ public static function CustomBaseConvert($sNumberInput, $sFromBaseInput = '01234 return $mRetVal; } -} +} \ No newline at end of file diff --git a/rainloop/appinfo/app.php b/rainloop/appinfo/app.php index dc7b1b7e..eaed3904 100644 --- a/rainloop/appinfo/app.php +++ b/rainloop/appinfo/app.php @@ -8,6 +8,25 @@ * Based initially on https://github.com/RainLoop/rainloop-webmail/tree/master/build/owncloud */ -$app = new OCA\RainLoop\AppInfo\Application(); -$app->registerNavigation(); -$app->getContainer()->query('RainLoopHelper')->registerHooks(); +OC::$CLASSPATH['OC_RainLoop_Helper'] = OC_App::getAppPath('rainloop') . '/lib/RainLoopHelper.php'; + +OCP\App::registerAdmin('rainloop', 'admin'); +OCP\App::registerPersonal('rainloop', 'personal'); + +if (\OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin', false) || \OC::$server->getConfig()->getAppValue('rainloop', 'rainloop-autologin-with-email', false)) +{ + OCP\Util::connectHook('OC_User', 'post_login', 'OC_RainLoop_Helper', 'login'); + OCP\Util::connectHook('OC_User', 'post_setPassword', 'OC_RainLoop_Helper', 'changePassword'); +} + +OCP\Util::connectHook('OC_User', 'logout', 'OC_RainLoop_Helper', 'logout'); + +OCP\Util::addScript('rainloop', 'rainloop'); + +\OC::$server->getNavigationManager()->add(array( + 'id' => 'rainloop_index', + 'order' => 10, + 'href' => OC::$server->getURLGenerator()->linkToRoute('rainloop_index'), + 'icon' => OC::$server->getURLGenerator()->imagePath('rainloop', 'mail.png'), + 'name' => \OCP\Util::getL10N('rainloop')->t('Email') +)); diff --git a/rainloop/appinfo/info.xml b/rainloop/appinfo/info.xml index 4ab1741f..15fe3438 100644 --- a/rainloop/appinfo/info.xml +++ b/rainloop/appinfo/info.xml @@ -7,20 +7,18 @@ 6.1.0 agpl RainLoop Team, Nextgen-Networks, Tab Fitts, Pierre-Alain Bandinelli - RainLoop + + + + + https://github.com/pierre-alain-b/rainloop-nextcloud/blob/master/README.md https://www.rainloop.net/ social - tools - https://raw.githubusercontent.com/pierre-alain-b/rainloop-nextcloud/master/screenshots/2016.10.20-screenshot.jpg + tools + https://raw.githubusercontent.com/pierre-alain-b/rainloop-nextcloud/master/screenshots/2016.10.20-screenshot.jpg https://github.com/pierre-alain-b/rainloop-nextcloud https://github.com/pierre-alain-b/rainloop-nextcloud/issues - https://raw.githubusercontent.com/pierre-alain-b/rainloop-nextcloud/master/screenshots/2016.10.20-screenshot.jpg - - - - - diff --git a/rainloop/appinfo/routes.php b/rainloop/appinfo/routes.php index ad187ee1..1cf56c56 100755 --- a/rainloop/appinfo/routes.php +++ b/rainloop/appinfo/routes.php @@ -1,31 +1,13 @@ - [ - [ - 'name' => 'page#index', - 'url' => '/', - 'verb' => 'GET' - ], - [ - 'name' => 'page#appGet', - 'url' => '/app/', - 'verb' => 'GET' - ], - [ - 'name' => 'page#appPost', - 'url' => '/app/', - 'verb' => 'POST' - ], - [ - 'name' => 'ajax#setPersonal', - 'url' => '/ajax/personal.php', - 'verb' => 'POST' - ], - [ - 'name' => 'ajax#setAdmin', - 'url' => '/ajax/admin.php', - 'verb' => 'POST' - ] - ] -]; \ No newline at end of file +create('rainloop_index', '/apps/rainloop/') + ->actionInclude('rainloop/index.php'); + +$this->create('rainloop_app', '/app/') + ->actionInclude('rainloop/app.php'); + +$this->create('rainloop_ajax_personal', 'ajax/personal.php') + ->actionInclude('rainloop/ajax/personal.php'); + +$this->create('rainloop_ajax_admin', 'ajax/admin.php') + ->actionInclude('rainloop/ajax/admin.php'); diff --git a/rainloop/index.php b/rainloop/index.php new file mode 100755 index 00000000..8919c8af --- /dev/null +++ b/rainloop/index.php @@ -0,0 +1,25 @@ +getNavigationManager()->setActiveEntry('rainloop_index'); + +// Load the empty file ../css/style.css, that's needed to allow theming of +// the ownCloud header and navigation if rainloop is the active app. +OCP\Util::addStyle('rainloop', 'style'); + +include_once OC_App::getAppPath('rainloop').'/lib/RainLoopHelper.php'; + +$sUrl = OC_RainLoop_Helper::normalizeUrl(OC_RainLoop_Helper::getAppUrl()); + +$oTemplate = new OCP\Template('rainloop', 'index', 'user'); +$oTemplate->assign('rainloop-iframe-url', OC_RainLoop_Helper::normalizeUrl($sUrl).'?OwnCloudAuth'); + +$oTemplate->printpage(); diff --git a/rainloop/lib/AppInfo/Application.php b/rainloop/lib/AppInfo/Application.php deleted file mode 100644 index 03453e50..00000000 --- a/rainloop/lib/AppInfo/Application.php +++ /dev/null @@ -1,67 +0,0 @@ -getContainer(); - $server = $container->getServer(); - $config = $server->getConfig(); - - /** - * Controllers - */ - $container->registerService( - 'PageController', function($c) { - return new PageController( - $c->query('AppName'), - $c->query('Request'), - $c->getServer()->getAppManager(), - $c->query('ServerContainer')->getConfig() - ); - } - ); - - /** - * Utils - */ - $container->registerService( - 'RainLoopHelper', function($c) { - return new RainLoopHelper( - $c->getServer()->getConfig(), - $c->getServer()->getUserSession(), - $c->getServer()->getAppManager() - ); - } - ); - - // Add script js/rainloop.js - \OCP\Util::addScript('rainloop', 'rainloop'); - } - - public function registerNavigation() { - $container = $this->getContainer(); - - $container->query('OCP\INavigationManager')->add(function () use ($container) { - $urlGenerator = $container->query('OCP\IURLGenerator'); - return [ - 'id' => 'rainloop', - 'order' => 10, - 'href' => $urlGenerator->linkToRoute('rainloop.page.index'), - 'icon' => $urlGenerator->imagePath('rainloop', 'mail.png'), - 'name' => 'Email' - ]; - }); - } - -} - diff --git a/rainloop/lib/Controller/AjaxController.php b/rainloop/lib/Controller/AjaxController.php deleted file mode 100644 index 5850af90..00000000 --- a/rainloop/lib/Controller/AjaxController.php +++ /dev/null @@ -1,95 +0,0 @@ - 'error', - 'data' => [ - 'message' => 'Invalid Argument(s)' - ] - ]); - } - - return new JSONResponse([ - 'status' => 'success', - 'data' => [ - 'message' => 'Saved successfully' - ] - ]); - } catch (Exception $e) { - return new JSONResponse([ - 'status' => 'error', - 'data' => [ - 'message' => $e->getMessage() - ] - ]); - } - } - - public function setPersonal(): JSONResponse { - try { - - if (isset($_POST['appname'], $_POST['rainloop-password'], $_POST['rainloop-email']) && 'rainloop' === $_POST['appname']) { - $sUser = \OC::$server->getUserSession()->getUser()->getUID(); - - $sPostEmail = $_POST['rainloop-email']; - OCP\IConfig::setUserValue($sUser, 'rainloop', 'rainloop-email', $sPostEmail); - - $sPass = $_POST['rainloop-password']; - if ('******' !== $sPass && '' !== $sPass) { - include_once OCP\App\IAppManager::getAppPath('rainloop').'/lib/RainLoopHelper.php' - - OCP\IConfig::setUserValue($sUser, 'rainloop', 'rainloop-password', - OC_RainLoop_Helper::encodePassword($sPass, md5($sPostEmail))); - } - - $sEmail = OCP\IConfig::getUserValue($sUser, 'rainloop', 'rainloop-email', ''); - } else { - return new JSONResponse([ - 'status' => 'error', - 'data' => [ - 'message' => 'Invalid argument(s)', - 'email' => $sEmail - ] - ]); - } - - return new JSONResponse([ - 'status' => 'success', - 'data' => [ - 'message' => 'Saved successfully', - 'email' => $sEmail - ] - ]); - } catch (Exception $e) { - return new JSONResponse([ - 'status' => 'error', - 'data' => [ - 'message' => $e->getMessage() - ] - ]); - } - } -} - diff --git a/rainloop/lib/Controller/PageController.php b/rainloop/lib/Controller/PageController.php deleted file mode 100644 index d574d4d1..00000000 --- a/rainloop/lib/Controller/PageController.php +++ /dev/null @@ -1,99 +0,0 @@ -appPath = $appManager->getAppPath('rainloop'); - $this->config = $config; - $this->appManager = $appManager; - } - - /** - * @NoAdminRequired - * @NoCSRFRequired - */ - public function index() { - \OC::$server->getNavigationManager()->setActiveEntry('rainloop'); - - \OCP\Util::addStyle('rainloop', 'style'); - - $sUrl = RainLoopHelper::normalizeUrl(RainLoopHelper::getAppUrl()); - - $params = [ - 'rainloop-iframe-url' => RainLoopHelper::normalizeUrl($sUrl).'?OwnCloudAuth' - ]; - - $response = new TemplateResponse('rainloop', 'index', $params); - - return $response; - } - - /** - * @NoAdminRequired - * @NoCSRFRequired - */ - public function appGet() { - $this->app(); - } - - /** - * @NoAdminRequired - * @NoCSRFRequired - */ - public function appPost() { - $this->app(); - } - - public function app() { - - $csp = new ContentSecurityPolicy(); - // fixes object-src: 'none' which blocks chrome from preview pdf - $csp->addAllowedObjectDomain("'self'"); - - $response = new TemplateResponse('rainloop', 'app'); - $response->setContentSecurityPolicy($csp); - - RainLoopHelper::regRainLoopDataFunction(); - - if (isset($_GET['OwnCloudAuth'])) { - $sEmail = ''; - $sEncodedPassword = ''; - - $sUser = \OC::$server->getUserSession()->getUser()->getUID(); - - if ($this->config->getAppValue('rainloop', 'rainloop-autologin', false)) { - $sEmail = $sUser; - $sEncodedPassword = $this->config->getUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); - } else { - $sEmail = $this->config->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); - $sEncodedPassword = $this->config->getUserValue($sUser, 'rainloop', 'rainloop-password', ''); - } - - $sDecodedPassword = RainLoopHelper::decodePassword($sEncodedPassword, md5($sEmail)); - - $_ENV['___rainloop_owncloud_email'] = $sEmail; - $_ENV['___rainloop_owncloud_password'] = $sDecodedPassword; - } - - include $this->appPath . '/app/index.php'; - - return $response; - } - -} diff --git a/rainloop/lib/Util/RainLoopHelper.php b/rainloop/lib/RainLoopHelper.php old mode 100644 new mode 100755 similarity index 72% rename from rainloop/lib/Util/RainLoopHelper.php rename to rainloop/lib/RainLoopHelper.php index fe3baba0..bc55cec1 --- a/rainloop/lib/Util/RainLoopHelper.php +++ b/rainloop/lib/RainLoopHelper.php @@ -1,350 +1,347 @@ -appManager = $appManager; - $this->config = $config; - $this->userSession = $userSession; - } - - public function registerHooks() { - $this->userSession->listen('\OC\User', 'postLogin', function($user, $password) { - $this->login($user, $password, $this->config); - }); - - $this->userSession->listen('\OC\User', 'logout', function() { - $this->logout($this->appManager, $this->config, $this->userSession); - }); - - $this->userSession->listen('\OC\User', 'postSetPassword', function($user, $password) { - $this->changePassword($user, $password, $this->config); - }); - } - - /** - * @return string - */ - public static function getAppUrl() - { - $sRequestUri = \OC::$server->getURLGenerator()->linkToRoute('rainloop.page.appGet'); - if ($sRequestUri) - { - return $sRequestUri; - } - - $sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': trim($_SERVER['REQUEST_URI']); - $sRequestUri = preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri); - $sRequestUri = $sRequestUri.'apps/rainloop/app/'; - - return '/'.ltrim($sRequestUri, '/\\'); - } - - /** - * @param string $sPath - * @param string $sEmail - * @param string $sPassword - * - * @return string - */ - public static function getSsoHash($sPath, $sEmail, $sPassword) - { - $SsoHash = ''; - - $sPath = rtrim(trim($sPath), '\\/').'/index.php'; - if (file_exists($sPath)) - { - self::regRainLoopDataFunction(); - - $_ENV['RAINLOOP_INCLUDE_AS_API'] = true; - include $sPath; - - if (class_exists('\\RainLoop\\Api')) - { - $SsoHash = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword); - } - } - - return $SsoHash; - } - - /** - * @param string $sUrl - * - * @return string - */ - public static function normalizeUrl($sUrl) - { - $sUrl = rtrim(trim($sUrl), '/\\'); - if ('.php' !== strtolower(substr($sUrl, -4))) - { - $sUrl .= '/'; - } - - return $sUrl; - } - - /** - * @return boolean - */ - public static function mcryptSupported() - { - return function_exists('mcrypt_encrypt') && - function_exists('mcrypt_decrypt') && - defined('MCRYPT_RIJNDAEL_256') && - defined('MCRYPT_MODE_ECB'); - } - - /** - * @return string - */ - public static function openSslSupportedMethod() - { - $method = 'AES-256-CBC'; - return 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()) ? $method : ''; - } - - /** - * @param string $sMethod - * @param string $sPassword - * @param string $sSalt - * - * @return string - */ - public static function encodePasswordSsl($sMethod, $sPassword, $sSalt) - { - $sData = base64_encode($sPassword); - - $iv = @openssl_random_pseudo_bytes(openssl_cipher_iv_length($sMethod)); - $r = @openssl_encrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv); - - return @base64_encode(base64_encode($r).'|'.base64_encode($iv)); - } - - /** - * @param string $sMethod - * @param string $sPassword - * @param string $sSalt - * - * @return string - */ - public static function decodePasswordSsl($sMethod, $sPassword, $sSalt) - { - $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, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv) - )); - } - - return ''; - } - - /** - * @param string $sPassword - * @param string $sSalt - * - * @return string - */ - public static function encodePassword($sPassword, $sSalt) - { - $method = self::openSslSupportedMethod(); - if ($method) - { - return self::encodePasswordSsl($method, $sPassword, $sSalt); - } - else if (self::mcryptSupported()) - { - return @trim(base64_encode( - @mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_encode($sPassword), MCRYPT_MODE_ECB) - )); - } - - return @trim(base64_encode($sPassword)); - } - - /** - * @param string $sPassword - * @param string $sSalt - * - * @return string - */ - public static function decodePassword($sPassword, $sSalt) - { - $method = self::openSslSupportedMethod(); - if ($method) - { - return self::decodePasswordSsl($method, $sPassword, $sSalt); - } - else if (self::mcryptSupported()) - { - return @base64_decode(trim( - @mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_decode(trim($sPassword)), MCRYPT_MODE_ECB) - )); - } - - return @base64_decode(trim($sPassword)); - } - - /** - * @param array $aParams - * - * @return boolean - */ - public static function login($user, $password, $config) - { - $sUser = $user->getUID(); - - $sEmail = $sUser; - $sPassword = $password; - $sEncodedPassword = self::encodePassword($sPassword, md5($sEmail)); - - return $config->setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', $sEncodedPassword); - } - - public static function logout($appManager, $config, $userSession) - { - $sUser = $userSession->getUser()->getUID(); - $config->setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', ''); - - $sApiPath = $appManager->getAppPath('rainloop') . '/app/index.php'; - - self::regRainLoopDataFunction(); - - $_ENV['RAINLOOP_INCLUDE_AS_API'] = true; - include $sApiPath; - - \RainLoop\Api::LogoutCurrentLogginedUser(); - - return true; - } - - public static function changePassword($user, $password, $config) - { - $sUser = $user->getUID(); - $sPassword = $password; - - $config->setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', - self::encodePassword($sPassword, md5($sUser))); - - $config->setUserValue($sUser, 'rainloop', 'rainloop-password', - self::encodePassword($sPassword, md5($sUser))); - - return true; - } - - public static function regRainLoopDataFunction() - { - if (!@function_exists('__get_custom_data_full_path')) - { - $_ENV['RAINLOOP_OWNCLOUD'] = true; - - function __get_custom_data_full_path() - { - $sData = rtrim(trim(OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/'; - return @is_dir($sData) ? $sData.'rainloop-storage' : ''; - } - } - } - - public static function mimeContentType($filename) { - - $mime_types = array( - - 'woff' => 'application/font-woff', - - 'txt' => 'text/plain', - 'htm' => 'text/html', - 'html' => 'text/html', - 'php' => 'text/html', - 'css' => 'text/css', - 'js' => 'application/javascript', - 'json' => 'application/json', - 'xml' => 'application/xml', - 'swf' => 'application/x-shockwave-flash', - 'flv' => 'video/x-flv', - - // images - 'png' => 'image/png', - 'jpe' => 'image/jpeg', - 'jpeg' => 'image/jpeg', - 'jpg' => 'image/jpeg', - 'gif' => 'image/gif', - 'bmp' => 'image/bmp', - 'ico' => 'image/vnd.microsoft.icon', - 'tiff' => 'image/tiff', - 'tif' => 'image/tiff', - 'svg' => 'image/svg+xml', - 'svgz' => 'image/svg+xml', - - // archives - 'zip' => 'application/zip', - 'rar' => 'application/x-rar-compressed', - 'exe' => 'application/x-msdownload', - 'msi' => 'application/x-msdownload', - 'cab' => 'application/vnd.ms-cab-compressed', - - // audio/video - 'mp3' => 'audio/mpeg', - 'qt' => 'video/quicktime', - 'mov' => 'video/quicktime', - - // adobe - 'pdf' => 'application/pdf', - 'psd' => 'image/vnd.adobe.photoshop', - 'ai' => 'application/postscript', - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - - // ms office - 'doc' => 'application/msword', - 'rtf' => 'application/rtf', - 'xls' => 'application/vnd.ms-excel', - 'ppt' => 'application/vnd.ms-powerpoint', - - // open office - 'odt' => 'application/vnd.oasis.opendocument.text', - 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', - ); - - if (0 < strpos($filename, '.')) - { - $ext = strtolower(array_pop(explode('.',$filename))); - if (array_key_exists($ext, $mime_types)) - { - return $mime_types[$ext]; - } - else if (function_exists('finfo_open')) - { - $finfo = finfo_open(FILEINFO_MIME); - $mimetype = finfo_file($finfo, $filename); - finfo_close($finfo); - return $mimetype; - } - } - - return 'application/octet-stream'; - } -} +getURLGenerator()->linkToRoute('rainloop_app'); + } + + $sRequestUri = empty($_SERVER['REQUEST_URI']) ? '': trim($_SERVER['REQUEST_URI']); + $sRequestUri = preg_replace('/index.php\/.+$/', 'index.php/', $sRequestUri); + $sRequestUri = $sRequestUri.'apps/rainloop/app/'; + + return '/'.ltrim($sRequestUri, '/\\'); + } + + /** + * @param string $sPath + * @param string $sEmail + * @param string $sPassword + * + * @return string + */ + public static function getSsoHash($sPath, $sEmail, $sPassword) + { + $SsoHash = ''; + + $sPath = rtrim(trim($sPath), '\\/').'/index.php'; + if (file_exists($sPath)) + { + self::regRainLoopDataFunction(); + + $_ENV['RAINLOOP_INCLUDE_AS_API'] = true; + include $sPath; + + if (class_exists('\\RainLoop\\Api')) + { + $SsoHash = \RainLoop\Api::GetUserSsoHash($sEmail, $sPassword); + } + } + + return $SsoHash; + } + + /** + * @param string $sUrl + * + * @return string + */ + public static function normalizeUrl($sUrl) + { + $sUrl = rtrim(trim($sUrl), '/\\'); + if ('.php' !== strtolower(substr($sUrl, -4))) + { + $sUrl .= '/'; + } + + return $sUrl; + } + + /** + * @return boolean + */ + public static function mcryptSupported() + { + return function_exists('mcrypt_encrypt') && + function_exists('mcrypt_decrypt') && + defined('MCRYPT_RIJNDAEL_256') && + defined('MCRYPT_MODE_ECB'); + } + + /** + * @return string + */ + public static function openSslSupportedMethod() + { + $method = 'AES-256-CBC'; + return 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()) ? $method : ''; + } + + /** + * @param string $sMethod + * @param string $sPassword + * @param string $sSalt + * + * @return string + */ + public static function encodePasswordSsl($sMethod, $sPassword, $sSalt) + { + $sData = base64_encode($sPassword); + + $iv = @openssl_random_pseudo_bytes(openssl_cipher_iv_length($sMethod)); + $r = @openssl_encrypt($sData, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv); + + return @base64_encode(base64_encode($r).'|'.base64_encode($iv)); + } + + /** + * @param string $sMethod + * @param string $sPassword + * @param string $sSalt + * + * @return string + */ + public static function decodePasswordSsl($sMethod, $sPassword, $sSalt) + { + $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, $sMethod, md5($sSalt), OPENSSL_RAW_DATA, $iv) + )); + } + + return ''; + } + + /** + * @param string $sPassword + * @param string $sSalt + * + * @return string + */ + public static function encodePassword($sPassword, $sSalt) + { + $method = self::openSslSupportedMethod(); + if ($method) + { + return self::encodePasswordSsl($method, $sPassword, $sSalt); + } + else if (self::mcryptSupported()) + { + return @trim(base64_encode( + @mcrypt_encrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_encode($sPassword), MCRYPT_MODE_ECB) + )); + } + + return @trim(base64_encode($sPassword)); + } + + /** + * @param string $sPassword + * @param string $sSalt + * + * @return string + */ + public static function decodePassword($sPassword, $sSalt) + { + $method = self::openSslSupportedMethod(); + if ($method) + { + return self::decodePasswordSsl($method, $sPassword, $sSalt); + } + else if (self::mcryptSupported()) + { + return @base64_decode(trim( + @mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($sSalt), base64_decode(trim($sPassword)), MCRYPT_MODE_ECB) + )); + } + + return @base64_decode(trim($sPassword)); + } + + /** + * @param array $aParams + * + * @return boolean + */ + public static function login($aParams) + { + if (isset($aParams['uid'], $aParams['password'])) + { + $sUser = $aParams['uid']; + + $sEmail = $sUser; + $sPassword = $aParams['password']; + + return \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', + self::encodePassword($sPassword, md5($sEmail))); + } + + return false; + } + + public static function logout() + { + \OC::$server->getConfig()->setUserValue( + OCP\User::getUser(), 'rainloop', 'rainloop-autologin-password', ''); + + $sApiPath = __DIR__.'/../app/index.php'; + if (file_exists($sApiPath)) + { + self::regRainLoopDataFunction(); + + $_ENV['RAINLOOP_INCLUDE_AS_API'] = true; + include $sApiPath; + + if (class_exists('\\RainLoop\\Api')) + { + \RainLoop\Api::LogoutCurrentLogginedUser(); + } + } + + return true; + } + + public static function changePassword($aParams) + { + if (isset($aParams['uid'], $aParams['password'])) + { + $sUser = $aParams['uid']; + + $sEmail = $sUser; + $sPassword = $aParams['password']; + + OCP\Util::writeLog('rainloop', 'rainloop|login: Setting new RainLoop password for '.$sEmail, OCP\Util::DEBUG); + + \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-autologin-password', + self::encodePassword($sPassword, md5($sEmail))); + + \OC::$server->getConfig()->setUserValue($sUser, 'rainloop', 'rainloop-password', + self::encodePassword($sPassword, md5($sEmail))); + + return true; + } + + return false; + } + + public static function regRainLoopDataFunction() + { + if (!@function_exists('__get_custom_data_full_path')) + { + $_ENV['RAINLOOP_OWNCLOUD'] = true; + + function __get_custom_data_full_path() + { + $sData = __DIR__.'/../../data/'; + if (class_exists('OC_Config')) + { + $sData = rtrim(trim(OC_Config::getValue('datadirectory', '')), '\\/').'/'; + } + else if (class_exists('OC')) + { + $sData = rtrim(trim(OC::$server->getSystemConfig()->getValue('datadirectory', '')), '\\/').'/'; + } + + return @is_dir($sData) ? $sData.'rainloop-storage' : ''; + } + } + } + + public static function mimeContentType($filename) { + + $mime_types = array( + + 'woff' => 'application/font-woff', + + 'txt' => 'text/plain', + 'htm' => 'text/html', + 'html' => 'text/html', + 'php' => 'text/html', + 'css' => 'text/css', + 'js' => 'application/javascript', + 'json' => 'application/json', + 'xml' => 'application/xml', + 'swf' => 'application/x-shockwave-flash', + 'flv' => 'video/x-flv', + + // images + 'png' => 'image/png', + 'jpe' => 'image/jpeg', + 'jpeg' => 'image/jpeg', + 'jpg' => 'image/jpeg', + 'gif' => 'image/gif', + 'bmp' => 'image/bmp', + 'ico' => 'image/vnd.microsoft.icon', + 'tiff' => 'image/tiff', + 'tif' => 'image/tiff', + 'svg' => 'image/svg+xml', + 'svgz' => 'image/svg+xml', + + // archives + 'zip' => 'application/zip', + 'rar' => 'application/x-rar-compressed', + 'exe' => 'application/x-msdownload', + 'msi' => 'application/x-msdownload', + 'cab' => 'application/vnd.ms-cab-compressed', + + // audio/video + 'mp3' => 'audio/mpeg', + 'qt' => 'video/quicktime', + 'mov' => 'video/quicktime', + + // adobe + 'pdf' => 'application/pdf', + 'psd' => 'image/vnd.adobe.photoshop', + 'ai' => 'application/postscript', + 'eps' => 'application/postscript', + 'ps' => 'application/postscript', + + // ms office + 'doc' => 'application/msword', + 'rtf' => 'application/rtf', + 'xls' => 'application/vnd.ms-excel', + 'ppt' => 'application/vnd.ms-powerpoint', + + // open office + 'odt' => 'application/vnd.oasis.opendocument.text', + 'ods' => 'application/vnd.oasis.opendocument.spreadsheet', + ); + + if (0 < strpos($filename, '.')) + { + $ext = strtolower(array_pop(explode('.',$filename))); + if (array_key_exists($ext, $mime_types)) + { + return $mime_types[$ext]; + } + else if (function_exists('finfo_open')) + { + $finfo = finfo_open(FILEINFO_MIME); + $mimetype = finfo_file($finfo, $filename); + finfo_close($finfo); + return $mimetype; + } + } + + return 'application/octet-stream'; + } +} diff --git a/rainloop/personal.php b/rainloop/personal.php new file mode 100755 index 00000000..79c0ed43 --- /dev/null +++ b/rainloop/personal.php @@ -0,0 +1,32 @@ +getConfig()->getAppValue('rainloop', 'rainloop-autologin', false)) +{ + $oTemplate = new OCP\Template('rainloop', 'empty'); +} +else +{ + $sUser = OCP\User::getUser(); + + $oTemplate = new OCP\Template('rainloop', 'personal'); + + $sEmail = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-email', ''); + $sPass = \OC::$server->getConfig()->getUserValue($sUser, 'rainloop', 'rainloop-password', ''); + + $oTemplate->assign('rainloop-email', $sEmail); + $oTemplate->assign('rainloop-password', 0 === strlen($sPass) && 0 === strlen($sEmail) ? '' : '******'); +} + +return $oTemplate->fetchPage(); diff --git a/rainloop/templates/app.php b/rainloop/templates/app.php deleted file mode 100644 index 84140d54..00000000 --- a/rainloop/templates/app.php +++ /dev/null @@ -1 +0,0 @@ -