From 9f777fba988422366732a3f128e2fb73ffddfbb4 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 25 Sep 2013 18:34:01 +0200 Subject: [PATCH 1/4] Add L10N interface to server container --- lib/l10n/factory.php | 34 +++++++++++++++++ lib/private/l10n.php | 18 +++------ lib/private/server.php | 12 ++++++ lib/public/il10n.php | 67 +++++++++++++++++++++++++++++++++ lib/public/iservercontainer.php | 7 ++++ 5 files changed, 125 insertions(+), 13 deletions(-) create mode 100644 lib/l10n/factory.php create mode 100644 lib/public/il10n.php diff --git a/lib/l10n/factory.php b/lib/l10n/factory.php new file mode 100644 index 0000000000..ba168872ac --- /dev/null +++ b/lib/l10n/factory.php @@ -0,0 +1,34 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC\L10N; + +/** + * TODO: Description + */ +class Factory { + /** + * cached instances + */ + protected $instances = array(); + + /** + * get an L10N instance + * @param $app string + * @param $lang string|null + * @return OC_L10N + */ + public function get($app) { + if (!isset($this->instances[$app])) { + $this->instances[$app] = new \OC_L10N($app); + } + return $this->instances[$app]; + } + +} diff --git a/lib/private/l10n.php b/lib/private/l10n.php index f93443b886..3e84c306dc 100644 --- a/lib/private/l10n.php +++ b/lib/private/l10n.php @@ -25,12 +25,7 @@ /** * This class is for i18n and l10n */ -class OC_L10N { - /** - * cached instances - */ - protected static $instances=array(); - +class OC_L10N implements \OCP\IL10N { /** * cache */ @@ -83,13 +78,10 @@ class OC_L10N { * @return OC_L10N */ public static function get($app, $lang=null) { - if(is_null($lang)) { - if(!isset(self::$instances[$app])) { - self::$instances[$app]=new OC_L10N($app); - } - return self::$instances[$app]; - }else{ - return new OC_L10N($app, $lang); + if (is_null($lang)) { + return OC::$server->getL10N($app); + } else { + return new \OC_L10N($app, $lang); } } diff --git a/lib/private/server.php b/lib/private/server.php index ef2007663c..e4cc0c6da8 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -102,6 +102,9 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('AllConfig', function($c) { return new \OC\AllConfig(); }); + $this->registerService('L10NFactory', function($c) { + return new \OC\L10N\Factory(); + }); $this->registerService('UserCache', function($c) { return new UserCache(); }); @@ -217,6 +220,15 @@ class Server extends SimpleContainer implements IServerContainer { return $this->query('AllConfig'); } + /** + * get an L10N instance + * @param $app string appid + * @return \OC_L10N + */ + function getL10N($app) { + return $this->query('L10NFactory')->get($app); + } + /** * Returns an ICache instance * diff --git a/lib/public/il10n.php b/lib/public/il10n.php new file mode 100644 index 0000000000..9cf9093d39 --- /dev/null +++ b/lib/public/il10n.php @@ -0,0 +1,67 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * TODO: Description + */ +interface IL10N { + /** + * @brief Translating + * @param $text String The text we need a translation for + * @param array $parameters default:array() Parameters for sprintf + * @return \OC_L10N_String|string Translation or the same text + * + * Returns the translation. If no translation is found, $text will be + * returned. + */ + public function t($text, $parameters = array()); + + /** + * @brief Translating + * @param $text_singular String the string to translate for exactly one object + * @param $text_plural String the string to translate for n objects + * @param $count Integer Number of objects + * @param array $parameters default:array() Parameters for sprintf + * @return \OC_L10N_String|string Translation or the same text + * + * Returns the translation. If no translation is found, $text will be + * returned. %n will be replaced with the number of objects. + * + * The correct plural is determined by the plural_forms-function + * provided by the po file. + * + */ + public function n($text_singular, $text_plural, $count, $parameters = array()); + + /** + * @brief Localization + * @param $type Type of localization + * @param $params parameters for this localization + * @returns String or false + * + * Returns the localized data. + * + * Implemented types: + * - date + * - Creates a date + * - l10n-field: date + * - params: timestamp (int/string) + * - datetime + * - Creates date and time + * - l10n-field: datetime + * - params: timestamp (int/string) + * - time + * - Creates a time + * - l10n-field: time + * - params: timestamp (int/string) + */ + public function l($type, $data); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index f4045faefe..e8bc1bedf9 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -101,6 +101,13 @@ interface IServerContainer { */ function getConfig(); + /** + * get an L10N instance + * @param $app string appid + * @return \OCP\IL10N + */ + function getL10N($app); + /** * Returns an ICache instance * From ce9436c0518d8ce522646dde33dbac141cc35c46 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Wed, 25 Sep 2013 18:34:50 +0200 Subject: [PATCH 2/4] OC_Defaults is only used in error reporting --- lib/private/config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/private/config.php b/lib/private/config.php index e773e6e2eb..72423137fa 100644 --- a/lib/private/config.php +++ b/lib/private/config.php @@ -160,7 +160,6 @@ class Config { */ private function writeData() { // Create a php file ... - $defaults = new \OC_Defaults; $content = "debugMode) { $content .= "define('DEBUG',true);\n"; @@ -172,6 +171,7 @@ class Config { // Write the file $result = @file_put_contents($this->configFilename, $content); if (!$result) { + $defaults = new \OC_Defaults; $url = $defaults->getDocBaseUrl() . '/server/5.0/admin_manual/installation/installation_source.html#set-the-directory-permissions'; throw new HintException( "Can't write into config directory!", From 61a9098b7d88656d0297a18c1b7685c04d1c64dc Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Thu, 26 Sep 2013 18:41:19 +0200 Subject: [PATCH 3/4] Add Helper and URLGenerator interfaces to server container --- lib/apphelper.php | 25 +++++++ lib/private/helper.php | 52 ++------------- lib/private/server.php | 20 ++++++ lib/private/util.php | 4 +- lib/public/ihelper.php | 23 +++++++ lib/public/iservercontainer.php | 10 +++ lib/public/iurlgenerator.php | 47 ++++++++++++++ lib/urlgenerator.php | 111 ++++++++++++++++++++++++++++++++ 8 files changed, 242 insertions(+), 50 deletions(-) create mode 100644 lib/apphelper.php create mode 100644 lib/public/ihelper.php create mode 100644 lib/public/iurlgenerator.php create mode 100644 lib/urlgenerator.php diff --git a/lib/apphelper.php b/lib/apphelper.php new file mode 100644 index 0000000000..bd02f3aabf --- /dev/null +++ b/lib/apphelper.php @@ -0,0 +1,25 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC; + +/** + * TODO: Description + */ +class AppHelper implements \OCP\IHelper { + /** + * Gets the content of an URL by using CURL or a fallback if it is not + * installed + * @param string $url the url that should be fetched + * @return string the content of the webpage + */ + public function getUrlContent($url) { + return \OC_Util::getUrlContent($url); + } +} diff --git a/lib/private/helper.php b/lib/private/helper.php index 66e7acb407..a34640d8e3 100644 --- a/lib/private/helper.php +++ b/lib/private/helper.php @@ -41,8 +41,7 @@ class OC_Helper { * Returns a url to the given app and file. */ public static function linkToRoute($route, $parameters = array()) { - $urlLinkTo = OC::getRouter()->generate($route, $parameters); - return $urlLinkTo; + return OC::$server->getURLGenerator()->linkToRoute($route, $parameters); } /** @@ -56,32 +55,7 @@ class OC_Helper { * Returns a url to the given app and file. */ public static function linkTo( $app, $file, $args = array() ) { - if( $app != '' ) { - $app_path = OC_App::getAppPath($app); - // Check if the app is in the app folder - if ($app_path && file_exists($app_path . '/' . $file)) { - if (substr($file, -3) == 'php' || substr($file, -3) == 'css') { - $urlLinkTo = OC::$WEBROOT . '/index.php/apps/' . $app; - $urlLinkTo .= ($file != 'index.php') ? '/' . $file : ''; - } else { - $urlLinkTo = OC_App::getAppWebPath($app) . '/' . $file; - } - } else { - $urlLinkTo = OC::$WEBROOT . '/' . $app . '/' . $file; - } - } else { - if (file_exists(OC::$SERVERROOT . '/core/' . $file)) { - $urlLinkTo = OC::$WEBROOT . '/core/' . $file; - } else { - $urlLinkTo = OC::$WEBROOT . '/' . $file; - } - } - - if ($args && $query = http_build_query($args, '', '&')) { - $urlLinkTo .= '?' . $query; - } - - return $urlLinkTo; + return OC::$server->getURLGenerator()->linkTo($app, $file, $args); } /** @@ -107,7 +81,7 @@ class OC_Helper { * Returns a absolute url to the given app and file. */ public static function makeURLAbsolute($url) { - return OC_Request::serverProtocol() . '://' . OC_Request::serverHost() . $url; + return OC::$server->getURLGenerator()->makeURLAbsolute($url); } /** @@ -156,25 +130,7 @@ class OC_Helper { * Returns the path to the image. */ public static function imagePath($app, $image) { - // Read the selected theme from the config file - $theme = OC_Util::getTheme(); - - // Check if the app is in the app folder - if (file_exists(OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image"; - } elseif (file_exists(OC_App::getAppPath($app) . "/img/$image")) { - return OC_App::getAppWebPath($app) . "/img/$image"; - } elseif (!empty($app) and file_exists(OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/$app/img/$image"; - } elseif (!empty($app) and file_exists(OC::$SERVERROOT . "/$app/img/$image")) { - return OC::$WEBROOT . "/$app/img/$image"; - } elseif (file_exists(OC::$SERVERROOT . "/themes/$theme/core/img/$image")) { - return OC::$WEBROOT . "/themes/$theme/core/img/$image"; - } elseif (file_exists(OC::$SERVERROOT . "/core/img/$image")) { - return OC::$WEBROOT . "/core/img/$image"; - } else { - throw new RuntimeException('image not found: image:' . $image . ' webroot:' . OC::$WEBROOT . ' serverroot:' . OC::$SERVERROOT); - } + return OC::$server->getURLGenerator()->imagePath($app, $image); } /** diff --git a/lib/private/server.php b/lib/private/server.php index e4cc0c6da8..4000f546a3 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -105,6 +105,12 @@ class Server extends SimpleContainer implements IServerContainer { $this->registerService('L10NFactory', function($c) { return new \OC\L10N\Factory(); }); + $this->registerService('URLGenerator', function($c) { + return new \OC\URLGenerator(); + }); + $this->registerService('AppHelper', function($c) { + return new \OC\AppHelper(); + }); $this->registerService('UserCache', function($c) { return new UserCache(); }); @@ -229,6 +235,20 @@ class Server extends SimpleContainer implements IServerContainer { return $this->query('L10NFactory')->get($app); } + /** + * @return \OC\URLGenerator + */ + function getURLGenerator() { + return $this->query('URLGenerator'); + } + + /** + * @return \OC\Helper + */ + function getHelper() { + return $this->query('AppHelper'); + } + /** * Returns an ICache instance * diff --git a/lib/private/util.php b/lib/private/util.php index ae9aef69b4..04a020ff00 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -982,9 +982,9 @@ class OC_Util { * @param string $url Url to get content * @return string of the response or false on error * This function get the content of a page via curl, if curl is enabled. - * If not, file_get_element is used. + * If not, file_get_contents is used. */ - public static function getUrlContent($url){ + public static function getUrlContent($url) { if (function_exists('curl_init')) { $curl = curl_init(); diff --git a/lib/public/ihelper.php b/lib/public/ihelper.php new file mode 100644 index 0000000000..fad02f7556 --- /dev/null +++ b/lib/public/ihelper.php @@ -0,0 +1,23 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * Functions that don't have any specific interface to place + */ +interface IHelper { + /** + * Gets the content of an URL by using CURL or a fallback if it is not + * installed + * @param string $url the url that should be fetched + * @return string the content of the webpage + */ + public function getUrlContent($url); +} diff --git a/lib/public/iservercontainer.php b/lib/public/iservercontainer.php index e8bc1bedf9..3afb2b6599 100644 --- a/lib/public/iservercontainer.php +++ b/lib/public/iservercontainer.php @@ -108,6 +108,16 @@ interface IServerContainer { */ function getL10N($app); + /** + * @return \OCP\IURLGenerator + */ + function getURLGenerator(); + + /** + * @return \OCP\IHelper + */ + function getHelper(); + /** * Returns an ICache instance * diff --git a/lib/public/iurlgenerator.php b/lib/public/iurlgenerator.php new file mode 100644 index 0000000000..4eb4c0f831 --- /dev/null +++ b/lib/public/iurlgenerator.php @@ -0,0 +1,47 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OCP; + +/** + * Class to generate URLs + */ +interface IURLGenerator { + /** + * Returns the URL for a route + * @param string $routeName the name of the route + * @param array $arguments an array with arguments which will be filled into the url + * @return string the url + */ + public function linkToRoute($routeName, $arguments = array()); + + /** + * Returns an URL for an image or file + * @param string $appName the name of the app + * @param string $file the name of the file + * @return string the url + */ + public function linkTo($appName, $file); + + /** + * Returns the link to an image, like linkTo but only with prepending img/ + * @param string $appName the name of the app + * @param string $file the name of the file + * @return string the url + */ + public function imagePath($appName, $file); + + + /** + * Makes an URL absolute + * @param string $url the url in the owncloud host + * @return string the absolute version of the url + */ + public function getAbsoluteURL($url); +} diff --git a/lib/urlgenerator.php b/lib/urlgenerator.php new file mode 100644 index 0000000000..1db4c36cc5 --- /dev/null +++ b/lib/urlgenerator.php @@ -0,0 +1,111 @@ + + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + * + */ + +namespace OC; + +/** + * Class to generate URLs + */ +class URLGenerator { + /** + * @brief Creates an url using a defined route + * @param $route + * @param array $parameters + * @return + * @internal param array $args with param=>value, will be appended to the returned url + * @returns the url + * + * Returns a url to the given app and file. + */ + public function linkToRoute($route, $parameters = array()) { + $urlLinkTo = \OC::getRouter()->generate($route, $parameters); + return $urlLinkTo; + } + + /** + * @brief Creates an url + * @param string $app app + * @param string $file file + * @param array $args array with param=>value, will be appended to the returned url + * The value of $args will be urlencoded + * @return string the url + * + * Returns a url to the given app and file. + */ + public function linkTo( $app, $file, $args = array() ) { + if( $app != '' ) { + $app_path = \OC_App::getAppPath($app); + // Check if the app is in the app folder + if ($app_path && file_exists($app_path . '/' . $file)) { + if (substr($file, -3) == 'php' || substr($file, -3) == 'css') { + $urlLinkTo = \OC::$WEBROOT . '/index.php/apps/' . $app; + $urlLinkTo .= ($file != 'index.php') ? '/' . $file : ''; + } else { + $urlLinkTo = \OC_App::getAppWebPath($app) . '/' . $file; + } + } else { + $urlLinkTo = \OC::$WEBROOT . '/' . $app . '/' . $file; + } + } else { + if (file_exists(\OC::$SERVERROOT . '/core/' . $file)) { + $urlLinkTo = \OC::$WEBROOT . '/core/' . $file; + } else { + $urlLinkTo = \OC::$WEBROOT . '/' . $file; + } + } + + if ($args && $query = http_build_query($args, '', '&')) { + $urlLinkTo .= '?' . $query; + } + + return $urlLinkTo; + } + + /** + * @brief Creates path to an image + * @param string $app app + * @param string $image image name + * @return string the url + * + * Returns the path to the image. + */ + public function imagePath($app, $image) { + // Read the selected theme from the config file + $theme = \OC_Util::getTheme(); + + // Check if the app is in the app folder + if (file_exists(\OC::$SERVERROOT . "/themes/$theme/apps/$app/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/apps/$app/img/$image"; + } elseif (file_exists(\OC_App::getAppPath($app) . "/img/$image")) { + return \OC_App::getAppWebPath($app) . "/img/$image"; + } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/themes/$theme/$app/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/$app/img/$image"; + } elseif (!empty($app) and file_exists(\OC::$SERVERROOT . "/$app/img/$image")) { + return \OC::$WEBROOT . "/$app/img/$image"; + } elseif (file_exists(\OC::$SERVERROOT . "/themes/$theme/core/img/$image")) { + return \OC::$WEBROOT . "/themes/$theme/core/img/$image"; + } elseif (file_exists(\OC::$SERVERROOT . "/core/img/$image")) { + return \OC::$WEBROOT . "/core/img/$image"; + } else { + throw new RuntimeException('image not found: image:' . $image . ' webroot:' . \OC::$WEBROOT . ' serverroot:' . \OC::$SERVERROOT); + } + } + + /** + * @brief Makes an $url absolute + * @param string $url the url + * @return string the absolute url + * + * Returns a absolute url to the given app and file. + */ + public function makeURLAbsolute($url) { + return \OC_Request::serverProtocol() . '://' . \OC_Request::serverHost() . $url; + } + +} From 21cbef0d2cc80228d2a473ccfb6ad5b071f314c7 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 27 Sep 2013 15:16:34 +0200 Subject: [PATCH 4/4] passesCSRFCheck added to OCP\IRequest --- lib/private/appframework/http/request.php | 38 +++++++++++++++++++++-- lib/private/server.php | 17 +++++++++- lib/private/util.php | 24 +------------- lib/public/irequest.php | 5 +++ 4 files changed, 57 insertions(+), 27 deletions(-) diff --git a/lib/private/appframework/http/request.php b/lib/private/appframework/http/request.php index f152956c8c..3e1f4ff87e 100644 --- a/lib/private/appframework/http/request.php +++ b/lib/private/appframework/http/request.php @@ -43,7 +43,8 @@ class Request implements \ArrayAccess, \Countable, IRequest { 'cookies', 'urlParams', 'parameters', - 'method' + 'method', + 'requesttoken', ); /** @@ -54,9 +55,9 @@ class Request implements \ArrayAccess, \Countable, IRequest { * @param array 'files' the $_FILES array * @param array 'server' the $_SERVER array * @param array 'env' the $_ENV array - * @param array 'session' the $_SESSION array * @param array 'cookies' the $_COOKIE array * @param string 'method' the request method (GET, POST etc) + * @param string|false 'requesttoken' the requesttoken or false when not available * @see http://www.php.net/manual/en/reserved.variables.php */ public function __construct(array $vars=array()) { @@ -354,4 +355,35 @@ class Request implements \ArrayAccess, \Countable, IRequest { return $this->content; } -} + + /** + * Checks if the CSRF check was correct + * @return bool true if CSRF check passed + * @see OC_Util::$callLifespan + * @see OC_Util::callRegister() + */ + public function passesCSRFCheck() { + if($this->items['requesttoken'] === false) { + return false; + } + + if (isset($this->items['get']['requesttoken'])) { + $token = $this->items['get']['requesttoken']; + } elseif (isset($this->items['post']['requesttoken'])) { + $token = $this->items['post']['requesttoken']; + } elseif (isset($this->items['server']['HTTP_REQUESTTOKEN'])) { + $token = $this->items['server']['HTTP_REQUESTTOKEN']; + } else { + //no token found. + return false; + } + + // Check if the token is valid + if($token !== $this->items['requesttoken']) { + // Not valid + return false; + } else { + // Valid token + return true; + } + }} diff --git a/lib/private/server.php b/lib/private/server.php index 4000f546a3..73a0cbd6ce 100644 --- a/lib/private/server.php +++ b/lib/private/server.php @@ -22,6 +22,19 @@ class Server extends SimpleContainer implements IServerContainer { return new ContactsManager(); }); $this->registerService('Request', function($c) { + if (isset($c['urlParams'])) { + $urlParams = $c['urlParams']; + } else { + $urlParams = array(); + } + + if (\OC::$session->exists('requesttoken')) { + $requesttoken = \OC::$session->get('requesttoken'); + } else { + $requesttoken = false; + } + + return new Request( array( 'get' => $_GET, @@ -33,7 +46,9 @@ class Server extends SimpleContainer implements IServerContainer { 'method' => (isset($_SERVER) && isset($_SERVER['REQUEST_METHOD'])) ? $_SERVER['REQUEST_METHOD'] : null, - 'urlParams' => $c['urlParams'] + 'params' => $params, + 'urlParams' => $urlParams, + 'requesttoken' => $requesttoken, ) ); }); diff --git a/lib/private/util.php b/lib/private/util.php index 04a020ff00..c5b4d2ae93 100755 --- a/lib/private/util.php +++ b/lib/private/util.php @@ -695,29 +695,7 @@ class OC_Util { * @see OC_Util::callRegister() */ public static function isCallRegistered() { - if(!\OC::$session->exists('requesttoken')) { - return false; - } - - if(isset($_GET['requesttoken'])) { - $token = $_GET['requesttoken']; - } elseif(isset($_POST['requesttoken'])) { - $token = $_POST['requesttoken']; - } elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) { - $token = $_SERVER['HTTP_REQUESTTOKEN']; - } else { - //no token found. - return false; - } - - // Check if the token is valid - if($token !== \OC::$session->get('requesttoken')) { - // Not valid - return false; - } else { - // Valid token - return true; - } + return \OC::$server->getRequest()->passesCSRFCheck(); } /** diff --git a/lib/public/irequest.php b/lib/public/irequest.php index 054f15d9eb..45b27868d7 100644 --- a/lib/public/irequest.php +++ b/lib/public/irequest.php @@ -107,4 +107,9 @@ interface IRequest { function getCookie($key); + /** + * Checks if the CSRF check was correct + * @return bool true if CSRF check passed + */ + public function passesCSRFCheck(); }