From 9c5416fe4a12acf5631b8822feb942143bf2408f Mon Sep 17 00:00:00 2001 From: kondou Date: Thu, 15 Aug 2013 08:49:19 +0200 Subject: [PATCH 001/169] Clean up \OC\Util - Use camelCase - Add some phpdoc - Fix some indents - Use some more spacing --- core/lostpassword/controller.php | 2 +- core/minimizer.php | 4 +- core/setup.php | 4 +- lib/app.php | 8 +- lib/base.php | 8 +- lib/public/share.php | 2 +- lib/setup.php | 2 +- lib/setup/mysql.php | 2 +- lib/setup/oci.php | 2 +- lib/setup/postgresql.php | 2 +- lib/templatelayout.php | 4 +- lib/user.php | 2 +- lib/util.php | 458 ++++++++++++++++++------------- settings/admin.php | 4 +- tests/lib/db.php | 2 +- tests/lib/dbschema.php | 2 +- tests/lib/util.php | 4 +- 17 files changed, 290 insertions(+), 222 deletions(-) diff --git a/core/lostpassword/controller.php b/core/lostpassword/controller.php index 74a5be2b96..f761e45d25 100644 --- a/core/lostpassword/controller.php +++ b/core/lostpassword/controller.php @@ -42,7 +42,7 @@ class OC_Core_LostPassword_Controller { } if (OC_User::userExists($_POST['user']) && $continue) { - $token = hash('sha256', OC_Util::generate_random_bytes(30).OC_Config::getValue('passwordsalt', '')); + $token = hash('sha256', OC_Util::generateRandomBytes(30).OC_Config::getValue('passwordsalt', '')); OC_Preferences::setValue($_POST['user'], 'owncloud', 'lostpassword', hash('sha256', $token)); // Hash the token again to prevent timing attacks $email = OC_Preferences::getValue($_POST['user'], 'settings', 'email', ''); diff --git a/core/minimizer.php b/core/minimizer.php index 4da9037c41..eeeddf86a8 100644 --- a/core/minimizer.php +++ b/core/minimizer.php @@ -5,11 +5,11 @@ OC_App::loadApps(); if ($service == 'core.css') { $minimizer = new OC_Minimizer_CSS(); - $files = OC_TemplateLayout::findStylesheetFiles(OC_Util::$core_styles); + $files = OC_TemplateLayout::findStylesheetFiles(OC_Util::$coreStyles); $minimizer->output($files, $service); } else if ($service == 'core.js') { $minimizer = new OC_Minimizer_JS(); - $files = OC_TemplateLayout::findJavascriptFiles(OC_Util::$core_scripts); + $files = OC_TemplateLayout::findJavascriptFiles(OC_Util::$coreScripts); $minimizer->output($files, $service); } diff --git a/core/setup.php b/core/setup.php index 40e30db533..1a2eac1603 100644 --- a/core/setup.php +++ b/core/setup.php @@ -33,8 +33,8 @@ $opts = array( 'hasOracle' => $hasOracle, 'hasMSSQL' => $hasMSSQL, 'directory' => $datadir, - 'secureRNG' => OC_Util::secureRNG_available(), - 'htaccessWorking' => OC_Util::ishtaccessworking(), + 'secureRNG' => OC_Util::secureRNGAvailable(), + 'htaccessWorking' => OC_Util::isHtaccessWorking(), 'vulnerableToNullByte' => $vulnerableToNullByte, 'errors' => array(), ); diff --git a/lib/app.php b/lib/app.php index 5fa650044f..2f5a952d9f 100644 --- a/lib/app.php +++ b/lib/app.php @@ -73,11 +73,11 @@ class OC_App{ if (!defined('DEBUG') || !DEBUG) { if (is_null($types) - && empty(OC_Util::$core_scripts) - && empty(OC_Util::$core_styles)) { - OC_Util::$core_scripts = OC_Util::$scripts; + && empty(OC_Util::$coreScripts) + && empty(OC_Util::$coreStyles)) { + OC_Util::$coreScripts = OC_Util::$scripts; OC_Util::$scripts = array(); - OC_Util::$core_styles = OC_Util::$styles; + OC_Util::$coreStyles = OC_Util::$styles; OC_Util::$styles = array(); } } diff --git a/lib/base.php b/lib/base.php index eaee842465..7a4f5fc7ce 100644 --- a/lib/base.php +++ b/lib/base.php @@ -413,7 +413,7 @@ class OC { } self::initPaths(); - OC_Util::issetlocaleworking(); + OC_Util::isSetlocaleWorking(); // set debug mode if an xdebug session is active if (!defined('DEBUG') || !DEBUG) { @@ -522,7 +522,7 @@ class OC { } // write error into log if locale can't be set - if (OC_Util::issetlocaleworking() == false) { + if (OC_Util::isSetlocaleWorking() == false) { OC_Log::write('core', 'setting locale to en_US.UTF-8/en_US.UTF8 failed. Support is probably not installed on your system', OC_Log::ERROR); @@ -735,7 +735,7 @@ class OC { if (in_array($_COOKIE['oc_token'], $tokens, true)) { // replace successfully used token with a new one OC_Preferences::deleteKey($_COOKIE['oc_username'], 'login_token', $_COOKIE['oc_token']); - $token = OC_Util::generate_random_bytes(32); + $token = OC_Util::generateRandomBytes(32); OC_Preferences::setValue($_COOKIE['oc_username'], 'login_token', $token, time()); OC_User::setMagicInCookie($_COOKIE['oc_username'], $token); // login @@ -774,7 +774,7 @@ class OC { if (defined("DEBUG") && DEBUG) { OC_Log::write('core', 'Setting remember login to cookie', OC_Log::DEBUG); } - $token = OC_Util::generate_random_bytes(32); + $token = OC_Util::generateRandomBytes(32); OC_Preferences::setValue($_POST['user'], 'login_token', $token, time()); OC_User::setMagicInCookie($_POST["user"], $token); } else { diff --git a/lib/public/share.php b/lib/public/share.php index 63645e6fa3..7714837769 100644 --- a/lib/public/share.php +++ b/lib/public/share.php @@ -463,7 +463,7 @@ class Share { if (isset($oldToken)) { $token = $oldToken; } else { - $token = \OC_Util::generate_random_bytes(self::TOKEN_LENGTH); + $token = \OC_Util::generateRandomBytes(self::TOKEN_LENGTH); } $result = self::put($itemType, $itemSource, $shareType, $shareWith, $uidOwner, $permissions, null, $token); diff --git a/lib/setup.php b/lib/setup.php index 05a4989097..6bf3c88370 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -61,7 +61,7 @@ class OC_Setup { } //generate a random salt that is used to salt the local user passwords - $salt = OC_Util::generate_random_bytes(30); + $salt = OC_Util::generateRandomBytes(30); OC_Config::setValue('passwordsalt', $salt); //write the config file diff --git a/lib/setup/mysql.php b/lib/setup/mysql.php index 0cf04fde5a..d97b6d2602 100644 --- a/lib/setup/mysql.php +++ b/lib/setup/mysql.php @@ -23,7 +23,7 @@ class MySQL extends AbstractDatabase { $this->dbuser=substr('oc_'.$username, 0, 16); if($this->dbuser!=$oldUser) { //hash the password so we don't need to store the admin config in the config file - $this->dbpassword=\OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generateRandomBytes(30); $this->createDBUser($connection); diff --git a/lib/setup/oci.php b/lib/setup/oci.php index 86b53de45a..326d7a0053 100644 --- a/lib/setup/oci.php +++ b/lib/setup/oci.php @@ -65,7 +65,7 @@ class OCI extends AbstractDatabase { //add prefix to the oracle user name to prevent collisions $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $this->dbpassword=\OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generateRandomBytes(30); //oracle passwords are treated as identifiers: // must start with aphanumeric char diff --git a/lib/setup/postgresql.php b/lib/setup/postgresql.php index 49fcbf0326..89d328ada1 100644 --- a/lib/setup/postgresql.php +++ b/lib/setup/postgresql.php @@ -33,7 +33,7 @@ class PostgreSQL extends AbstractDatabase { //add prefix to the postgresql user name to prevent collisions $this->dbuser='oc_'.$username; //create a new password so we don't need to store the admin config in the config file - $this->dbpassword=\OC_Util::generate_random_bytes(30); + $this->dbpassword=\OC_Util::generateRandomBytes(30); $this->createDBUser($connection); diff --git a/lib/templatelayout.php b/lib/templatelayout.php index 0024c9d496..0b868a39e4 100644 --- a/lib/templatelayout.php +++ b/lib/templatelayout.php @@ -58,7 +58,7 @@ class OC_TemplateLayout extends OC_Template { if (OC_Config::getValue('installed', false) && $renderas!='error') { $this->append( 'jsfiles', OC_Helper::linkToRoute('js_config') . $versionParameter); } - if (!empty(OC_Util::$core_scripts)) { + if (!empty(OC_Util::$coreScripts)) { $this->append( 'jsfiles', OC_Helper::linkToRemoteBase('core.js', false) . $versionParameter); } foreach($jsfiles as $info) { @@ -71,7 +71,7 @@ class OC_TemplateLayout extends OC_Template { // Add the css files $cssfiles = self::findStylesheetFiles(OC_Util::$styles); $this->assign('cssfiles', array()); - if (!empty(OC_Util::$core_styles)) { + if (!empty(OC_Util::$coreStyles)) { $this->append( 'cssfiles', OC_Helper::linkToRemoteBase('core.css', false) . $versionParameter); } foreach($cssfiles as $info) { diff --git a/lib/user.php b/lib/user.php index 93c7c9d4cd..0f6f40aec9 100644 --- a/lib/user.php +++ b/lib/user.php @@ -353,7 +353,7 @@ class OC_User { * generates a password */ public static function generatePassword() { - return OC_Util::generate_random_bytes(30); + return OC_Util::generateRandomBytes(30); } /** diff --git a/lib/util.php b/lib/util.php index 25632ac1ea..24ae7d3d1c 100755 --- a/lib/util.php +++ b/lib/util.php @@ -11,12 +11,16 @@ class OC_Util { public static $headers=array(); private static $rootMounted=false; private static $fsSetup=false; - public static $core_styles=array(); - public static $core_scripts=array(); + public static $coreStyles=array(); + public static $coreScripts=array(); - // Can be set up - public static function setupFS( $user = '' ) {// configure the initial filesystem based on the configuration - if(self::$fsSetup) {//setting up the filesystem twice can only lead to trouble + /** + * @brief Can be set up + * @param user string + * @return boolean + */ + public static function setupFS( $user = '' ) { // configure the initial filesystem based on the configuration + if(self::$fsSetup) { //setting up the filesystem twice can only lead to trouble return false; } @@ -37,42 +41,45 @@ class OC_Util { self::$fsSetup=true; } - $CONFIG_DATADIRECTORY = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); + $configDataDirectory = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ); //first set up the local "root" storage \OC\Files\Filesystem::initMounts(); if(!self::$rootMounted) { - \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir'=>$CONFIG_DATADIRECTORY), '/'); - self::$rootMounted=true; + \OC\Files\Filesystem::mount('\OC\Files\Storage\Local', array('datadir'=>$configDataDirectory), '/'); + self::$rootMounted = true; } if( $user != "" ) { //if we aren't logged in, there is no use to set up the filesystem - $user_dir = '/'.$user.'/files'; - $user_root = OC_User::getHome($user); - $userdirectory = $user_root . '/files'; - if( !is_dir( $userdirectory )) { - mkdir( $userdirectory, 0755, true ); + $userDir = '/'.$user.'/files'; + $userRoot = OC_User::getHome($user); + $userDirectory = $userRoot . '/files'; + if( !is_dir( $userDirectory )) { + mkdir( $userDirectory, 0755, true ); } //jail the user into his "home" directory - \OC\Files\Filesystem::init($user, $user_dir); + \OC\Files\Filesystem::init($user, $userDir); - $quotaProxy=new OC_FileProxy_Quota(); + $quotaProxy = new OC_FileProxy_Quota(); $fileOperationProxy = new OC_FileProxy_FileOperations(); OC_FileProxy::register($quotaProxy); OC_FileProxy::register($fileOperationProxy); - OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $user_dir)); + OC_Hook::emit('OC_Filesystem', 'setup', array('user' => $user, 'user_dir' => $userDir)); } return true; } + /** + * @return void + */ public static function tearDownFS() { \OC\Files\Filesystem::tearDown(); self::$fsSetup=false; - self::$rootMounted=false; + self::$rootMounted=false; } /** - * get the current installed version of ownCloud + * @brief get the current installed version of ownCloud * @return array */ public static function getVersion() { @@ -82,7 +89,7 @@ class OC_Util { } /** - * get the current installed version string of ownCloud + * @brief get the current installed version string of ownCloud * @return string */ public static function getVersionString() { @@ -90,7 +97,7 @@ class OC_Util { } /** - * get the current installed edition of ownCloud. There is the community + * @description get the current installed edition of ownCloud. There is the community * edition that just returns an empty string and the enterprise edition * that returns "Enterprise". * @return string @@ -100,37 +107,39 @@ class OC_Util { } /** - * add a javascript file + * @brief add a javascript file * - * @param appid $application - * @param filename $file + * @param appid $application + * @param filename $file + * @return void */ public static function addScript( $application, $file = null ) { - if( is_null( $file )) { + if ( is_null( $file )) { $file = $application; $application = ""; } - if( !empty( $application )) { + if ( !empty( $application )) { self::$scripts[] = "$application/js/$file"; - }else{ + } else { self::$scripts[] = "js/$file"; } } /** - * add a css file + * @brief add a css file * - * @param appid $application - * @param filename $file + * @param appid $application + * @param filename $file + * @return void */ public static function addStyle( $application, $file = null ) { - if( is_null( $file )) { + if ( is_null( $file )) { $file = $application; $application = ""; } - if( !empty( $application )) { + if ( !empty( $application )) { self::$styles[] = "$application/css/$file"; - }else{ + } else { self::$styles[] = "css/$file"; } } @@ -140,63 +149,74 @@ class OC_Util { * @param string tag tag name of the element * @param array $attributes array of attributes for the element * @param string $text the text content for the element + * @return void */ public static function addHeader( $tag, $attributes, $text='') { - self::$headers[] = array('tag'=>$tag, 'attributes'=>$attributes, 'text'=>$text); + self::$headers[] = array( + 'tag'=>$tag, + 'attributes'=>$attributes, + 'text'=>$text + ); } /** - * formats a timestamp in the "right" way + * @brief formats a timestamp in the "right" way * * @param int timestamp $timestamp * @param bool dateOnly option to omit time from the result + * @return string timestamp */ public static function formatDate( $timestamp, $dateOnly=false) { - if(\OC::$session->exists('timezone')) {//adjust to clients timezone if we know it + if(\OC::$session->exists('timezone')) { //adjust to clients timezone if we know it $systemTimeZone = intval(date('O')); - $systemTimeZone=(round($systemTimeZone/100, 0)*60)+($systemTimeZone%100); - $clientTimeZone=\OC::$session->get('timezone')*60; - $offset=$clientTimeZone-$systemTimeZone; - $timestamp=$timestamp+$offset*60; + $systemTimeZone = (round($systemTimeZone/100, 0)*60) + ($systemTimeZone%100); + $clientTimeZone = \OC::$session->get('timezone')*60; + $offset = $clientTimeZone - $systemTimeZone; + $timestamp = $timestamp + $offset*60; } - $l=OC_L10N::get('lib'); + $l = OC_L10N::get('lib'); return $l->l($dateOnly ? 'date' : 'datetime', $timestamp); } /** - * check if the current server configuration is suitable for ownCloud + * @brief check if the current server configuration is suitable for ownCloud * @return array arrays with error messages and hints */ public static function checkServer() { // Assume that if checkServer() succeeded before in this session, then all is fine. - if(\OC::$session->exists('checkServer_suceeded') && \OC::$session->get('checkServer_suceeded')) + if(\OC::$session->exists('checkServer_suceeded') && \OC::$session->get('checkServer_suceeded')) { return array(); + } - $errors=array(); + $errors = array(); $defaults = new \OC_Defaults(); - $web_server_restart= false; + $webServerRestart = false; //check for database drivers if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect') and !is_callable('oci_connect')) { - $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.', - 'hint'=>'');//TODO: sane hint - $web_server_restart= true; + $errors[] = array( + 'error'=>'No database drivers (sqlite, mysql, or postgresql) installed.', + 'hint'=>'' //TODO: sane hint + ); + $webServerRestart = true; } //common hint for all file permissons error messages $permissionsHint = 'Permissions can usually be fixed by ' - .'giving the webserver write access to the root directory.'; + .'giving the webserver write access to the root directory.'; // Check if config folder is writable. if(!is_writable(OC::$SERVERROOT."/config/") or !is_readable(OC::$SERVERROOT."/config/")) { $errors[] = array( 'error' => "Can't write into config directory", 'hint' => 'This can usually be fixed by ' - .'giving the webserver write access to the config directory.' + .'giving the webserver write access to the config directory.' ); } @@ -208,7 +228,8 @@ class OC_Util { $errors[] = array( 'error' => "Can't write into apps directory", 'hint' => 'This can usually be fixed by ' - .'giving the webserver write access to the apps directory ' + .'giving the webserver write access to the apps directory ' .'or disabling the appstore in the config file.' ); } @@ -223,94 +244,131 @@ class OC_Util { $errors[] = array( 'error' => "Can't create data directory (".$CONFIG_DATADIRECTORY.")", 'hint' => 'This can usually be fixed by ' - .'giving the webserver write access to the root directory.' + .'giving the webserver write access to the root directory.' ); } } else if(!is_writable($CONFIG_DATADIRECTORY) or !is_readable($CONFIG_DATADIRECTORY)) { - $errors[]=array('error'=>'Data directory ('.$CONFIG_DATADIRECTORY.') not writable by ownCloud', - 'hint'=>$permissionsHint); + $errors[] = array( + 'error'=>'Data directory ('.$CONFIG_DATADIRECTORY.') not writable by ownCloud', + 'hint'=>$permissionsHint + ); } else { $errors = array_merge($errors, self::checkDataDirectoryPermissions($CONFIG_DATADIRECTORY)); } + + $moduleHint = "Please ask your server administrator to install the module."; // check if all required php modules are present if(!class_exists('ZipArchive')) { - $errors[]=array('error'=>'PHP module zip not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module zip not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!class_exists('DOMDocument')) { - $errors[] = array('error' => 'PHP module dom not installed.', - 'hint' => 'Please ask your server administrator to install the module.'); - $web_server_restart =true; + $errors[] = array( + 'error' => 'PHP module dom not installed.', + 'hint' => $moduleHint + ); + $webServerRestart =true; } if(!function_exists('xml_parser_create')) { - $errors[] = array('error' => 'PHP module libxml not installed.', - 'hint' => 'Please ask your server administrator to install the module.'); - $web_server_restart =true; + $errors[] = array( + 'error' => 'PHP module libxml not installed.', + 'hint' => $moduleHint + ); + $webServerRestart = true; } if(!function_exists('mb_detect_encoding')) { - $errors[]=array('error'=>'PHP module mb multibyte not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module mb multibyte not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!function_exists('ctype_digit')) { - $errors[]=array('error'=>'PHP module ctype is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module ctype is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!function_exists('json_encode')) { - $errors[]=array('error'=>'PHP module JSON is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module JSON is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!extension_loaded('gd') || !function_exists('gd_info')) { - $errors[]=array('error'=>'PHP module GD is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module GD is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!function_exists('gzencode')) { - $errors[]=array('error'=>'PHP module zlib is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module zlib is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!function_exists('iconv')) { - $errors[]=array('error'=>'PHP module iconv is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module iconv is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if(!function_exists('simplexml_load_string')) { - $errors[]=array('error'=>'PHP module SimpleXML is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP module SimpleXML is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } - if(floatval(phpversion())<5.3) { - $errors[]=array('error'=>'PHP 5.3 is required.', + if(floatval(phpversion()) < 5.3) { + $errors[] = array( + 'error'=>'PHP 5.3 is required.', 'hint'=>'Please ask your server administrator to update PHP to version 5.3 or higher.' - .' PHP 5.2 is no longer supported by ownCloud and the PHP community.'); - $web_server_restart=true; + .' PHP 5.2 is no longer supported by ownCloud and the PHP community.' + ); + $webServerRestart = true; } if(!defined('PDO::ATTR_DRIVER_NAME')) { - $errors[]=array('error'=>'PHP PDO module is not installed.', - 'hint'=>'Please ask your server administrator to install the module.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP PDO module is not installed.', + 'hint'=>$moduleHint + ); + $webServerRestart = true; } if (((strtolower(@ini_get('safe_mode')) == 'on') || (strtolower(@ini_get('safe_mode')) == 'yes') || (strtolower(@ini_get('safe_mode')) == 'true') || (ini_get("safe_mode") == 1 ))) { - $errors[]=array('error'=>'PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly.', - 'hint'=>'PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'PHP Safe Mode is enabled. ownCloud requires that it is disabled to work properly.', + 'hint'=>'PHP Safe Mode is a deprecated and mostly useless setting that should be disabled. ' + .'Please ask your server administrator to disable it in php.ini or in your webserver config.' + ); + $webServerRestart = true; } if (get_magic_quotes_gpc() == 1 ) { - $errors[]=array('error'=>'Magic Quotes is enabled. ownCloud requires that it is disabled to work properly.', - 'hint'=>'Magic Quotes is a deprecated and mostly useless setting that should be disabled. Please ask your server administrator to disable it in php.ini or in your webserver config.'); - $web_server_restart=true; + $errors[] = array( + 'error'=>'Magic Quotes is enabled. ownCloud requires that it is disabled to work properly.', + 'hint'=>'Magic Quotes is a deprecated and mostly useless setting that should be disabled. ' + .'Please ask your server administrator to disable it in php.ini or in your webserver config.' + ); + $webServerRestart = true; } - if($web_server_restart) { - $errors[]=array('error'=>'PHP modules have been installed, but they are still listed as missing?', - 'hint'=>'Please ask your server administrator to restart the web server.'); + if($webServerRestart) { + $errors[] = array( + 'error'=>'PHP modules have been installed, but they are still listed as missing?', + 'hint'=>'Please ask your server administrator to restart the web server.' + ); } // Cache the result of this function @@ -330,20 +388,25 @@ class OC_Util { } else { $permissionsModHint = 'Please change the permissions to 0770 so that the directory' .' cannot be listed by other users.'; - $prems = substr(decoct(@fileperms($dataDirectory)), -3); - if (substr($prems, -1) != '0') { + $perms = substr(decoct(@fileperms($dataDirectory)), -3); + if (substr($perms, -1) != '0') { OC_Helper::chmodr($dataDirectory, 0770); clearstatcache(); - $prems = substr(decoct(@fileperms($dataDirectory)), -3); - if (substr($prems, 2, 1) != '0') { - $errors[] = array('error' => 'Data directory ('.$dataDirectory.') is readable for other users', - 'hint' => $permissionsModHint); + $perms = substr(decoct(@fileperms($dataDirectory)), -3); + if (substr($perms, 2, 1) != '0') { + $errors[] = array( + 'error' => 'Data directory ('.$dataDirectory.') is readable for other users', + 'hint' => $permissionsModHint + ); } } } return $errors; } + /** + * @return void + */ public static function displayLoginPage($errors = array()) { $parameters = array(); foreach( $errors as $key => $value ) { @@ -357,8 +420,8 @@ class OC_Util { $parameters['user_autofocus'] = true; } if (isset($_REQUEST['redirect_url'])) { - $redirect_url = $_REQUEST['redirect_url']; - $parameters['redirect_url'] = urlencode($redirect_url); + $redirectUrl = $_REQUEST['redirect_url']; + $parameters['redirect_url'] = urlencode($redirectUrl); } $parameters['alt_login'] = OC_App::getAlternativeLogIns(); @@ -367,7 +430,8 @@ class OC_Util { /** - * Check if the app is enabled, redirects to home if not + * @brief Check if the app is enabled, redirects to home if not + * @return void */ public static function checkAppEnabled($app) { if( !OC_App::isEnabled($app)) { @@ -379,18 +443,21 @@ class OC_Util { /** * Check if the user is logged in, redirects to home if not. With * redirect URL parameter to the request URI. + * @return void */ public static function checkLoggedIn() { // Check if we are a user if( !OC_User::isLoggedIn()) { header( 'Location: '.OC_Helper::linkToAbsolute( '', 'index.php', - array('redirect_url' => OC_Request::requestUri()))); + array('redirectUrl' => OC_Request::requestUri()) + )); exit(); } } /** - * Check if the user is a admin, redirects to home if not + * @brief Check if the user is a admin, redirects to home if not + * @return void */ public static function checkAdminUser() { if( !OC_User::isAdminUser(OC_User::getUser())) { @@ -400,7 +467,7 @@ class OC_Util { } /** - * Check if the user is a subadmin, redirects to home if not + * @brief Check if the user is a subadmin, redirects to home if not * @return array $groups where the current user is subadmin */ public static function checkSubAdminUser() { @@ -412,7 +479,8 @@ class OC_Util { } /** - * Redirect to the user default page + * @brief Redirect to the user default page + * @return void */ public static function redirectToDefaultPage() { if(isset($_REQUEST['redirect_url'])) { @@ -420,13 +488,11 @@ class OC_Util { } else if (isset(OC::$REQUESTEDAPP) && !empty(OC::$REQUESTEDAPP)) { $location = OC_Helper::linkToAbsolute( OC::$REQUESTEDAPP, 'index.php' ); - } - else { - $defaultpage = OC_Appconfig::getValue('core', 'defaultpage'); - if ($defaultpage) { - $location = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/'.$defaultpage); - } - else { + } else { + $defaultPage = OC_Appconfig::getValue('core', 'defaultpage'); + if ($defaultPage) { + $location = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/'.$defaultPage); + } else { $location = OC_Helper::linkToAbsolute( 'files', 'index.php' ); } } @@ -435,19 +501,19 @@ class OC_Util { exit(); } - /** - * get an id unique for this instance - * @return string - */ - public static function getInstanceId() { - $id = OC_Config::getValue('instanceid', null); - if(is_null($id)) { - // We need to guarantee at least one letter in instanceid so it can be used as the session_name - $id = 'oc' . OC_Util::generate_random_bytes(10); - OC_Config::setValue('instanceid', $id); - } - return $id; - } + /** + * @brief get an id unique for this instance + * @return string + */ + public static function getInstanceId() { + $id = OC_Config::getValue('instanceid', null); + if(is_null($id)) { + // We need to guarantee at least one letter in instanceid so it can be used as the session_name + $id = 'oc' . self::generateRandomBytes(10); + OC_Config::setValue('instanceid', $id); + } + return $id; + } /** * @brief Static lifespan (in seconds) when a request token expires. @@ -476,7 +542,7 @@ class OC_Util { // Check if a token exists if(!\OC::$session->exists('requesttoken')) { // No valid token found, generate a new one. - $requestToken = self::generate_random_bytes(20); + $requestToken = self::generateRandomBytes(20); \OC::$session->set('requesttoken', $requestToken); } else { // Valid token already exists, send it @@ -497,11 +563,11 @@ class OC_Util { } if(isset($_GET['requesttoken'])) { - $token=$_GET['requesttoken']; + $token = $_GET['requesttoken']; } elseif(isset($_POST['requesttoken'])) { - $token=$_POST['requesttoken']; + $token = $_POST['requesttoken']; } elseif(isset($_SERVER['HTTP_REQUESTTOKEN'])) { - $token=$_SERVER['HTTP_REQUESTTOKEN']; + $token = $_SERVER['HTTP_REQUESTTOKEN']; } else { //no token found. return false; @@ -519,11 +585,12 @@ class OC_Util { /** * @brief Check an ajax get/post call if the request token is valid. exit if not. - * Todo: Write howto + * @todo Write howto + * @return void */ public static function callCheck() { if(!OC_Util::isCallRegistered()) { - exit; + exit(); } } @@ -562,12 +629,13 @@ class OC_Util { } /** - * Check if the htaccess file is working by creating a test file in the data directory and trying to access via http + * @brief Check if the htaccess file is working by creating a test file in the data directory and trying to access via http + * @return bool */ - public static function ishtaccessworking() { + public static function isHtaccessWorking() { // testdata - $filename='/htaccesstest.txt'; - $testcontent='testcontent'; + $filename = '/htaccesstest.txt'; + $testcontent = 'testcontent'; // creating a test file $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename; @@ -591,19 +659,20 @@ class OC_Util { // does it work ? if($content==$testcontent) { - return(false); - }else{ - return(true); + return false; + } else { + return true; } } /** - * we test if webDAV is working properly - * + * @brief test if webDAV is working properly + * @return bool + * @description * The basic assumption is that if the server returns 401/Not Authenticated for an unauthenticated PROPFIND * the web server it self is setup properly. * - * Why not an authenticated PROFIND and other verbs? + * Why not an authenticated PROPFIND and other verbs? * - We don't have the password available * - We have no idea about other auth methods implemented (e.g. OAuth with Bearer header) * @@ -617,7 +686,7 @@ class OC_Util { ); // save the old timeout so that we can restore it later - $old_timeout=ini_get("default_socket_timeout"); + $oldTimeout = ini_get("default_socket_timeout"); // use a 5 sec timeout for the check. Should be enough for local requests. ini_set("default_socket_timeout", 5); @@ -631,15 +700,15 @@ class OC_Util { try { // test PROPFIND $client->propfind('', array('{DAV:}resourcetype')); - } catch(\Sabre_DAV_Exception_NotAuthenticated $e) { + } catch (\Sabre_DAV_Exception_NotAuthenticated $e) { $return = true; - } catch(\Exception $e) { + } catch (\Exception $e) { OC_Log::write('core', 'isWebDAVWorking: NO - Reason: '.$e->getMessage(). ' ('.get_class($e).')', OC_Log::WARN); $return = false; } // restore the original timeout - ini_set("default_socket_timeout", $old_timeout); + ini_set("default_socket_timeout", $oldTimeout); return $return; } @@ -647,8 +716,9 @@ class OC_Util { /** * Check if the setlocal call doesn't work. This can happen if the right * local packages are not available on the server. + * @return bool */ - public static function issetlocaleworking() { + public static function isSetlocaleWorking() { // setlocale test is pointless on Windows if (OC_Util::runningOnWindows() ) { return true; @@ -662,7 +732,7 @@ class OC_Util { } /** - * Check if the PHP module fileinfo is loaded. + * @brief Check if the PHP module fileinfo is loaded. * @return bool */ public static function fileInfoLoaded() { @@ -670,7 +740,8 @@ class OC_Util { } /** - * Check if the ownCloud server can connect to the internet + * @brief Check if the ownCloud server can connect to the internet + * @return bool */ public static function isInternetConnectionWorking() { // in case there is no internet connection on purpose return false @@ -683,30 +754,29 @@ class OC_Util { if ($connected) { fclose($connected); return true; - }else{ - + } else { // second try in case one server is down $connected = @fsockopen("apps.owncloud.com", 80); if ($connected) { fclose($connected); return true; - }else{ + } else { return false; } - } - } /** - * Check if the connection to the internet is disabled on purpose + * @brief Check if the connection to the internet is disabled on purpose + * @return bool */ public static function isInternetConnectionEnabled(){ return \OC_Config::getValue("has_internet_connection", true); } /** - * clear all levels of output buffering + * @brief clear all levels of output buffering + * @return void */ public static function obEnd(){ while (ob_get_level()) { @@ -719,44 +789,44 @@ class OC_Util { * @brief Generates a cryptographical secure pseudorandom string * @param Int with the length of the random string * @return String - * Please also update secureRNG_available if you change something here + * Please also update secureRNGAvailable if you change something here */ - public static function generate_random_bytes($length = 30) { - + public static function generateRandomBytes($length = 30) { // Try to use openssl_random_pseudo_bytes - if(function_exists('openssl_random_pseudo_bytes')) { - $pseudo_byte = bin2hex(openssl_random_pseudo_bytes($length, $strong)); + if (function_exists('openssl_random_pseudo_bytes')) { + $pseudoByte = bin2hex(openssl_random_pseudo_bytes($length, $strong)); if($strong == true) { - return substr($pseudo_byte, 0, $length); // Truncate it to match the length + return substr($pseudoByte, 0, $length); // Truncate it to match the length } } // Try to use /dev/urandom - $fp = @file_get_contents('/dev/urandom', false, null, 0, $length); - if ($fp !== false) { - $string = substr(bin2hex($fp), 0, $length); - return $string; + if (!self::runningOnWindows()) { + $fp = @file_get_contents('/dev/urandom', false, null, 0, $length); + if ($fp !== false) { + $string = substr(bin2hex($fp), 0, $length); + return $string; + } } // Fallback to mt_rand() $characters = '0123456789'; $characters .= 'abcdefghijklmnopqrstuvwxyz'; $charactersLength = strlen($characters)-1; - $pseudo_byte = ""; + $pseudoByte = ""; // Select some random characters for ($i = 0; $i < $length; $i++) { - $pseudo_byte .= $characters[mt_rand(0, $charactersLength)]; + $pseudoByte .= $characters[mt_rand(0, $charactersLength)]; } - return $pseudo_byte; + return $pseudoByte; } /** * @brief Checks if a secure random number generator is available * @return bool */ - public static function secureRNG_available() { - + public static function secureRNGAvailable() { // Check openssl_random_pseudo_bytes if(function_exists('openssl_random_pseudo_bytes')) { openssl_random_pseudo_bytes(1, $strong); @@ -766,9 +836,11 @@ class OC_Util { } // Check /dev/urandom - $fp = @file_get_contents('/dev/urandom', false, null, 0, 1); - if ($fp !== false) { - return true; + if (!self::runningOnWindows()) { + $fp = @file_get_contents('/dev/urandom', false, null, 0, 1); + if ($fp !== false) { + return true; + } } return false; @@ -781,11 +853,8 @@ class OC_Util { * This function get the content of a page via curl, if curl is enabled. * If not, file_get_element is used. */ - public static function getUrlContent($url){ - - if (function_exists('curl_init')) { - + if (function_exists('curl_init')) { $curl = curl_init(); curl_setopt($curl, CURLOPT_HEADER, 0); @@ -796,10 +865,10 @@ class OC_Util { curl_setopt($curl, CURLOPT_MAXREDIRS, 10); curl_setopt($curl, CURLOPT_USERAGENT, "ownCloud Server Crawler"); - if(OC_Config::getValue('proxy', '')<>'') { + if(OC_Config::getValue('proxy', '') != '') { curl_setopt($curl, CURLOPT_PROXY, OC_Config::getValue('proxy')); } - if(OC_Config::getValue('proxyuserpwd', '')<>'') { + if(OC_Config::getValue('proxyuserpwd', '') != '') { curl_setopt($curl, CURLOPT_PROXYUSERPWD, OC_Config::getValue('proxyuserpwd')); } $data = curl_exec($curl); @@ -808,7 +877,7 @@ class OC_Util { } else { $contextArray = null; - if(OC_Config::getValue('proxy', '')<>'') { + if(OC_Config::getValue('proxy', '') != '') { $contextArray = array( 'http' => array( 'timeout' => 10, @@ -823,11 +892,10 @@ class OC_Util { ); } - $ctx = stream_context_create( $contextArray ); - $data=@file_get_contents($url, 0, $ctx); + $data = @file_get_contents($url, 0, $ctx); } return $data; @@ -840,7 +908,6 @@ class OC_Util { return (substr(PHP_OS, 0, 3) === "WIN"); } - /** * Handles the case that there may not be a theme, then check if a "default" * theme exists and take that one @@ -850,20 +917,19 @@ class OC_Util { $theme = OC_Config::getValue("theme", ''); if($theme === '') { - if(is_dir(OC::$SERVERROOT . '/themes/default')) { $theme = 'default'; } - } return $theme; } /** - * Clear the opcode cache if one exists + * @brief Clear the opcode cache if one exists * This is necessary for writing to the config file * in case the opcode cache doesn't revalidate files + * @return void */ public static function clearOpcodeCache() { // APC @@ -902,8 +968,10 @@ class OC_Util { return $value; } - public static function basename($file) - { + /** + * @return string + */ + public static function basename($file) { $file = rtrim($file, '/'); $t = explode('/', $file); return array_pop($t); diff --git a/settings/admin.php b/settings/admin.php index 10e239204f..d721593eb7 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -15,7 +15,7 @@ OC_App::setActiveNavigationEntry( "admin" ); $tmpl = new OC_Template( 'settings', 'admin', 'user'); $forms=OC_App::getForms('admin'); -$htaccessworking=OC_Util::ishtaccessworking(); +$htaccessworking=OC_Util::isHtaccessWorking(); $entries=OC_Log_Owncloud::getEntries(3); $entriesremain=(count(OC_Log_Owncloud::getEntries(4)) > 3)?true:false; @@ -25,7 +25,7 @@ $tmpl->assign('entries', $entries); $tmpl->assign('entriesremain', $entriesremain); $tmpl->assign('htaccessworking', $htaccessworking); $tmpl->assign('internetconnectionworking', OC_Util::isInternetConnectionEnabled() ? OC_Util::isInternetConnectionWorking() : false); -$tmpl->assign('islocaleworking', OC_Util::issetlocaleworking()); +$tmpl->assign('islocaleworking', OC_Util::isSetlocaleWorking()); $tmpl->assign('isWebDavWorking', OC_Util::isWebDAVWorking()); $tmpl->assign('has_fileinfo', OC_Util::fileInfoLoaded()); $tmpl->assign('backgroundjobs_mode', OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax')); diff --git a/tests/lib/db.php b/tests/lib/db.php index 51edbf7b30..1977025cf1 100644 --- a/tests/lib/db.php +++ b/tests/lib/db.php @@ -15,7 +15,7 @@ class Test_DB extends PHPUnit_Framework_TestCase { public function setUp() { $dbfile = OC::$SERVERROOT.'/tests/data/db_structure.xml'; - $r = '_'.OC_Util::generate_random_bytes('4').'_'; + $r = '_'.OC_Util::generateRandomBytes('4').'_'; $content = file_get_contents( $dbfile ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); file_put_contents( self::$schema_file, $content ); diff --git a/tests/lib/dbschema.php b/tests/lib/dbschema.php index c2e55eabf4..7de90c047c 100644 --- a/tests/lib/dbschema.php +++ b/tests/lib/dbschema.php @@ -16,7 +16,7 @@ class Test_DBSchema extends PHPUnit_Framework_TestCase { $dbfile = OC::$SERVERROOT.'/tests/data/db_structure.xml'; $dbfile2 = OC::$SERVERROOT.'/tests/data/db_structure2.xml'; - $r = '_'.OC_Util::generate_random_bytes('4').'_'; + $r = '_'.OC_Util::generateRandomBytes('4').'_'; $content = file_get_contents( $dbfile ); $content = str_replace( '*dbprefix*', '*dbprefix*'.$r, $content ); file_put_contents( $this->schema_file, $content ); diff --git a/tests/lib/util.php b/tests/lib/util.php index 13aa49c8c6..d607a3e772 100644 --- a/tests/lib/util.php +++ b/tests/lib/util.php @@ -71,8 +71,8 @@ class Test_Util extends PHPUnit_Framework_TestCase { $this->assertTrue(\OC_Util::isInternetConnectionEnabled()); } - function testGenerate_random_bytes() { - $result = strlen(OC_Util::generate_random_bytes(59)); + function testGenerateRandomBytes() { + $result = strlen(OC_Util::generateRandomBytes(59)); $this->assertEquals(59, $result); } From 64d09452f55c0c73fe0d55a70f82d8ad7a386d7c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 16 Aug 2013 17:19:48 +0200 Subject: [PATCH 002/169] remove editor div in filelist --- apps/files/templates/index.php | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/files/templates/index.php b/apps/files/templates/index.php index 79c283dc33..dd783e95cc 100644 --- a/apps/files/templates/index.php +++ b/apps/files/templates/index.php @@ -101,7 +101,6 @@ -

t('The files you are trying to upload exceed the maximum size for file uploads on this server.'));?> From 5b8d30c6b613b8b50d95fcad7dca4234a64c1632 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=B6rn=20Friedrich=20Dreyer?= Date: Fri, 16 Aug 2013 17:20:49 +0200 Subject: [PATCH 003/169] refactor OC.Breadcrumbs, allow injection of container to allow rendering crumbs into full screen editor --- core/js/js.js | 49 +++++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 20 deletions(-) diff --git a/core/js/js.js b/core/js/js.js index c2b81ae327..5e7946868a 100644 --- a/core/js/js.js +++ b/core/js/js.js @@ -431,9 +431,16 @@ OC.Notification={ OC.Breadcrumb={ container:null, - crumbs:[], show:function(dir, leafname, leaflink){ - OC.Breadcrumb.clear(); + if(!this.container){//default + this.container=$('#controls'); + } + this._show(this.container, dir, leafname, leaflink); + }, + _show:function(container, dir, leafname, leaflink){ + var self = this; + + this._clear(container); // show home + path in subdirectories if (dir && dir !== '/') { @@ -450,8 +457,7 @@ OC.Breadcrumb={ crumbImg.attr('src',OC.imagePath('core','places/home')); crumbLink.append(crumbImg); crumb.append(crumbLink); - OC.Breadcrumb.container.prepend(crumb); - OC.Breadcrumb.crumbs.push(crumb); + container.prepend(crumb); //add path parts var segments = dir.split('/'); @@ -460,20 +466,23 @@ OC.Breadcrumb={ if (name !== '') { pathurl = pathurl+'/'+name; var link = OC.linkTo('files','index.php')+'?dir='+encodeURIComponent(pathurl); - OC.Breadcrumb.push(name, link); + self._push(container, name, link); } }); } //add leafname if (leafname && leaflink) { - OC.Breadcrumb.push(leafname, leaflink); + this._push(container, leafname, leaflink); } }, push:function(name, link){ - if(!OC.Breadcrumb.container){//default - OC.Breadcrumb.container=$('#controls'); + if(!this.container){//default + this.container=$('#controls'); } + return this._push(OC.Breadcrumb.container, name, link); + }, + _push:function(container, name, link){ var crumb=$('

'); crumb.addClass('crumb').addClass('last'); @@ -482,30 +491,30 @@ OC.Breadcrumb={ crumbLink.text(name); crumb.append(crumbLink); - var existing=OC.Breadcrumb.container.find('div.crumb'); + var existing=container.find('div.crumb'); if(existing.length){ existing.removeClass('last'); existing.last().after(crumb); }else{ - OC.Breadcrumb.container.prepend(crumb); + container.prepend(crumb); } - OC.Breadcrumb.crumbs.push(crumb); return crumb; }, pop:function(){ - if(!OC.Breadcrumb.container){//default - OC.Breadcrumb.container=$('#controls'); + if(!this.container){//default + this.container=$('#controls'); } - OC.Breadcrumb.container.find('div.crumb').last().remove(); - OC.Breadcrumb.container.find('div.crumb').last().addClass('last'); - OC.Breadcrumb.crumbs.pop(); + this.container.find('div.crumb').last().remove(); + this.container.find('div.crumb').last().addClass('last'); }, clear:function(){ - if(!OC.Breadcrumb.container){//default - OC.Breadcrumb.container=$('#controls'); + if(!this.container){//default + this.container=$('#controls'); } - OC.Breadcrumb.container.find('div.crumb').remove(); - OC.Breadcrumb.crumbs=[]; + this._clear(this.container); + }, + _clear:function(container) { + container.find('div.crumb').remove(); } }; From a0b7bf78a6e1c269adc8ee1c84b72a8d205a6f28 Mon Sep 17 00:00:00 2001 From: Bart Visscher Date: Fri, 16 Aug 2013 19:05:07 +0200 Subject: [PATCH 004/169] Remove disconnect function from OC_DB --- lib/db.php | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/lib/db.php b/lib/db.php index ebd012c72f..f090f47424 100644 --- a/lib/db.php +++ b/lib/db.php @@ -329,18 +329,6 @@ class OC_DB { self::$connection->commit(); } - /** - * @brief Disconnect - * - * This is good bye, good bye, yeah! - */ - public static function disconnect() { - // Cut connection if required - if(self::$connection) { - self::$connection->close(); - } - } - /** * @brief saves database schema to xml file * @param string $file name of file From d43b4c52ae0169d80e10532db4ce2103f211cd56 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Sat, 17 Aug 2013 10:57:31 +0200 Subject: [PATCH 005/169] also emit hooks for views that are a subfolder of the user folder --- lib/files/view.php | 89 +++++++++++++++++++++++++++++----------------- 1 file changed, 57 insertions(+), 32 deletions(-) diff --git a/lib/files/view.php b/lib/files/view.php index c9727fe498..21c902ccc4 100644 --- a/lib/files/view.php +++ b/lib/files/view.php @@ -267,18 +267,18 @@ class View { $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); if (\OC_FileProxy::runPreProxies('file_put_contents', $absolutePath, $data) and Filesystem::isValidPath($path) - and !Filesystem::isFileBlacklisted($path) + and !Filesystem::isFileBlacklisted($path) ) { $path = $this->getRelativePath($absolutePath); $exists = $this->file_exists($path); $run = true; - if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path)) { + if ($this->shouldEmitHooks($path)) { if (!$exists) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_create, array( - Filesystem::signal_param_path => $path, + Filesystem::signal_param_path => $this->getHookPath($path), Filesystem::signal_param_run => &$run ) ); @@ -287,7 +287,7 @@ class View { Filesystem::CLASSNAME, Filesystem::signal_write, array( - Filesystem::signal_param_path => $path, + Filesystem::signal_param_path => $this->getHookPath($path), Filesystem::signal_param_run => &$run ) ); @@ -300,18 +300,18 @@ class View { list ($count, $result) = \OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if ($this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path) && $result !== false) { + if ($this->shouldEmitHooks($path) && $result !== false) { if (!$exists) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_create, - array(Filesystem::signal_param_path => $path) + array(Filesystem::signal_param_path => $this->getHookPath($path)) ); } \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_write, - array(Filesystem::signal_param_path => $path) + array(Filesystem::signal_param_path => $this->getHookPath($path)) ); } \OC_FileProxy::runPostProxies('file_put_contents', $absolutePath, $count); @@ -353,21 +353,21 @@ class View { return false; } $run = true; - if ($this->fakeRoot == Filesystem::getRoot() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) { + if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2))) { // if it was a rename from a part file to a regular file it was a write and not a rename operation \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_write, array( - Filesystem::signal_param_path => $path2, + Filesystem::signal_param_path => $this->getHookPath($path2), Filesystem::signal_param_run => &$run ) ); - } elseif ($this->fakeRoot == Filesystem::getRoot()) { + } elseif ($this->shouldEmitHooks()) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_rename, array( - Filesystem::signal_param_oldpath => $path1, - Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_oldpath => $this->getHookPath($path1), + Filesystem::signal_param_newpath => $this->getHookPath($path2), Filesystem::signal_param_run => &$run ) ); @@ -407,22 +407,22 @@ class View { } } } - if ($this->fakeRoot == Filesystem::getRoot() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { + if ($this->shouldEmitHooks() && (Cache\Scanner::isPartialFile($path1) && !Cache\Scanner::isPartialFile($path2)) && $result !== false) { // if it was a rename from a part file to a regular file it was a write and not a rename operation \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_write, array( - Filesystem::signal_param_path => $path2, + Filesystem::signal_param_path => $this->getHookPath($path2), ) ); - } elseif ($this->fakeRoot == Filesystem::getRoot() && $result !== false) { + } elseif ($this->shouldEmitHooks() && $result !== false) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_rename, array( - Filesystem::signal_param_oldpath => $path1, - Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $this->getHookPath($path1), + Filesystem::signal_param_newpath => $this->getHookPath($path2) ) ); } @@ -454,13 +454,13 @@ class View { } $run = true; $exists = $this->file_exists($path2); - if ($this->fakeRoot == Filesystem::getRoot()) { + if ($this->shouldEmitHooks()) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_copy, array( - Filesystem::signal_param_oldpath => $path1, - Filesystem::signal_param_newpath => $path2, + Filesystem::signal_param_oldpath => $this->getHookPath($path1), + Filesystem::signal_param_newpath => $this->getHookPath($path2), Filesystem::signal_param_run => &$run ) ); @@ -469,7 +469,7 @@ class View { Filesystem::CLASSNAME, Filesystem::signal_create, array( - Filesystem::signal_param_path => $path2, + Filesystem::signal_param_path => $this->getHookPath($path2), Filesystem::signal_param_run => &$run ) ); @@ -479,7 +479,7 @@ class View { Filesystem::CLASSNAME, Filesystem::signal_write, array( - Filesystem::signal_param_path => $path2, + Filesystem::signal_param_path => $this->getHookPath($path2), Filesystem::signal_param_run => &$run ) ); @@ -510,26 +510,26 @@ class View { list($count, $result) = \OC_Helper::streamCopy($source, $target); } } - if ($this->fakeRoot == Filesystem::getRoot() && $result !== false) { + if ($this->shouldEmitHooks() && $result !== false) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_copy, array( - Filesystem::signal_param_oldpath => $path1, - Filesystem::signal_param_newpath => $path2 + Filesystem::signal_param_oldpath => $this->getHookPath($path1), + Filesystem::signal_param_newpath => $this->getHookPath($path2) ) ); if (!$exists) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_create, - array(Filesystem::signal_param_path => $path2) + array(Filesystem::signal_param_path => $this->getHookPath($path2)) ); } \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_post_write, - array(Filesystem::signal_param_path => $path2) + array(Filesystem::signal_param_path => $this->getHookPath($path2)) ); } return $result; @@ -620,11 +620,11 @@ class View { if ($path == null) { return false; } - if (Filesystem::$loaded && $this->fakeRoot == Filesystem::getRoot()) { + if ($this->shouldEmitHooks($path)) { \OC_Hook::emit( Filesystem::CLASSNAME, Filesystem::signal_read, - array(Filesystem::signal_param_path => $path) + array(Filesystem::signal_param_path => $this->getHookPath($path)) ); } list($storage, $internalPath) = Filesystem::resolvePath($absolutePath . $postFix); @@ -658,7 +658,7 @@ class View { $absolutePath = Filesystem::normalizePath($this->getAbsolutePath($path)); if (\OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and Filesystem::isValidPath($path) - and !Filesystem::isFileBlacklisted($path) + and !Filesystem::isFileBlacklisted($path) ) { $path = $this->getRelativePath($absolutePath); if ($path == null) { @@ -674,7 +674,7 @@ class View { $result = $storage->$operation($internalPath); } $result = \OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); - if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot() && $result !== false) { + if ($this->shouldEmitHooks($path) && $result !== false) { if ($operation != 'fopen') { //no post hooks for fopen, the file stream is still open $this->runHooks($hooks, $path, true); } @@ -685,10 +685,35 @@ class View { return null; } + /** + * get the path relative to the default root for hook usage + * + * @param string $path + * @return string + */ + private function getHookPath($path) { + if (!Filesystem::getView()) { + return $path; + } + return Filesystem::getView()->getRelativePath($this->getAbsolutePath($path)); + } + + private function shouldEmitHooks($path = '') { + if ($path && Cache\Scanner::isPartialFile($path)) { + return false; + } + if (!Filesystem::$loaded) { + return false; + } + $defaultRoot = Filesystem::getRoot(); + return (strlen($this->fakeRoot) >= strlen($defaultRoot)) && (substr($this->fakeRoot, 0, strlen($defaultRoot)) === $defaultRoot); + } + private function runHooks($hooks, $path, $post = false) { + $path = $this->getHookPath($path); $prefix = ($post) ? 'post_' : ''; $run = true; - if (Filesystem::$loaded and $this->fakeRoot == Filesystem::getRoot() && !Cache\Scanner::isPartialFile($path)) { + if ($this->shouldEmitHooks($path)) { foreach ($hooks as $hook) { if ($hook != 'read') { \OC_Hook::emit( From 65d802329f8307cd010a306073d2d3ffd7dc7b74 Mon Sep 17 00:00:00 2001 From: kondou Date: Sun, 18 Aug 2013 10:33:09 +0200 Subject: [PATCH 006/169] Fix some naming and spacing in lib/util.php --- core/setup.php | 2 +- lib/base.php | 4 ++-- lib/util.php | 25 +++++++++++++++---------- settings/admin.php | 4 ++-- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/core/setup.php b/core/setup.php index 1a2eac1603..4758c23b04 100644 --- a/core/setup.php +++ b/core/setup.php @@ -34,7 +34,7 @@ $opts = array( 'hasMSSQL' => $hasMSSQL, 'directory' => $datadir, 'secureRNG' => OC_Util::secureRNGAvailable(), - 'htaccessWorking' => OC_Util::isHtaccessWorking(), + 'htaccessWorking' => OC_Util::isHtAccessWorking(), 'vulnerableToNullByte' => $vulnerableToNullByte, 'errors' => array(), ); diff --git a/lib/base.php b/lib/base.php index 7a4f5fc7ce..32e0ebe27e 100644 --- a/lib/base.php +++ b/lib/base.php @@ -413,7 +413,7 @@ class OC { } self::initPaths(); - OC_Util::isSetlocaleWorking(); + OC_Util::isSetLocaleWorking(); // set debug mode if an xdebug session is active if (!defined('DEBUG') || !DEBUG) { @@ -522,7 +522,7 @@ class OC { } // write error into log if locale can't be set - if (OC_Util::isSetlocaleWorking() == false) { + if (OC_Util::isSetLocaleWorking() == false) { OC_Log::write('core', 'setting locale to en_US.UTF-8/en_US.UTF8 failed. Support is probably not installed on your system', OC_Log::ERROR); diff --git a/lib/util.php b/lib/util.php index 24ae7d3d1c..10b526ef6b 100755 --- a/lib/util.php +++ b/lib/util.php @@ -18,9 +18,11 @@ class OC_Util { * @brief Can be set up * @param user string * @return boolean + * @description configure the initial filesystem based on the configuration */ - public static function setupFS( $user = '' ) { // configure the initial filesystem based on the configuration - if(self::$fsSetup) { //setting up the filesystem twice can only lead to trouble + public static function setupFS( $user = '' ) { + //setting up the filesystem twice can only lead to trouble + if(self::$fsSetup) { return false; } @@ -71,11 +73,11 @@ class OC_Util { /** * @return void - */ + */ public static function tearDownFS() { \OC\Files\Filesystem::tearDown(); self::$fsSetup=false; - self::$rootMounted=false; + self::$rootMounted=false; } /** @@ -165,9 +167,10 @@ class OC_Util { * @param int timestamp $timestamp * @param bool dateOnly option to omit time from the result * @return string timestamp + * @description adjust to clients timezone if we know it */ public static function formatDate( $timestamp, $dateOnly=false) { - if(\OC::$session->exists('timezone')) { //adjust to clients timezone if we know it + if(\OC::$session->exists('timezone')) { $systemTimeZone = intval(date('O')); $systemTimeZone = (round($systemTimeZone/100, 0)*60) + ($systemTimeZone%100); $clientTimeZone = \OC::$session->get('timezone')*60; @@ -629,13 +632,15 @@ class OC_Util { } /** - * @brief Check if the htaccess file is working by creating a test file in the data directory and trying to access via http + * @brief Check if the htaccess file is working * @return bool + * @description Check if the htaccess file is working by creating a test + * file in the data directory and trying to access via http */ - public static function isHtaccessWorking() { + public static function isHtAccessWorking() { // testdata - $filename = '/htaccesstest.txt'; - $testcontent = 'testcontent'; + $fileName = '/htaccesstest.txt'; + $testContent = 'testcontent'; // creating a test file $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename; @@ -718,7 +723,7 @@ class OC_Util { * local packages are not available on the server. * @return bool */ - public static function isSetlocaleWorking() { + public static function isSetLocaleWorking() { // setlocale test is pointless on Windows if (OC_Util::runningOnWindows() ) { return true; diff --git a/settings/admin.php b/settings/admin.php index d721593eb7..0cbb98756d 100755 --- a/settings/admin.php +++ b/settings/admin.php @@ -15,7 +15,7 @@ OC_App::setActiveNavigationEntry( "admin" ); $tmpl = new OC_Template( 'settings', 'admin', 'user'); $forms=OC_App::getForms('admin'); -$htaccessworking=OC_Util::isHtaccessWorking(); +$htaccessworking=OC_Util::isHtAccessWorking(); $entries=OC_Log_Owncloud::getEntries(3); $entriesremain=(count(OC_Log_Owncloud::getEntries(4)) > 3)?true:false; @@ -25,7 +25,7 @@ $tmpl->assign('entries', $entries); $tmpl->assign('entriesremain', $entriesremain); $tmpl->assign('htaccessworking', $htaccessworking); $tmpl->assign('internetconnectionworking', OC_Util::isInternetConnectionEnabled() ? OC_Util::isInternetConnectionWorking() : false); -$tmpl->assign('islocaleworking', OC_Util::isSetlocaleWorking()); +$tmpl->assign('islocaleworking', OC_Util::isSetLocaleWorking()); $tmpl->assign('isWebDavWorking', OC_Util::isWebDAVWorking()); $tmpl->assign('has_fileinfo', OC_Util::fileInfoLoaded()); $tmpl->assign('backgroundjobs_mode', OC_Appconfig::getValue('core', 'backgroundjobs_mode', 'ajax')); From 1c258087c9a1d4ae33c15aed6533862c728f8742 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20M=C3=BCller?= Date: Thu, 22 Aug 2013 01:20:28 +0200 Subject: [PATCH 007/169] fixing typos --- lib/util.php | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/lib/util.php b/lib/util.php index dbda3ac0ad..dacfd5b56f 100755 --- a/lib/util.php +++ b/lib/util.php @@ -228,7 +228,7 @@ class OC_Util { $webServerRestart = true; } - //common hint for all file permissons error messages + //common hint for all file permissions error messages $permissionsHint = 'Permissions can usually be fixed by ' .'giving the webserver write access to the root directory.'; @@ -560,9 +560,9 @@ class OC_Util { * @see OC_Util::callRegister() * @see OC_Util::isCallRegistered() * @description - * Also required for the client side to compute the piont in time when to + * Also required for the client side to compute the point in time when to * request a fresh token. The client will do so when nearly 97% of the - * timespan coded here has expired. + * time span coded here has expired. */ public static $callLifespan = 3600; // 3600 secs = 1 hour @@ -640,14 +640,15 @@ class OC_Util { * This function is used to sanitize HTML and should be applied on any * string or array of strings before displaying it on a web page. * - * @param string or array of strings + * @param string|array of strings * @return array with sanitized strings or a single sanitized string, depends on the input parameter. */ public static function sanitizeHTML( &$value ) { if (is_array($value)) { array_walk_recursive($value, 'OC_Util::sanitizeHTML'); } else { - $value = htmlentities((string)$value, ENT_QUOTES, 'UTF-8'); //Specify encoding for PHP<5.4 + //Specify encoding for PHP<5.4 + $value = htmlentities((string)$value, ENT_QUOTES, 'UTF-8'); } return $value; } @@ -756,7 +757,7 @@ class OC_Util { } /** - * Check if the setlocal call doesn't work. This can happen if the right + * Check if the setlocal call does not work. This can happen if the right * local packages are not available on the server. * @return bool */ @@ -828,8 +829,8 @@ class OC_Util { /** - * @brief Generates a cryptographical secure pseudorandom string - * @param Int with the length of the random string + * @brief Generates a cryptographic secure pseudo-random string + * @param Int $length of the random string * @return String * Please also update secureRNGAvailable if you change something here */ @@ -970,7 +971,7 @@ class OC_Util { /** * @brief Clear the opcode cache if one exists * This is necessary for writing to the config file - * in case the opcode cache doesn't revalidate files + * in case the opcode cache does not re-validate files * @return void */ public static function clearOpcodeCache() { From 8dd93c8c0288a11f04816bea2a58aee661ef9e97 Mon Sep 17 00:00:00 2001 From: kondou Date: Fri, 23 Aug 2013 07:30:42 +0200 Subject: [PATCH 008/169] Fix some phpdoc and camelcase --- lib/util.php | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/lib/util.php b/lib/util.php index dacfd5b56f..f343e78320 100755 --- a/lib/util.php +++ b/lib/util.php @@ -16,7 +16,7 @@ class OC_Util { /** * @brief Can be set up - * @param user string + * @param string $user * @return boolean * @description configure the initial filesystem based on the configuration */ @@ -51,7 +51,8 @@ class OC_Util { self::$rootMounted = true; } - if( $user != "" ) { //if we aren't logged in, there is no use to set up the filesystem + //if we aren't logged in, there is no use to set up the filesystem + if( $user != "" ) { $quota = self::getUserQuota($user); if ($quota !== \OC\Files\SPACE_UNLIMITED) { \OC\Files\Filesystem::addStorageWrapper(function($mountPoint, $storage) use ($quota, $user) { @@ -131,7 +132,7 @@ class OC_Util { /** * @brief add a javascript file * - * @param appid $application + * @param string $application * @param filename $file * @return void */ @@ -150,7 +151,7 @@ class OC_Util { /** * @brief add a css file * - * @param appid $application + * @param string $application * @param filename $file * @return void */ @@ -168,7 +169,7 @@ class OC_Util { /** * @brief Add a custom element to the header - * @param string tag tag name of the element + * @param string $tag tag name of the element * @param array $attributes array of attributes for the element * @param string $text the text content for the element * @return void @@ -184,8 +185,8 @@ class OC_Util { /** * @brief formats a timestamp in the "right" way * - * @param int timestamp $timestamp - * @param bool dateOnly option to omit time from the result + * @param int $timestamp + * @param bool $dateOnly option to omit time from the result * @return string timestamp * @description adjust to clients timezone if we know it */ @@ -418,12 +419,13 @@ class OC_Util { } /** - * Check for correct file permissions of data directory - * @return array arrays with error messages and hints - */ + * @brief Check for correct file permissions of data directory + * @paran string $dataDirectory + * @return array arrays with error messages and hints + */ public static function checkDataDirectoryPermissions($dataDirectory) { $errors = array(); - if (stristr(PHP_OS, 'WIN')) { + if (self::runningOnWindows()) { //TODO: permissions checks for windows hosts } else { $permissionsModHint = 'Please change the permissions to 0770 so that the directory' @@ -681,9 +683,9 @@ class OC_Util { $testContent = 'testcontent'; // creating a test file - $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename; + $testFile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$fileName; - if(file_exists($testfile)) {// already running this test, possible recursive call + if(file_exists($testFile)) {// already running this test, possible recursive call return false; } @@ -692,7 +694,7 @@ class OC_Util { @fclose($fp); // accessing the file via http - $url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$filename); + $url = OC_Helper::makeURLAbsolute(OC::$WEBROOT.'/data'.$fileName); $fp = @fopen($url, 'r'); $content=@fread($fp, 2048); @fclose($fp); @@ -701,7 +703,7 @@ class OC_Util { @unlink($testfile); // does it work ? - if($content==$testcontent) { + if($content==$testContent) { return false; } else { return true; From 4a08f7d710ced1c564e05471e1f873ecfb9ca161 Mon Sep 17 00:00:00 2001 From: kondou Date: Fri, 26 Jul 2013 12:20:11 +0200 Subject: [PATCH 009/169] Add basic avatars and gravatar --- config/config.sample.php | 6 ++++ core/img/defaultavatar.png | Bin 0 -> 12444 bytes core/templates/layout.user.php | 1 + lib/avatar.php | 59 ++++++++++++++++++++++++++++++++ lib/public/avatar.php | 15 ++++++++ lib/templatelayout.php | 5 +++ settings/admin.php | 1 + settings/ajax/setavatarmode.php | 12 +++++++ settings/js/admin.js | 6 ++++ settings/personal.php | 1 + settings/routes.php | 2 ++ settings/templates/admin.php | 37 ++++++++++++++++++++ settings/templates/personal.php | 13 +++++++ 13 files changed, 158 insertions(+) create mode 100644 core/img/defaultavatar.png create mode 100644 lib/avatar.php create mode 100644 lib/public/avatar.php create mode 100644 settings/ajax/setavatarmode.php diff --git a/config/config.sample.php b/config/config.sample.php index 24ba541ac5..fb2271339b 100644 --- a/config/config.sample.php +++ b/config/config.sample.php @@ -65,6 +65,12 @@ $CONFIG = array( /* URL to the parent directory of the 3rdparty directory, as seen by the browser */ "3rdpartyurl" => "", +/* What avatars to use. + * May be "none" for none, "local" for uploaded avatars, or "gravatar" for gravatars. + * Default is "local". + */ +"avatars" => "local", + /* Default app to load on login */ "defaultapp" => "files", diff --git a/core/img/defaultavatar.png b/core/img/defaultavatar.png new file mode 100644 index 0000000000000000000000000000000000000000..e9572080bbf3fb403a8b07b11d9271546c89c78e GIT binary patch literal 12444 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