diff options
author | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-25 17:08:18 -0400 |
---|---|---|
committer | Michael Gapczynski <mtgap@owncloud.com> | 2012-07-25 17:08:18 -0400 |
commit | 30b58f56771aa54304069d40a62070c06f5308fc (patch) | |
tree | e0bb2bba21c561f96d27bb9cfc09d714aa21d332 /lib | |
parent | 4d17ed2f71c8cbb0d34c039aa7953b2427ce5c78 (diff) | |
parent | f25ccaff59c135d7f1f22196bf266916ef131b35 (diff) | |
download | nextcloud-server-30b58f56771aa54304069d40a62070c06f5308fc.tar.gz nextcloud-server-30b58f56771aa54304069d40a62070c06f5308fc.zip |
Merge branch 'master' into share_api
Conflicts:
apps/calendar/js/loader.js
apps/contacts/index.php
apps/contacts/js/loader.js
apps/files/js/files.js
apps/files_sharing/sharedstorage.php
lib/filesystemview.php
Diffstat (limited to 'lib')
59 files changed, 1803 insertions, 1034 deletions
diff --git a/lib/MDB2/Driver/sqlite3.php b/lib/MDB2/Driver/sqlite3.php index 25927aff637..6bfccadad9a 100644 --- a/lib/MDB2/Driver/sqlite3.php +++ b/lib/MDB2/Driver/sqlite3.php @@ -1221,7 +1221,7 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common return $affected_rows; } - $result =& $this->db->_wrapResult($result, $this->result_types, + $result = $this->db->_wrapResult($result, $this->result_types, $result_class, $result_wrap_class, $this->limit, $this->offset); $this->db->debug($this->query, 'execute', array('is_manip' => $this->is_manip, 'when' => 'post', 'result' => $result)); return $result; diff --git a/lib/app.php b/lib/app.php index 4c2c43ec26b..56132c08671 100755 --- a/lib/app.php +++ b/lib/app.php @@ -27,7 +27,6 @@ * upgrading and removing apps. */ class OC_App{ - static private $init = false; static private $activeapp = ''; static private $navigation = array(); static private $settingsForms = array(); @@ -196,7 +195,7 @@ class OC_App{ // check if the app is compatible with this version of ownCloud $info=OC_App::getAppInfo($app); $version=OC_Util::getVersion(); - if(!isset($info['require']) or ($version[0]>$info['require'])){ + if(!isset($info['require']) or ($version[0]>$info['require'])){ OC_Log::write('core','App "'.$info['name'].'" can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR); return false; }else{ @@ -332,8 +331,8 @@ class OC_App{ } /** - * Get the path where to install apps - */ + * Get the path where to install apps + */ public static function getInstallPath() { if(OC_Config::getValue('appstoreenabled', true)==false) { return false; @@ -608,7 +607,7 @@ class OC_App{ //set remote/public handelers $appData=self::getAppInfo($appid); foreach($appData['remote'] as $name=>$path){ - OCP\CONFIG::setAppValue('core', 'remote_'.$name, $path); + OCP\CONFIG::setAppValue('core', 'remote_'.$name, $appid.'/'.$path); } foreach($appData['public'] as $name=>$path){ OCP\CONFIG::setAppValue('core', 'public_'.$name, $appid.'/'.$path); diff --git a/lib/archive/zip.php b/lib/archive/zip.php index 6631a649b16..b2d6674d639 100644 --- a/lib/archive/zip.php +++ b/lib/archive/zip.php @@ -11,7 +11,6 @@ class OC_Archive_ZIP extends OC_Archive{ * @var ZipArchive zip */ private $zip=null; - private $success=false; private $path; function __construct($source){ @@ -74,8 +73,7 @@ class OC_Archive_ZIP extends OC_Archive{ * @return int */ function mtime($path){ - $stat=$this->zip->statName($path); - return $stat['mtime']; + return filemtime($this->path); } /** * get the files in a folder diff --git a/lib/base.php b/lib/base.php index fe69ad70c0f..888dc265d64 100644 --- a/lib/base.php +++ b/lib/base.php @@ -83,6 +83,9 @@ class OC{ elseif(strpos($className,'OCP\\')===0){ require_once 'public/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php'); } + elseif(strpos($className,'OCA\\')===0){ + require_once 'apps/'.strtolower(str_replace('\\','/',substr($className,3)) . '.php'); + } elseif(strpos($className,'Sabre_')===0) { require_once str_replace('_','/',$className) . '.php'; } @@ -345,7 +348,7 @@ class OC{ $_SESSION['user_id'] = ''; } - OC_User::useBackend( OC_Config::getValue( "userbackend", "database" )); + OC_User::useBackend(new OC_User_Database()); OC_Group::useBackend(new OC_Group_Database()); // Load Apps diff --git a/lib/cache.php b/lib/cache.php index 1f269174fad..55f189a5da8 100644 --- a/lib/cache.php +++ b/lib/cache.php @@ -7,48 +7,96 @@ */ class OC_Cache { + /** + * @var OC_Cache $user_cache + */ static protected $user_cache; + /** + * @var OC_Cache $global_cache + */ static protected $global_cache; + /** + * @var OC_Cache $global_cache_fast + */ + static protected $global_cache_fast; + /** + * @var OC_Cache $user_cache_fast + */ + static protected $user_cache_fast; + static protected $isFast=null; - static public function getGlobalCache() { + /** + * get the global cache + * @return OC_Cache + */ + static public function getGlobalCache($fast=false) { if (!self::$global_cache) { - $fast_cache = null; - if (!$fast_cache && function_exists('xcache_set')) { - $fast_cache = new OC_Cache_XCache(true); + self::$global_cache_fast = null; + if (!self::$global_cache_fast && function_exists('xcache_set')) { + self::$global_cache_fast = new OC_Cache_XCache(true); } - if (!$fast_cache && function_exists('apc_store')) { - $fast_cache = new OC_Cache_APC(true); + if (!self::$global_cache_fast && function_exists('apc_store')) { + self::$global_cache_fast = new OC_Cache_APC(true); } + self::$global_cache = new OC_Cache_FileGlobal(); - if ($fast_cache) { - self::$global_cache = new OC_Cache_Broker($fast_cache, self::$global_cache); + if (self::$global_cache_fast) { + self::$global_cache = new OC_Cache_Broker(self::$global_cache_fast, self::$global_cache); + } + } + if($fast){ + if(self::$global_cache_fast){ + return self::$global_cache_fast; + }else{ + return false; } } return self::$global_cache; } - static public function getUserCache() { + /** + * get the user cache + * @return OC_Cache + */ + static public function getUserCache($fast=false) { if (!self::$user_cache) { - $fast_cache = null; - if (!$fast_cache && function_exists('xcache_set')) { - $fast_cache = new OC_Cache_XCache(); + self::$user_cache_fast = null; + if (!self::$user_cache_fast && function_exists('xcache_set')) { + self::$user_cache_fast = new OC_Cache_XCache(); } - if (!$fast_cache && function_exists('apc_store')) { - $fast_cache = new OC_Cache_APC(); + if (!self::$user_cache_fast && function_exists('apc_store')) { + self::$user_cache_fast = new OC_Cache_APC(); } + self::$user_cache = new OC_Cache_File(); - if ($fast_cache) { - self::$user_cache = new OC_Cache_Broker($fast_cache, self::$user_cache); + if (self::$user_cache_fast) { + self::$user_cache = new OC_Cache_Broker(self::$user_cache_fast, self::$user_cache); + } + } + + if($fast){ + if(self::$user_cache_fast){ + return self::$user_cache_fast; + }else{ + return false; } } return self::$user_cache; } + /** + * get a value from the user cache + * @return mixed + */ static public function get($key) { $user_cache = self::getUserCache(); return $user_cache->get($key); } + /** + * set a value in the user cache + * @return bool + */ static public function set($key, $value, $ttl=0) { if (empty($key)) { return false; @@ -57,19 +105,43 @@ class OC_Cache { return $user_cache->set($key, $value, $ttl); } + /** + * check if a value is set in the user cache + * @return bool + */ static public function hasKey($key) { $user_cache = self::getUserCache(); return $user_cache->hasKey($key); } + /** + * remove an item from the user cache + * @return bool + */ static public function remove($key) { $user_cache = self::getUserCache(); return $user_cache->remove($key); } - static public function clear() { + /** + * clear the user cache of all entries starting with a prefix + * @param string prefix (optional) + * @return bool + */ + static public function clear($prefix='') { $user_cache = self::getUserCache(); - return $user_cache->clear(); + return $user_cache->clear($prefix); + } + + /** + * check if a fast memory based cache is available + * @return true + */ + static public function isFast() { + if(is_null(self::$isFast)){ + self::$isFast=function_exists('xcache_set') || function_exists('apc_store'); + } + return self::$isFast; } } diff --git a/lib/cache/apc.php b/lib/cache/apc.php index 6cf47d0c158..c192fe2f196 100644 --- a/lib/cache/apc.php +++ b/lib/cache/apc.php @@ -43,14 +43,15 @@ class OC_Cache_APC { return apc_delete($this->getNamespace().$key); } - public function clear(){ - $ns = $this->getNamespace(); + public function clear($prefix=''){ + $ns = $this->getNamespace().$prefix; $cache = apc_cache_info('user'); foreach($cache['cache_list'] as $entry) { if (strpos($entry['info'], $ns) === 0) { apc_delete($entry['info']); } } + return true; } } if(!function_exists('apc_exists')) { diff --git a/lib/cache/broker.php b/lib/cache/broker.php index 931d0dd407e..c2aceabaf53 100644 --- a/lib/cache/broker.php +++ b/lib/cache/broker.php @@ -46,8 +46,8 @@ class OC_Cache_Broker { return $this->slow_cache->remove($key); } - public function clear(){ - $this->fast_cache->clear(); - $this->slow_cache->clear(); + public function clear($prefix=''){ + $this->fast_cache->clear($prefix); + $this->slow_cache->clear($prefix); } } diff --git a/lib/cache/file.php b/lib/cache/file.php index 0b7d3e30508..562c3d17167 100644 --- a/lib/cache/file.php +++ b/lib/cache/file.php @@ -62,15 +62,16 @@ class OC_Cache_File{ return $storage->unlink($key); } - public function clear(){ + public function clear($prefix=''){ $storage = $this->getStorage(); if($storage and $storage->is_dir('/')){ $dh=$storage->opendir('/'); while($file=readdir($dh)){ - if($file!='.' and $file!='..'){ + if($file!='.' and $file!='..' and ($prefix==='' || strpos($file, $prefix) === 0)){ $storage->unlink('/'.$file); } } } + return true; } } diff --git a/lib/cache/xcache.php b/lib/cache/xcache.php index bd55cee8f6b..951f9b47545 100644 --- a/lib/cache/xcache.php +++ b/lib/cache/xcache.php @@ -43,7 +43,8 @@ class OC_Cache_XCache { return xcache_unset($this->getNamespace().$key); } - public function clear(){ - return xcache_unset_by_prefix($this->getNamespace()); + public function clear($prefix=''){ + xcache_unset_by_prefix($this->getNamespace().$prefix); + return true; } } diff --git a/lib/connector/sabre/auth.php b/lib/connector/sabre/auth.php index ee680391626..99f696e3a07 100644 --- a/lib/connector/sabre/auth.php +++ b/lib/connector/sabre/auth.php @@ -31,13 +31,18 @@ class OC_Connector_Sabre_Auth extends Sabre_DAV_Auth_Backend_AbstractBasic { * @return bool */ protected function validateUserPass($username, $password){ - OC_Util::setUpFS();//login hooks may need early access to the filesystem - if(OC_User::login($username,$password)){ - OC_Util::setUpFS($username); + if (OC_User::isLoggedIn()) { + OC_Util::setupFS($username); return true; - } - else{ - return false; + } else { + OC_Util::setUpFS();//login hooks may need early access to the filesystem + if(OC_User::login($username,$password)){ + OC_Util::setUpFS($username); + return true; + } + else{ + return false; + } } } } diff --git a/lib/connector/sabre/client.php b/lib/connector/sabre/client.php index 87f9d59b3ae..7e8f21264f9 100644 --- a/lib/connector/sabre/client.php +++ b/lib/connector/sabre/client.php @@ -68,18 +68,13 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { // Automatically follow redirects
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_MAXREDIRS => 5,
- CURLOPT_SSL_VERIFYPEER => true,
- //CURLOPT_SSL_VERIFYPEER => false,
);
-
+
if($this->trustedCertificates) {
$curlSettings[CURLOPT_CAINFO] = $this->trustedCertificates;
}
-
+
switch ($method) {
- case 'PUT':
- $curlSettings[CURLOPT_PUT] = true;
- break;
case 'HEAD' :
// do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
@@ -110,8 +105,15 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { $curlSettings[CURLOPT_PROXY] = $this->proxy;
}
- if ($this->userName) {
- $curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
+ if ($this->userName && $this->authType) {
+ $curlType = 0;
+ if ($this->authType & self::AUTH_BASIC) {
+ $curlType |= CURLAUTH_BASIC;
+ }
+ if ($this->authType & self::AUTH_DIGEST) {
+ $curlType |= CURLAUTH_DIGEST;
+ }
+ $curlSettings[CURLOPT_HTTPAUTH] = $curlType;
$curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
}
@@ -167,5 +169,5 @@ class OC_Connector_Sabre_Client extends Sabre_DAV_Client { return $response;
- }
+ }
}
\ No newline at end of file diff --git a/lib/connector/sabre/directory.php b/lib/connector/sabre/directory.php index b75bb5c50f5..0842fc4fc65 100644 --- a/lib/connector/sabre/directory.php +++ b/lib/connector/sabre/directory.php @@ -26,17 +26,33 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa /** * Creates a new file in the directory * - * data is a readable stream resource + * Data will either be supplied as a stream resource, or in certain cases + * as a string. Keep in mind that you may have to support either. + * + * After succesful creation of the file, you may choose to return the ETag + * of the new file here. + * + * The returned ETag must be surrounded by double-quotes (The quotes should + * be part of the actual string). + * + * If you cannot accurately determine the ETag, you should not return it. + * If you don't store the file exactly as-is (you're transforming it + * somehow) you should also not return an ETag. + * + * This means that if a subsequent GET to this new file does not exactly + * return the same contents of what was submitted here, you are strongly + * recommended to omit the ETag. * * @param string $name Name of the file - * @param resource $data Initial payload - * @return void + * @param resource|string $data Initial payload + * @return null|string */ public function createFile($name, $data = null) { $newPath = $this->path . '/' . $name; OC_Filesystem::file_put_contents($newPath,$data); + return OC_Connector_Sabre_Node::getETagPropertyForFile($newPath); } /** @@ -146,7 +162,7 @@ class OC_Connector_Sabre_Directory extends OC_Connector_Sabre_Node implements Sa * @return array */ public function getQuotaInfo() { - $rootInfo=OC_FileCache::get(''); + $rootInfo=OC_FileCache_Cached::get(''); return array( $rootInfo['size'], OC_Filesystem::free_space() diff --git a/lib/connector/sabre/file.php b/lib/connector/sabre/file.php index e4dc8c93445..80f0a0ab4d8 100644 --- a/lib/connector/sabre/file.php +++ b/lib/connector/sabre/file.php @@ -26,13 +26,28 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D /** * Updates the data * + * The data argument is a readable stream resource. + * + * After a succesful put operation, you may choose to return an ETag. The + * etag must always be surrounded by double-quotes. These quotes must + * appear in the actual string you're returning. + * + * Clients may use the ETag from a PUT request to later on make sure that + * when they update the file, the contents haven't changed in the mean + * time. + * + * If you don't plan to store the file byte-by-byte, and you return a + * different object on a subsequent GET you are strongly recommended to not + * return an ETag, and just return null. + * * @param resource $data - * @return void + * @return string|null */ public function put($data) { OC_Filesystem::file_put_contents($this->path,$data); + return OC_Connector_Sabre_Node::getETagPropertyForFile($this->path); } /** @@ -42,7 +57,7 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D */ public function get() { - return OC_Filesystem::readfile($this->path); + return OC_Filesystem::fopen($this->path,'rb'); } @@ -79,9 +94,11 @@ class OC_Connector_Sabre_File extends OC_Connector_Sabre_Node implements Sabre_D * @return mixed */ public function getETag() { - - return null; - + $properties = $this->getProperties(array(self::GETETAG_PROPERTYNAME)); + if (isset($properties[self::GETETAG_PROPERTYNAME])) { + return $properties[self::GETETAG_PROPERTYNAME]; + } + return $this->getETagPropertyForFile($this->path); } /** diff --git a/lib/connector/sabre/locks.php b/lib/connector/sabre/locks.php index 94382e68a1a..e95dcf02d27 100644 --- a/lib/connector/sabre/locks.php +++ b/lib/connector/sabre/locks.php @@ -108,7 +108,7 @@ class OC_Connector_Sabre_Locks extends Sabre_DAV_Locks_Backend_Abstract { $locks = $this->getLocks($uri,false); $exists = false; - foreach($locks as $k=>$lock) { + foreach($locks as $lock) { if ($lock->token == $lockInfo->token) $exists = true; } diff --git a/lib/connector/sabre/node.php b/lib/connector/sabre/node.php index be315a0ffd9..663970487fb 100644 --- a/lib/connector/sabre/node.php +++ b/lib/connector/sabre/node.php @@ -22,6 +22,7 @@ */ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IProperties { + const GETETAG_PROPERTYNAME = '{DAV:}getetag'; /** * The path to the current node @@ -141,6 +142,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr public function updateProperties($properties) { $existing = $this->getProperties(array()); foreach($properties as $propertyName => $propertyValue) { + $propertyName = preg_replace("/^{.*}/", "", $propertyName); // remove leading namespace from property name // If it was null, we need to delete the property if (is_null($propertyValue)) { if(array_key_exists( $propertyName, $existing )){ @@ -178,7 +180,7 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr * @param array $properties * @return void */ - function getProperties($properties) { + public function getProperties($properties) { if (is_null($this->property_cache)) { $query = OC_DB::prepare( 'SELECT * FROM *PREFIX*properties WHERE userid = ? AND propertypath = ?' ); $result = $query->execute( array( OC_User::getUser(), $this->path )); @@ -200,4 +202,29 @@ abstract class OC_Connector_Sabre_Node implements Sabre_DAV_INode, Sabre_DAV_IPr } return $props; } + + /** + * Returns the ETag surrounded by double-quotes for this path. + * @param string $path Path of the file + * @return string|null Returns null if the ETag can not effectively be determined + */ + static public function getETagPropertyForFile($path) { + $tag = OC_Filesystem::hash('md5', $path); + if (empty($tag)) { + return null; + } + $etag = '"'.$tag.'"'; + $query = OC_DB::prepare( 'INSERT INTO *PREFIX*properties (userid,propertypath,propertyname,propertyvalue) VALUES(?,?,?,?)' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME, $etag )); + return $etag; + } + + /** + * Remove the ETag from the cache. + * @param string $path Path of the file + */ + static public function removeETagPropertyForFile($path) { + $query = OC_DB::prepare( 'DELETE FROM *PREFIX*properties WHERE userid = ? AND propertypath = ? AND propertyname = ?' ); + $query->execute( array( OC_User::getUser(), $path, self::GETETAG_PROPERTYNAME )); + } } diff --git a/lib/db.php b/lib/db.php index 2a06d72ea32..6971fe4a583 100644 --- a/lib/db.php +++ b/lib/db.php @@ -33,8 +33,6 @@ class OC_DB { static private $MDB2=false; static private $PDO=false; static private $schema=false; - static private $affected=0; - static private $result=false; static private $inTransaction=false; static private $prefix=null; static private $type=null; @@ -222,7 +220,7 @@ class OC_DB { echo( '<b>can not connect to database, using '.$type.'. ('.self::$MDB2->getUserInfo().')</center>'); OC_Log::write('core',self::$MDB2->getUserInfo(),OC_Log::FATAL); OC_Log::write('core',self::$MDB2->getMessage(),OC_Log::FATAL); - die( $error ); + die(); } // We always, really always want associative arrays @@ -370,9 +368,6 @@ class OC_DB { if( $definition instanceof MDB2_Schema_Error ){ die( $definition->getMessage().': '.$definition->getUserInfo()); } -// if(OC_Config::getValue('dbtype','sqlite')=='sqlite'){ -// $definition['overwrite']=true;//always overwrite for sqlite -// } $ret=self::$schema->createDatabase( $definition ); // Die in case something went wrong @@ -519,8 +514,9 @@ class OC_DB { // Delete our temporary file unlink( $file2 ); - foreach($definition['tables'] as $name=>$table){ - self::dropTable($name); + $tables=array_keys($definition['tables']); + foreach($tables as $table){ + self::dropTable($table); } } @@ -528,8 +524,7 @@ class OC_DB { * @brief replaces the owncloud tables with a new set * @param $file string path to the MDB2 xml db export file */ - public static function replaceDB( $file ){ - + public static function replaceDB( $file ){ $apps = OC_App::getAllApps(); self::beginTransaction(); // Delete the old tables diff --git a/lib/eventsource.php b/lib/eventsource.php index cf10660b94c..95af2e471bc 100644 --- a/lib/eventsource.php +++ b/lib/eventsource.php @@ -36,12 +36,15 @@ class OC_EventSource{ header('Cache-Control: no-cache'); $this->fallback=isset($_GET['fallback']) and $_GET['fallback']=='true'; if($this->fallback){ - $fallBackId=$_GET['fallback_id']; + $this->fallBackId=$_GET['fallback_id']; header("Content-Type: text/html"); echo str_repeat('<span></span>'.PHP_EOL,10); //dummy data to keep IE happy }else{ header("Content-Type: text/event-stream"); } + if( !OC_Util::isCallRegistered()){ + exit(); + } flush(); } diff --git a/lib/exception.php b/lib/exception.php new file mode 100644 index 00000000000..db516fc12d2 --- /dev/null +++ b/lib/exception.php @@ -0,0 +1,93 @@ +<?php +/** + * ownCloud + * + * @author Georg Ehrke + * @copyright 2012 georg@owncloud.com + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ +class OC_Exception extends Exception{ + + function __construct($message = null, $code = 0, $file = null, $line = null){ + parent::__construct($message, $code); + if(!is_null($file)){ + $this->file = $file; + } + if(!is_null($line)){ + $this->line = $line; + } + $this->writelog(); + } + + private function writelog(){ + @OC_Log::write(OC_App::getCurrentApp(), $this->getMessage() . '-' . $this->getFile() . '-' . $this->getLine(), OC_Log::FATAL); + } + + private function generatesysinfo(){ + return array('phpversion' => PHP_VERSION, + 'os' => php_uname('s'), + 'osrelease' => php_uname('r'), + 'osarchitecture' => php_uname('m'), + 'phpserverinterface' => php_sapi_name(), + 'serverprotocol' => $_SERVER['SERVER_PROTOCOL'], + 'requestmethod' => $_SERVER['REQUEST_METHOD'], + 'https' => ($_SERVER['HTTPS']==''?'false':'true'), + 'database'=>(@OC_Config::getValue('dbtype')!=''?@OC_Config::getValue('dbtype'):'') + ); + } + + function __toString(){ + $tmpl = new OC_Template('core', 'exception', 'guest'); + $tmpl->assign('showsysinfo', true); + $tmpl->assign('message', $this->getMessage()); + $tmpl->assign('code', $this->getCode()); + $tmpl->assign('file', $this->getFile()); + $tmpl->assign('line', $this->getLine()); + $tmpl->assign('sysinfo', $this->generatesysinfo()); + $tmpl->printPage(); + } +} + +function oc_exceptionhandler($exception){ + switch($exception->getCode()){ + case E_NOTICE: + case E_DEPRECATED: + case E_USER_NOTICE: + case E_USER_DEPRECATED: + break; + default: + throw new OC_Exception($exception->getMessage(), $exception->getCode(), $exception->getFile(), $exception->getLine()); + break; + } + return true; +} + +function oc_errorhandler($errno , $errstr , $errfile , $errline){ + switch($errno){ + case E_NOTICE: + case E_DEPRECATED: + case E_USER_NOTICE: + case E_USER_DEPRECATED: + break; + default: + throw new OC_Exception($errstr, $errno, $errfile, $errline); + break; + } + return true; +} +set_exception_handler('oc_exceptionhandler'); +set_error_handler('oc_errorhandler'); +error_reporting(E_ERROR | E_WARNING | E_PARSE);
\ No newline at end of file diff --git a/lib/filecache.php b/lib/filecache.php index b6f4d23986b..8211637d141 100644 --- a/lib/filecache.php +++ b/lib/filecache.php @@ -98,6 +98,10 @@ class OC_FileCache{ if(OC_DB::isError($result)){ OC_Log::write('files','error while writing file('.$path.') to cache',OC_Log::ERROR); } + + if($cache=OC_Cache::getUserCache(true)){ + $cache->remove('fileid/'.$path);//ensure we don't have -1 cached + } } /** @@ -126,7 +130,7 @@ class OC_FileCache{ $query=OC_DB::prepare($sql); $result=$query->execute($arguments); if(OC_DB::isError($result)){ - OC_Log::write('files','error while updating file('.$path.') in cache',OC_Log::ERROR); + OC_Log::write('files','error while updating file('.$id.') in cache',OC_Log::ERROR); } } @@ -146,6 +150,11 @@ class OC_FileCache{ $query=OC_DB::prepare('UPDATE *PREFIX*fscache SET parent=? ,name=?, path=?, path_hash=? WHERE path_hash=?'); $query->execute(array($newParent,basename($newPath),$newPath,md5($newPath),md5($oldPath))); + if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$oldPath)){ + $cache->set('fileid/'.$newPath,$cache->get('fileid/'.$oldPath)); + $cache->remove('fileid/'.$oldPath); + } + $query=OC_DB::prepare('SELECT path FROM *PREFIX*fscache WHERE path LIKE ?'); $oldLength=strlen($oldPath); $updateQuery=OC_DB::prepare('UPDATE *PREFIX*fscache SET path=?, path_hash=? WHERE path_hash=?'); @@ -153,6 +162,11 @@ class OC_FileCache{ $old=$row['path']; $new=$newPath.substr($old,$oldLength); $updateQuery->execute(array($new,md5($new),md5($old))); + + if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$old)){ + $cache->set('fileid/'.$new,$cache->get('fileid/'.$old)); + $cache->remove('fileid/'.$old); + } } } @@ -171,6 +185,8 @@ class OC_FileCache{ //delete everything inside the folder $query=OC_DB::prepare('DELETE FROM *PREFIX*fscache WHERE path LIKE ?'); $query->execute(array($root.$path.'/%')); + + OC_Cache::remove('fileid/'.$root.$path); } /** @@ -245,9 +261,14 @@ class OC_FileCache{ if($root===false){ $root=OC_Filesystem::getRoot(); } + + $fullPath=$root.$path; + if(($cache=OC_Cache::getUserCache(true)) && $cache->hasKey('fileid/'.$fullPath)){ + return $cache->get('fileid/'.$fullPath); + } $query=OC_DB::prepare('SELECT id FROM *PREFIX*fscache WHERE path_hash=?'); - $result=$query->execute(array(md5($root.$path))); + $result=$query->execute(array(md5($fullPath))); if(OC_DB::isError($result)){ OC_Log::write('files','error while getting file id of '.$path,OC_Log::ERROR); return -1; @@ -255,10 +276,15 @@ class OC_FileCache{ $result=$result->fetchRow(); if(is_array($result)){ - return $result['id']; + $id=$result['id']; }else{ - return -1; + $id=-1; } + if($cache=OC_Cache::getUserCache(true)){ + $cache->set('fileid/'.$fullPath,$id); + } + + return $id; } /** @@ -303,7 +329,7 @@ class OC_FileCache{ */ public static function increaseSize($path,$sizeDiff, $root=false){ if($sizeDiff==0) return; - $id=self::getId($path,''); + $id=self::getId($path,$root); while($id!=-1){//walk up the filetree increasing the size of all parent folders $query=OC_DB::prepare('UPDATE *PREFIX*fscache SET size=size+? WHERE id=?'); $query->execute(array($sizeDiff,$id)); diff --git a/lib/filecache/update.php b/lib/filecache/update.php index dd77f491ca0..93b632acb4e 100644 --- a/lib/filecache/update.php +++ b/lib/filecache/update.php @@ -207,7 +207,6 @@ class OC_FileCache_Update{ $cached=OC_FileCache_Cached::get($oldPath,$root); $oldSize=$cached['size']; - $size=$view->filesize($newPath); OC_FileCache::increaseSize(dirname($oldPath),-$oldSize,$root); OC_FileCache::increaseSize(dirname($newPath),$oldSize,$root); OC_FileCache::move($oldPath,$newPath); diff --git a/lib/filestorage.php b/lib/filestorage.php index c104fca87fe..5d864b5d7bb 100644 --- a/lib/filestorage.php +++ b/lib/filestorage.php @@ -24,7 +24,7 @@ * Provde a common interface to all different storage options */ abstract class OC_Filestorage{ - public function __construct($parameters){} + abstract public function __construct($parameters); abstract public function mkdir($path); abstract public function rmdir($path); abstract public function opendir($path); @@ -48,7 +48,7 @@ abstract class OC_Filestorage{ abstract public function copy($path1,$path2); abstract public function fopen($path,$mode); abstract public function getMimeType($path); - abstract public function hash($type,$path,$raw); + abstract public function hash($type,$path,$raw = false); abstract public function free_space($path); abstract public function search($query); abstract public function touch($path, $mtime=null); diff --git a/lib/filestorage/common.php b/lib/filestorage/common.php index 633c2fdfc76..00c76796c57 100644 --- a/lib/filestorage/common.php +++ b/lib/filestorage/common.php @@ -204,7 +204,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage { unlink($tmpFile); return $mime; } - public function hash($type,$path,$raw){ + public function hash($type,$path,$raw = false){ $tmpFile=$this->getLocalFile(); $hash=hash($type,$tmpFile,$raw); unlink($tmpFile); @@ -229,7 +229,7 @@ abstract class OC_Filestorage_Common extends OC_Filestorage { } $tmpFile=OC_Helper::tmpFile($extension); $target=fopen($tmpFile,'w'); - $count=OC_Helper::streamCopy($source,$target); + OC_Helper::streamCopy($source,$target); return $tmpFile; } // abstract public function touch($path, $mtime=null); diff --git a/lib/filestorage/local.php b/lib/filestorage/local.php index 658e14eaf9d..6be04db96ae 100644 --- a/lib/filestorage/local.php +++ b/lib/filestorage/local.php @@ -4,7 +4,6 @@ */ class OC_Filestorage_Local extends OC_Filestorage_Common{ protected $datadir; - private static $mimetypes=null; public function __construct($arguments){ $this->datadir=$arguments['datadir']; if(substr($this->datadir,-1)!=='/'){ @@ -41,7 +40,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ } public function filesize($path){ if($this->is_dir($path)){ - return $this->getFolderSize($path); + return 0; }else{ return filesize($this->datadir.$path); } @@ -157,7 +156,7 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ return $return; } - public function hash($type,$path,$raw){ + public function hash($path,$type,$raw=false){ return hash_file($type,$this->datadir.$path,$raw); } @@ -187,15 +186,6 @@ class OC_Filestorage_Local extends OC_Filestorage_Common{ } /** - * @brief get the size of folder and it's content - * @param string $path file path - * @return int size of folder and it's content - */ - public function getFolderSize($path){ - return 0;//depricated, use OC_FileCach instead - } - - /** * check if a file or folder has been updated since $time * @param int $time * @return bool diff --git a/lib/filesystem.php b/lib/filesystem.php index 5dfcaa107b8..e5817a1bc82 100644 --- a/lib/filesystem.php +++ b/lib/filesystem.php @@ -46,105 +46,106 @@ class OC_Filesystem{ static private $storages=array(); static private $mounts=array(); - static private $storageTypes=array(); public static $loaded=false; - private $fakeRoot=''; + /** + * @var OC_Filestorage $defaultInstance + */ static private $defaultInstance; - /** - * classname which used for hooks handling - * used as signalclass in OC_Hooks::emit() - */ - const CLASSNAME = 'OC_Filesystem'; - - /** - * signalname emited before file renaming - * @param oldpath - * @param newpath - */ - const signal_rename = 'rename'; - - /** - * signal emited after file renaming - * @param oldpath - * @param newpath - */ - const signal_post_rename = 'post_rename'; - - /** - * signal emited before file/dir creation - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_create = 'create'; - - /** - * signal emited after file/dir creation - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_post_create = 'post_create'; - - /** - * signal emits before file/dir copy - * @param oldpath - * @param newpath - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_copy = 'copy'; - - /** - * signal emits after file/dir copy - * @param oldpath - * @param newpath - */ - const signal_post_copy = 'post_copy'; - - /** - * signal emits before file/dir save - * @param path - * @param run changing this flag to false in hook handler will cancel event - */ - const signal_write = 'write'; - - /** - * signal emits after file/dir save - * @param path - */ - const signal_post_write = 'post_write'; - - /** - * signal emits when reading file/dir - * @param path - */ - const signal_read = 'read'; - - /** - * signal emits when removing file/dir - * @param path - */ - const signal_delete = 'delete'; - - /** - * parameters definitions for signals - */ - const signal_param_path = 'path'; - const signal_param_oldpath = 'oldpath'; - const signal_param_newpath = 'newpath'; - - /** - * run - changing this flag to false in hook handler will cancel event - */ - const signal_param_run = 'run'; - - /** - * get the mountpoint of the storage object for a path - ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account - * - * @param string path - * @return string - */ + /** + * classname which used for hooks handling + * used as signalclass in OC_Hooks::emit() + */ + const CLASSNAME = 'OC_Filesystem'; + + /** + * signalname emited before file renaming + * @param oldpath + * @param newpath + */ + const signal_rename = 'rename'; + + /** + * signal emited after file renaming + * @param oldpath + * @param newpath + */ + const signal_post_rename = 'post_rename'; + + /** + * signal emited before file/dir creation + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_create = 'create'; + + /** + * signal emited after file/dir creation + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_post_create = 'post_create'; + + /** + * signal emits before file/dir copy + * @param oldpath + * @param newpath + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_copy = 'copy'; + + /** + * signal emits after file/dir copy + * @param oldpath + * @param newpath + */ + const signal_post_copy = 'post_copy'; + + /** + * signal emits before file/dir save + * @param path + * @param run changing this flag to false in hook handler will cancel event + */ + const signal_write = 'write'; + + /** + * signal emits after file/dir save + * @param path + */ + const signal_post_write = 'post_write'; + + /** + * signal emits when reading file/dir + * @param path + */ + const signal_read = 'read'; + + /** + * signal emits when removing file/dir + * @param path + */ + const signal_delete = 'delete'; + + /** + * parameters definitions for signals + */ + const signal_param_path = 'path'; + const signal_param_oldpath = 'oldpath'; + const signal_param_newpath = 'newpath'; + + /** + * run - changing this flag to false in hook handler will cancel event + */ + const signal_param_run = 'run'; + + /** + * get the mountpoint of the storage object for a path + ( note: because a storage is not always mounted inside the fakeroot, the returned mountpoint is relative to the absolute root of the filesystem and doesn't take the chroot into account + * + * @param string path + * @return string + */ static public function getMountPoint($path){ OC_Hook::emit(self::CLASSNAME,'get_mountpoint',array('path'=>$path)); if(!$path){ @@ -155,7 +156,8 @@ class OC_Filesystem{ } $path=str_replace('//', '/',$path); $foundMountPoint=''; - foreach(OC_Filesystem::$mounts as $mountpoint=>$storage){ + $mountPoints=array_keys(OC_Filesystem::$mounts); + foreach($mountPoints as $mountpoint){ if($mountpoint==$path){ return $mountpoint; } @@ -260,10 +262,7 @@ class OC_Filesystem{ * tear down the filesystem, removing all storage providers */ static public function tearDown(){ - foreach(self::$storages as $mountpoint=>$storage){ - unset(self::$storages[$mountpoint]); - } - $fakeRoot=''; + self::$storages=array(); } /** @@ -287,7 +286,7 @@ class OC_Filesystem{ * @return bool */ static public function chroot($fakeRoot){ - return self::$defaultInstance->chroot($path); + return self::$defaultInstance->chroot($fakeRoot); } /** @@ -320,22 +319,8 @@ class OC_Filesystem{ if(substr($mountpoint,-1)!=='/'){ $mountpoint=$mountpoint.'/'; } - if (self::getView() != null && $mountpoint != '/' && !self::is_dir(basename($mountpoint))) { - self::mkdir(basename($mountpoint)); - } self::$mounts[$mountpoint]=array('class'=>$class,'arguments'=>$arguments); } - - /** - * create all storage backends mounted in the filesystem - */ - static private function mountAll(){ - foreach(self::$mounts as $mountPoint=>$mount){ - if(!isset(self::$storages[$mountPoint])){ - self::$storages[$mountPoint]=self::createStorage($mount['type'],$mount['arguments']); - } - } - } /** * return the path to a local version of the file @@ -488,8 +473,8 @@ class OC_Filesystem{ static public function getMimeType($path){ return self::$defaultInstance->getMimeType($path); } - static public function hash($type,$path){ - return self::$defaultInstance->hash($type,$path); + static public function hash($type,$path, $raw = false){ + return self::$defaultInstance->hash($type,$path, $raw); } static public function free_space($path='/'){ @@ -506,9 +491,17 @@ class OC_Filesystem{ * @return bool */ static public function hasUpdated($path,$time){ - return self::$defaultInstance->hasUpdated($path); + return self::$defaultInstance->hasUpdated($path,$time); + } + + static public function removeETagHook($params) { + $path=$params['path']; + OC_Connector_Sabre_Node::removeETagPropertyForFile($path); } } +OC_Hook::connect('OC_Filesystem','post_write', 'OC_Filesystem','removeETagHook'); +OC_Hook::connect('OC_Filesystem','post_delete','OC_Filesystem','removeETagHook'); +OC_Hook::connect('OC_Filesystem','post_rename','OC_Filesystem','removeETagHook'); OC_Util::setupFS(); require_once('filecache.php'); diff --git a/lib/filesystemview.php b/lib/filesystemview.php index 05731299467..af1a578ec6a 100644 --- a/lib/filesystemview.php +++ b/lib/filesystemview.php @@ -22,19 +22,19 @@ /** - * Class to provide access to ownCloud filesystem via a "view", and methods for - * working with files within that view (e.g. read, write, delete, etc.). Each - * view is restricted to a set of directories via a virtual root. The default view - * uses the currently logged in user's data directory as root (parts of + * Class to provide access to ownCloud filesystem via a "view", and methods for + * working with files within that view (e.g. read, write, delete, etc.). Each + * view is restricted to a set of directories via a virtual root. The default view + * uses the currently logged in user's data directory as root (parts of * OC_Filesystem are merely a wrapper for OC_FilesystemView). - * + * * Apps that need to access files outside of the user data folders (to modify files * belonging to a user other than the one currently logged in, for example) should * use this class directly rather than using OC_Filesystem, or making use of PHP's - * built-in file manipulation functions. This will ensure all hooks and proxies + * built-in file manipulation functions. This will ensure all hooks and proxies * are triggered correctly. * - * Filesystem functions are not called directly; they are passed to the correct + * Filesystem functions are not called directly; they are passed to the correct * OC_Filestorage object */ @@ -43,11 +43,11 @@ class OC_FilesystemView { private $internal_path_cache=array(); private $storage_cache=array(); - public function __construct($root){ + public function __construct($root) { $this->fakeRoot=$root; } - public function getAbsolutePath($path){ + public function getAbsolutePath($path) { if(!$path){ $path='/'; } @@ -63,9 +63,9 @@ class OC_FilesystemView { * @param string fakeRoot * @return bool */ - public function chroot($fakeRoot){ + public function chroot($fakeRoot) { if(!$fakeRoot==''){ - if($fakeRoot[0]!=='/'){ + if($fakeRoot[0]!=='/') { $fakeRoot='/'.$fakeRoot; } } @@ -76,7 +76,7 @@ class OC_FilesystemView { * get the fake root * @return string */ - public function getRoot(){ + public function getRoot() { return $this->fakeRoot; } @@ -85,7 +85,7 @@ class OC_FilesystemView { * @param string path * @return bool */ - public function getInternalPath($path){ + public function getInternalPath($path) { if (!isset($this->internal_path_cache[$path])) { $this->internal_path_cache[$path] = OC_Filesystem::getInternalPath($this->getAbsolutePath($path)); } @@ -97,23 +97,23 @@ class OC_FilesystemView { * @param string path * @return string */ - public function getRelativePath($path){ - if($this->fakeRoot==''){ + public function getRelativePath($path) { + if($this->fakeRoot=='') { return $path; } - if(strpos($path,$this->fakeRoot)!==0){ + if(strpos($path, $this->fakeRoot)!==0) { return null; }else{ - return substr($path,strlen($this->fakeRoot)); + return substr($path, strlen($this->fakeRoot)); } } - + /** * get the storage object for a path * @param string path * @return OC_Filestorage */ - public function getStorage($path){ + public function getStorage($path) { if (!isset($this->storage_cache[$path])) { $this->storage_cache[$path] = OC_Filesystem::getStorage($this->getAbsolutePath($path)); } @@ -127,7 +127,7 @@ class OC_FilesystemView { * @param string path * @return string */ - public function getMountPoint($path){ + public function getMountPoint($path) { return OC_Filesystem::getMountPoint($this->getAbsolutePath($path)); } @@ -137,55 +137,55 @@ class OC_FilesystemView { * @param string path * @return string */ - public function getLocalFile($path){ - $parent=substr($path,0,strrpos($path,'/')); - if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)){ + public function getLocalFile($path) { + $parent=substr($path, 0, strrpos($path,'/')); + if(OC_Filesystem::isValidPath($parent) and $storage=$this->getStorage($path)) { return $storage->getLocalFile($this->getInternalPath($path)); } } /** - * the following functions operate with arguments and return values identical - * to those of their PHP built-in equivalents. Mostly they are merely wrappers + * the following functions operate with arguments and return values identical + * to those of their PHP built-in equivalents. Mostly they are merely wrappers * for OC_Filestorage via basicOperation(). */ - public function mkdir($path){ - return $this->basicOperation('mkdir',$path,array('create','write')); + public function mkdir($path) { + return $this->basicOperation('mkdir', $path, array('create', 'write')); } - public function rmdir($path){ - return $this->basicOperation('rmdir',$path,array('delete')); + public function rmdir($path) { + return $this->basicOperation('rmdir', $path, array('delete')); } - public function opendir($path){ - return $this->basicOperation('opendir',$path,array('read')); + public function opendir($path) { + return $this->basicOperation('opendir', $path, array('read')); } - public function readdir($handle){ + public function readdir($handle) { $fsLocal= new OC_Filestorage_Local( array( 'datadir' => '/' ) ); return $fsLocal->readdir( $handle ); } - public function is_dir($path){ + public function is_dir($path) { if($path=='/'){ return true; } - return $this->basicOperation('is_dir',$path); + return $this->basicOperation('is_dir', $path); } - public function is_file($path){ + public function is_file($path) { if($path=='/'){ return false; } - return $this->basicOperation('is_file',$path); + return $this->basicOperation('is_file', $path); } - public function stat($path){ - return $this->basicOperation('stat',$path); + public function stat($path) { + return $this->basicOperation('stat', $path); } - public function filetype($path){ - return $this->basicOperation('filetype',$path); + public function filetype($path) { + return $this->basicOperation('filetype', $path); } - public function filesize($path){ - return $this->basicOperation('filesize',$path); + public function filesize($path) { + return $this->basicOperation('filesize', $path); } - public function readfile($path){ + public function readfile($path) { @ob_end_clean(); - $handle=$this->fopen($path,'rb'); + $handle=$this->fopen($path, 'rb'); if ($handle) { $chunkSize = 8192;// 8 MB chunks while (!feof($handle)) { @@ -224,131 +224,204 @@ class OC_FilesystemView { public function isSharable($path) { return $this->basicOperation('isSharable', $path); } - public function file_exists($path){ + public function file_exists($path) { if($path=='/'){ return true; } - return $this->basicOperation('file_exists',$path); + return $this->basicOperation('file_exists', $path); } - public function filectime($path){ - return $this->basicOperation('filectime',$path); + public function filectime($path) { + return $this->basicOperation('filectime', $path); } - public function filemtime($path){ - return $this->basicOperation('filemtime',$path); + public function filemtime($path) { + return $this->basicOperation('filemtime', $path); } - public function touch($path, $mtime=null){ + public function touch($path, $mtime=null) { return $this->basicOperation('touch', $path, array('write'), $mtime); } - public function file_get_contents($path){ - return $this->basicOperation('file_get_contents',$path,array('read')); - } - public function file_put_contents($path,$data){ - if(is_resource($data)){//not having to deal with streams in file_put_contents makes life easier - $exists=$this->file_exists($path); - $run=true; - if(!$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); + public function file_get_contents($path) { + return $this->basicOperation('file_get_contents', $path, array('read')); + } + public function file_put_contents($path, $data) { + if(is_resource($data)) {//not having to deal with streams in file_put_contents makes life easier + $exists = $this->file_exists($path); + $run = true; + if(!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); - if(!$run){ + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + if(!$run) { return false; } - $target=$this->fopen($path,'w'); - if($target){ - $count=OC_Helper::streamCopy($data,$target); + $target=$this->fopen($path, 'w'); + if($target) { + $count=OC_Helper::streamCopy($data, $target); fclose($target); fclose($data); - if(!$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path)); + if(!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_create, + array( OC_Filesystem::signal_param_path => $path) + ); } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path)); - return $count>0; + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array( OC_Filesystem::signal_param_path => $path) + ); + return $count > 0; }else{ return false; } }else{ - return $this->basicOperation('file_put_contents',$path,array('create','write'),$data); + return $this->basicOperation('file_put_contents', $path, array('create', 'write'), $data); } } - public function unlink($path){ - return $this->basicOperation('unlink',$path,array('delete')); + public function unlink($path) { + return $this->basicOperation('unlink', $path, array('delete')); } public function deleteAll( $directory, $empty = false ) { return $this->basicOperation( 'deleteAll', $directory, array('delete'), $empty ); } - public function rename($path1,$path2){ - $absolutePath1=$this->getAbsolutePath($path1); - $absolutePath2=$this->getAbsolutePath($path2); - if(OC_FileProxy::runPreProxies('rename',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){ - $path1=$this->getRelativePath($absolutePath1); - $path2=$this->getRelativePath($absolutePath2); - if($path1==null or $path2==null){ + public function rename($path1, $path2) { + $absolutePath1 = $this->getAbsolutePath($path1); + $absolutePath2 = $this->getAbsolutePath($path2); + if(OC_FileProxy::runPreProxies('rename', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + if($path1 == null or $path2 == null) { return false; } $run=true; - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run)); - if($run){ - $mp1=$this->getMountPoint($path1); - $mp2=$this->getMountPoint($path2); - if($mp1==$mp2){ - if($storage=$this->getStorage($path1)){ - $result=$storage->rename($this->getInternalPath($path1),$this->getInternalPath($path2)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, OC_Filesystem::signal_rename, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); + if($run) { + $mp1 = $this->getMountPoint($path1); + $mp2 = $this->getMountPoint($path2); + if($mp1 == $mp2) { + if($storage = $this->getStorage($path1)) { + $result = $storage->rename($this->getInternalPath($path1), $this->getInternalPath($path2)); } - }else{ - $source=$this->fopen($path1,'r'); - $target=$this->fopen($path2,'w'); - $count=OC_Helper::streamCopy($source,$target); - $storage1=$this->getStorage($path1); + } else { + $source = $this->fopen($path1, 'r'); + $target = $this->fopen($path2, 'w'); + $count = OC_Helper::streamCopy($source, $target); + $storage1 = $this->getStorage($path1); $storage1->unlink($this->getInternalPath($path1)); - $result=$count>0; + $result = $count>0; } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_rename, array( OC_Filesystem::signal_param_oldpath => $path1, OC_Filesystem::signal_param_newpath=>$path2)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_rename, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath => $path2 + ) + ); return $result; } } } - public function copy($path1,$path2){ - $absolutePath1=$this->getAbsolutePath($path1); - $absolutePath2=$this->getAbsolutePath($path2); - if(OC_FileProxy::runPreProxies('copy',$absolutePath1,$absolutePath2) and OC_Filesystem::isValidPath($path2)){ - $path1=$this->getRelativePath($absolutePath1); - $path2=$this->getRelativePath($absolutePath2); - if($path1==null or $path2==null){ + public function copy($path1, $path2) { + $absolutePath1 = $this->getAbsolutePath($path1); + $absolutePath2 = $this->getAbsolutePath($path2); + if(OC_FileProxy::runPreProxies('copy', $absolutePath1, $absolutePath2) and OC_Filesystem::isValidPath($path2)) { + $path1 = $this->getRelativePath($absolutePath1); + $path2 = $this->getRelativePath($absolutePath2); + if($path1 == null or $path2 == null) { return false; } $run=true; - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2, OC_Filesystem::signal_param_run => &$run)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_copy, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath=>$path2, + OC_Filesystem::signal_param_run => &$run + ) + ); $exists=$this->file_exists($path2); - if($run and !$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_create, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run)); + if($run and !$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_create, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); } - if($run){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_write, array( OC_Filesystem::signal_param_path => $path2, OC_Filesystem::signal_param_run => &$run)); + if($run) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_write, + array( + OC_Filesystem::signal_param_path => $path2, + OC_Filesystem::signal_param_run => &$run + ) + ); } - if($run){ + if($run) { $mp1=$this->getMountPoint($path1); $mp2=$this->getMountPoint($path2); - if($mp1==$mp2){ - if($storage=$this->getStorage($path1)){ - $result=$storage->copy($this->getInternalPath($path1),$this->getInternalPath($path2)); + if($mp1 == $mp2){ + if($storage = $this->getStorage($path1)) { + $result=$storage->copy($this->getInternalPath($path1), $this->getInternalPath($path2)); } - }else{ - $source=$this->fopen($path1,'r'); - $target=$this->fopen($path2,'w'); - $result=OC_Helper::streamCopy($source,$target); + } else { + $source = $this->fopen($path1, 'r'); + $target = $this->fopen($path2, 'w'); + $result = OC_Helper::streamCopy($source, $target); } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_copy, array( OC_Filesystem::signal_param_oldpath => $path1 , OC_Filesystem::signal_param_newpath=>$path2)); - if(!$exists){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_create, array( OC_Filesystem::signal_param_path => $path2)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_copy, + array( + OC_Filesystem::signal_param_oldpath => $path1, + OC_Filesystem::signal_param_newpath=>$path2 + ) + ); + if(!$exists) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_create, + array(OC_Filesystem::signal_param_path => $path2) + ); } - OC_Hook::emit( OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, array( OC_Filesystem::signal_param_path => $path2)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_post_write, + array( OC_Filesystem::signal_param_path => $path2) + ); return $result; } } } - public function fopen($path,$mode){ + public function fopen($path, $mode) { $hooks=array(); - switch($mode){ + switch($mode) { case 'r': case 'rb': $hooks[]='read'; @@ -376,49 +449,68 @@ class OC_FilesystemView { OC_Log::write('core','invalid mode ('.$mode.') for '.$path,OC_Log::ERROR); } - return $this->basicOperation('fopen',$path,$hooks,$mode); + return $this->basicOperation('fopen', $path, $hooks, $mode); } - public function toTmpFile($path){ - if(OC_Filesystem::isValidPath($path)){ - $source=$this->fopen($path,'r'); - if($source){ + public function toTmpFile($path) { + if(OC_Filesystem::isValidPath($path)) { + $source = $this->fopen($path, 'r'); + if($source) { $extension=''; - $extOffset=strpos($path,'.'); + $extOffset=strpos($path, '.'); if($extOffset !== false) { - $extension=substr($path,strrpos($path,'.')); + $extension=substr($path, strrpos($path,'.')); } - $tmpFile=OC_Helper::tmpFile($extension); - file_put_contents($tmpFile,$source); + $tmpFile = OC_Helper::tmpFile($extension); + file_put_contents($tmpFile, $source); return $tmpFile; } } } - public function fromTmpFile($tmpFile,$path){ - if(OC_Filesystem::isValidPath($path)){ - if(!$tmpFile){ + public function fromTmpFile($tmpFile, $path) { + if(OC_Filesystem::isValidPath($path)) { + if(!$tmpFile) { debug_print_backtrace(); } - $source=fopen($tmpFile,'r'); - if($source){ - $this->file_put_contents($path,$source); + $source=fopen($tmpFile, 'r'); + if($source) { + $this->file_put_contents($path, $source); unlink($tmpFile); return true; - }else{ + } else { } - }else{ + } else { return false; } } - public function getMimeType($path){ - return $this->basicOperation('getMimeType',$path); - } - public function hash($type,$path){ - return $this->basicOperation('hash',$path,array('read')); + public function getMimeType($path) { + return $this->basicOperation('getMimeType', $path); + } + public function hash($type, $path, $raw = false) { + $absolutePath = $this->getAbsolutePath($path); + if (OC_FileProxy::runPreProxies('hash', $absolutePath) && OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + if ($path == null) { + return false; + } + if (OC_Filesystem::$loaded && $this->fakeRoot == OC_Filesystem::getRoot()) { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + OC_Filesystem::signal_read, + array( OC_Filesystem::signal_param_path => $path) + ); + } + if ($storage = $this->getStorage($path)) { + $result = $storage->hash($type, $this->getInternalPath($path), $raw); + $result = OC_FileProxy::runPostProxies('hash', $absolutePath, $result); + return $result; + } + } + return null; } - public function free_space($path='/'){ - return $this->basicOperation('free_space',$path); + public function free_space($path='/') { + return $this->basicOperation('free_space', $path); } /** @@ -428,41 +520,56 @@ class OC_FilesystemView { * @param array (optional) hooks * @param mixed (optional) $extraParam * @return mixed - * - * This method takes requests for basic filesystem functions (e.g. reading & writing - * files), processes hooks and proxies, sanitises paths, and finally passes them on to + * + * This method takes requests for basic filesystem functions (e.g. reading & writing + * files), processes hooks and proxies, sanitises paths, and finally passes them on to * OC_Filestorage for delegation to a storage backend for execution */ - private function basicOperation($operation,$path,$hooks=array(),$extraParam=null){ - $absolutePath=$this->getAbsolutePath($path); - if(OC_FileProxy::runPreProxies($operation,$absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)){ - $path=$this->getRelativePath($absolutePath); - if($path==null){ + private function basicOperation($operation, $path, $hooks=array(), $extraParam=null) { + $absolutePath = $this->getAbsolutePath($path); + if(OC_FileProxy::runPreProxies($operation, $absolutePath, $extraParam) and OC_Filesystem::isValidPath($path)) { + $path = $this->getRelativePath($absolutePath); + if($path == null) { return false; } - $internalPath=$this->getInternalPath($path); - $run=true; - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){ - foreach($hooks as $hook){ - if($hook!='read'){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path, OC_Filesystem::signal_param_run => &$run)); - }else{ - OC_Hook::emit( OC_Filesystem::CLASSNAME, $hook, array( OC_Filesystem::signal_param_path => $path)); + $internalPath = $this->getInternalPath($path); + $run = true; + if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { + foreach($hooks as $hook) { + if($hook!='read') { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $hook, + array( + OC_Filesystem::signal_param_path => $path, + OC_Filesystem::signal_param_run => &$run + ) + ); + } else { + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + $hook, + array( OC_Filesystem::signal_param_path => $path) + ); } } } - if($run and $storage=$this->getStorage($path)){ - if(!is_null($extraParam)){ - $result=$storage->$operation($internalPath,$extraParam); - }else{ - $result=$storage->$operation($internalPath); + if($run and $storage = $this->getStorage($path)) { + if(!is_null($extraParam)) { + $result = $storage->$operation($internalPath, $extraParam); + } else { + $result = $storage->$operation($internalPath); } - $result=OC_FileProxy::runPostProxies($operation,$this->getAbsolutePath($path),$result); - if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()){ - if($operation!='fopen'){//no post hooks for fopen, the file stream is still open - foreach($hooks as $hook){ + $result = OC_FileProxy::runPostProxies($operation, $this->getAbsolutePath($path), $result); + if(OC_Filesystem::$loaded and $this->fakeRoot==OC_Filesystem::getRoot()) { + if($operation!='fopen') {//no post hooks for fopen, the file stream is still open + foreach($hooks as $hook) { if($hook!='read'){ - OC_Hook::emit( OC_Filesystem::CLASSNAME, 'post_'.$hook, array( OC_Filesystem::signal_param_path => $path)); + OC_Hook::emit( + OC_Filesystem::CLASSNAME, + 'post_'.$hook, + array( OC_Filesystem::signal_param_path => $path) + ); } } } @@ -478,7 +585,7 @@ class OC_FilesystemView { * @param int $time * @return bool */ - public function hasUpdated($path,$time){ - return $this->basicOperation('hasUpdated',$path,array(),$time); + public function hasUpdated($path, $time) { + return $this->basicOperation('hasUpdated', $path, array(), $time); } } diff --git a/lib/group.php b/lib/group.php index ceee5fa4edb..12e5f5ebb30 100644 --- a/lib/group.php +++ b/lib/group.php @@ -43,7 +43,7 @@ class OC_Group { * @returns true/false */ public static function useBackend( $backend ){ - if($backend instanceof OC_Group_Backend){ + if($backend instanceof OC_Group_Interface){ self::$_usedBackends[]=$backend; } } @@ -168,7 +168,7 @@ class OC_Group { if($run){ $succes=false; - + //add the user to the all backends that have the group foreach(self::$_usedBackends as $backend){ if(!$backend->implementsActions(OC_GROUP_BACKEND_ADD_TO_GROUP)) @@ -245,7 +245,7 @@ class OC_Group { asort($groups); return $groups; } - + /** * check if a group exists * @param string $gid @@ -259,7 +259,7 @@ class OC_Group { } return false; } - + /** * @brief get a list of all users in a group * @returns array with user ids diff --git a/lib/group/backend.php b/lib/group/backend.php index 24778afd1e5..ebc078f152a 100644 --- a/lib/group/backend.php +++ b/lib/group/backend.php @@ -37,7 +37,7 @@ define('OC_GROUP_BACKEND_REMOVE_FROM_GOUP', 0x00001000); /** * Abstract base class for user management */ -abstract class OC_Group_Backend { +abstract class OC_Group_Backend implements OC_Group_Interface { protected $possibleActions = array( OC_GROUP_BACKEND_CREATE_GROUP => 'createGroup', OC_GROUP_BACKEND_DELETE_GROUP => 'deleteGroup', diff --git a/lib/group/database.php b/lib/group/database.php index fb173665eb8..2770ec185c4 100644 --- a/lib/group/database.php +++ b/lib/group/database.php @@ -41,7 +41,6 @@ * Class for group management in a SQL Database (e.g. MySQL, SQLite) */ class OC_Group_Database extends OC_Group_Backend { - private $userGroupCache=array(); /** * @brief Try to create a new group @@ -116,7 +115,7 @@ class OC_Group_Database extends OC_Group_Backend { // No duplicate entries! if( !$this->inGroup( $uid, $gid )){ $query = OC_DB::prepare( "INSERT INTO `*PREFIX*group_user` ( `uid`, `gid` ) VALUES( ?, ? )" ); - $result = $query->execute( array( $uid, $gid )); + $query->execute( array( $uid, $gid )); return true; }else{ return false; @@ -133,7 +132,7 @@ class OC_Group_Database extends OC_Group_Backend { */ public function removeFromGroup( $uid, $gid ){ $query = OC_DB::prepare( "DELETE FROM *PREFIX*group_user WHERE uid = ? AND gid = ?" ); - $result = $query->execute( array( $uid, $gid )); + $query->execute( array( $uid, $gid )); return true; } diff --git a/lib/group/dummy.php b/lib/group/dummy.php index 0825b10708a..1243891023f 100644 --- a/lib/group/dummy.php +++ b/lib/group/dummy.php @@ -126,7 +126,8 @@ class OC_Group_Dummy extends OC_Group_Backend { */ public function getUserGroups($uid){ $groups=array(); - foreach($this->groups as $group=>$user){ + $allGroups=array_keys($this->groups); + foreach($allGroups as $group){ if($this->inGroup($uid,$group)){ $groups[]=$group; } diff --git a/lib/group/example.php b/lib/group/example.php index c18562db7a4..9c9ece5ac77 100644 --- a/lib/group/example.php +++ b/lib/group/example.php @@ -34,7 +34,7 @@ abstract class OC_Group_Example { * Trys to create a new group. If the group name already exists, false will * be returned. */ - public static function createGroup($gid){} + abstract public static function createGroup($gid); /** * @brief delete a group @@ -43,7 +43,7 @@ abstract class OC_Group_Example { * * Deletes a group and removes it from the group_user-table */ - public static function deleteGroup($gid){} + abstract public static function deleteGroup($gid); /** * @brief is user in group? @@ -53,7 +53,7 @@ abstract class OC_Group_Example { * * Checks whether the user is member of a group or not. */ - public static function inGroup($uid, $gid){} + abstract public static function inGroup($uid, $gid); /** * @brief Add a user to a group @@ -63,7 +63,7 @@ abstract class OC_Group_Example { * * Adds a user to a group. */ - public static function addToGroup($uid, $gid){} + abstract public static function addToGroup($uid, $gid); /** * @brief Removes a user from a group @@ -73,7 +73,7 @@ abstract class OC_Group_Example { * * removes the user from a group. */ - public static function removeFromGroup($uid,$gid){} + abstract public static function removeFromGroup($uid,$gid); /** * @brief Get all groups a user belongs to @@ -83,7 +83,7 @@ abstract class OC_Group_Example { * This function fetches all groups a user belongs to. It does not check * if the user exists at all. */ - public static function getUserGroups($uid){} + abstract public static function getUserGroups($uid); /** * @brief get a list of all groups @@ -91,19 +91,19 @@ abstract class OC_Group_Example { * * Returns a list with all groups */ - public static function getGroups(){} + abstract public static function getGroups(); /** * check if a group exists * @param string $gid * @return bool */ - public function groupExists($gid){} + abstract public function groupExists($gid); /** * @brief get a list of all users in a group * @returns array with user ids */ - public static function usersInGroup($gid){} + abstract public static function usersInGroup($gid); } diff --git a/lib/group/interface.php b/lib/group/interface.php new file mode 100644 index 00000000000..7cca6061e10 --- /dev/null +++ b/lib/group/interface.php @@ -0,0 +1,76 @@ +<?php + +/** + * ownCloud - group interface + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +interface OC_Group_Interface { + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_GROUP_BACKEND_CREATE_GROUP etc. + */ + public function implementsActions($actions); + + /** + * @brief is user in group? + * @param $uid uid of the user + * @param $gid gid of the group + * @returns true/false + * + * Checks whether the user is member of a group or not. + */ + public function inGroup($uid, $gid); + + /** + * @brief Get all groups a user belongs to + * @param $uid Name of the user + * @returns array with group names + * + * This function fetches all groups a user belongs to. It does not check + * if the user exists at all. + */ + public function getUserGroups($uid); + + /** + * @brief get a list of all groups + * @returns array with group names + * + * Returns a list with all groups + */ + public function getGroups(); + + /** + * check if a group exists + * @param string $gid + * @return bool + */ + public function groupExists($gid); + + /** + * @brief get a list of all users in a group + * @returns array with user ids + */ + public function usersInGroup($gid); + +}
\ No newline at end of file diff --git a/lib/helper.php b/lib/helper.php index 0d18098a4e7..666bc6badfc 100644 --- a/lib/helper.php +++ b/lib/helper.php @@ -175,10 +175,8 @@ class OC_Helper { */ public static function mimetypeIcon( $mimetype ){ $alias=array('application/xml'=>'code/xml'); -// echo $mimetype; if(isset($alias[$mimetype])){ $mimetype=$alias[$mimetype]; -// echo $mimetype; } // Replace slash with a minus $mimetype = str_replace( "/", "-", $mimetype ); @@ -345,18 +343,24 @@ class OC_Helper { */ static function getMimeType($path){ $isWrapped=(strpos($path,'://')!==false) and (substr($path,0,7)=='file://'); - $mimeType='application/octet-stream'; - if ($mimeType=='application/octet-stream') { - self::$mimetypes = include('mimetypes.fixlist.php'); - $extension=strtolower(strrchr(basename($path), ".")); - $extension=substr($extension,1);//remove leading . - $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream'; - } if (@is_dir($path)) { // directories are easy return "httpd/unix-directory"; } + + if(strpos($path,'.')){ + //try to guess the type by the file extension + if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){ + self::$mimetypes=include('mimetypes.list.php'); + } + $extension=strtolower(strrchr(basename($path), ".")); + $extension=substr($extension,1);//remove leading . + $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream'; + }else{ + $mimeType='application/octet-stream'; + } + if($mimeType=='application/octet-stream' and function_exists('finfo_open') and function_exists('finfo_file') and $finfo=finfo_open(FILEINFO_MIME)){ $info = @strtolower(finfo_file($finfo,$path)); if($info){ @@ -385,15 +389,6 @@ class OC_Helper { } } - if ($mimeType=='application/octet-stream') { - // Fallback solution: (try to guess the type by the file extension - if(!self::$mimetypes || self::$mimetypes != include('mimetypes.list.php')){ - self::$mimetypes=include('mimetypes.list.php'); - } - $extension=strtolower(strrchr(basename($path), ".")); - $extension=substr($extension,1);//remove leading . - $mimeType=(isset(self::$mimetypes[$extension]))?self::$mimetypes[$extension]:'application/octet-stream'; - } return $mimeType; } @@ -676,12 +671,38 @@ class OC_Helper { */ public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { $offset = -1; - $length = mb_strlen($search, 'UTF-8'); - while(($i = mb_strrpos($subject, $search, $offset, 'UTF-8'))) { + $length = mb_strlen($search, $encoding); + while(($i = mb_strrpos($subject, $search, $offset, $encoding))) { $subject = OC_Helper::mb_substr_replace($subject, $replace, $i, $length); - $offset = $i - mb_strlen($subject, 'UTF-8') - 1; + $offset = $i - mb_strlen($subject, $encoding) - 1; $count++; } return $subject; } + + /** + * @brief performs a search in a nested array + * @param haystack the array to be searched + * @param needle the search string + * @param $index optional, only search this key name + * @return the key of the matching field, otherwise false + * + * performs a search in a nested array + * + * taken from http://www.php.net/manual/en/function.array-search.php#97645 + */ + public static function recursiveArraySearch($haystack, $needle, $index = null) { + $aIt = new RecursiveArrayIterator($haystack); + $it = new RecursiveIteratorIterator($aIt); + + while($it->valid()) { + if (((isset($index) AND ($it->key() == $index)) OR (!isset($index))) AND ($it->current() == $needle)) { + return $aIt->key(); + } + + $it->next(); + } + + return false; + } } diff --git a/lib/image.php b/lib/image.php index 01e843d8316..90c64320a7c 100644 --- a/lib/image.php +++ b/lib/image.php @@ -23,12 +23,12 @@ //From user comments at http://dk2.php.net/manual/en/function.exif-imagetype.php if ( ! function_exists( 'exif_imagetype' ) ) { - function exif_imagetype ( $filename ) { - if ( ( list($width, $height, $type, $attr) = getimagesize( $filename ) ) !== false ) { - return $type; - } - return false; - } + function exif_imagetype ( $filename ) { + if ( ( $info = getimagesize( $filename ) ) !== false ) { + return $info[2]; + } + return false; + } } function ellipsis($str, $maxlen) { @@ -66,7 +66,6 @@ class OC_Image { public function __construct($imageref = null) { //OC_Log::write('core',__METHOD__.'(): start', OC_Log::DEBUG); if(!extension_loaded('gd') || !function_exists('gd_info')) { - //if(!function_exists('imagecreatefromjpeg')) { OC_Log::write('core',__METHOD__.'(): GD module not installed', OC_Log::ERROR); return false; } @@ -364,7 +363,7 @@ class OC_Image { public function load($imageref) { if(is_resource($imageref)) { if(get_resource_type($imageref) == 'gd') { - $this->resource = $res; + $this->resource = $imageref; return $this->resource; } elseif(in_array(get_resource_type($imageref), array('file','stream'))) { return $this->loadFromFileHandle($imageref); @@ -650,9 +649,6 @@ class OC_Image { OC_Log::write('core',__METHOD__.'(): No image loaded', OC_Log::ERROR); return false; } - $width_orig=imageSX($this->resource); - $height_orig=imageSY($this->resource); - //OC_Log::write('core',__METHOD__.'(): Original size: '.$width_orig.'x'.$height_orig, OC_Log::DEBUG); $process = imagecreatetruecolor($w, $h); if ($process == false) { OC_Log::write('core',__METHOD__.'(): Error creating true color image',OC_Log::ERROR); diff --git a/lib/installer.php b/lib/installer.php index 00feb6d4709..a8b56cb34f2 100644 --- a/lib/installer.php +++ b/lib/installer.php @@ -126,19 +126,19 @@ class OC_Installer{ return false; } $info=OC_App::getAppInfo($extractDir.'/appinfo/info.xml',true); - // check the code for not allowed calls - if(!OC_Installer::checkCode($info['id'],$extractDir)){ + // check the code for not allowed calls + if(!OC_Installer::checkCode($info['id'],$extractDir)){ OC_Log::write('core','App can\'t be installed because of not allowed code in the App',OC_Log::ERROR); OC_Helper::rmdirr($extractDir); - return false; + return false; } - // check if the app is compatible with this version of ownCloud + // check if the app is compatible with this version of ownCloud $version=OC_Util::getVersion(); - if(!isset($info['require']) or ($version[0]>$info['require'])){ + if(!isset($info['require']) or ($version[0]>$info['require'])){ OC_Log::write('core','App can\'t be installed because it is not compatible with this version of ownCloud',OC_Log::ERROR); OC_Helper::rmdirr($extractDir); - return false; + return false; } //check if an app with the same id is already installed @@ -339,12 +339,12 @@ class OC_Installer{ } - /** - * check the code of an app with some static code checks - * @param string $folder the folder of the app to check - * @returns true for app is o.k. and false for app is not o.k. - */ - public static function checkCode($appname,$folder){ + /** + * check the code of an app with some static code checks + * @param string $folder the folder of the app to check + * @returns true for app is o.k. and false for app is not o.k. + */ + public static function checkCode($appname,$folder){ $blacklist=array( 'exec(', @@ -377,9 +377,7 @@ class OC_Installer{ return true; }else{ - return true; + return true; } - } - - + } } diff --git a/lib/json.php b/lib/json.php index c49b831c12b..b46878375d5 100644 --- a/lib/json.php +++ b/lib/json.php @@ -94,12 +94,12 @@ class OC_JSON{ * Encode and print $data in json format */ public static function encodedPrint($data,$setContentType=true){ - // Disable mimesniffing, don't move this to setContentTypeHeader! - header( 'X-Content-Type-Options: nosniff' ); - if($setContentType){ - self::setContentTypeHeader(); - } - array_walk_recursive($data, array('OC_JSON', 'to_string')); - echo json_encode($data); + // Disable mimesniffing, don't move this to setContentTypeHeader! + header( 'X-Content-Type-Options: nosniff' ); + if($setContentType){ + self::setContentTypeHeader(); + } + array_walk_recursive($data, array('OC_JSON', 'to_string')); + echo json_encode($data); } } diff --git a/lib/l10n.php b/lib/l10n.php index de8514573d3..e7f5ffea0e4 100644 --- a/lib/l10n.php +++ b/lib/l10n.php @@ -154,8 +154,15 @@ class OC_L10N{ * * Returns the translation. If no translation is found, $textArray will be * returned. + * + * + * @deprecated deprecated since ownCloud version 5.0 + * This method will probably be removed with ownCloud 6.0 + * + * */ public function tA($textArray){ + OC_Log::write('core', 'DEPRECATED: the method tA is deprecated and will be removed soon.',OC_Log::WARN); $result = array(); foreach($textArray as $key => $text){ $result[$key] = (string)$this->t($text); diff --git a/lib/migrate.php b/lib/migrate.php index f788a637d3c..1b6367ed6ec 100644 --- a/lib/migrate.php +++ b/lib/migrate.php @@ -91,7 +91,7 @@ class OC_Migrate{ if( self::$exporttype == 'user' ){ // Check user exists if( !is_null($uid) ){ - $db = new OC_User_Database; + $db = new OC_User_Database; if( !$db->userExists( $uid ) ){ OC_Log::write('migration', 'User: '.$uid.' is not in the database and so cannot be exported.', OC_Log::ERROR); return json_encode( array( 'success' => false ) ); diff --git a/lib/mimetypes.fixlist.php b/lib/mimetypes.fixlist.php deleted file mode 100644 index 13e3f16b369..00000000000 --- a/lib/mimetypes.fixlist.php +++ /dev/null @@ -1,22 +0,0 @@ -<?php -return array( - 'ics'=>'text/calendar', - 'ical'=>'text/calendar', - 'js'=>'application/javascript', - 'odt'=>'application/vnd.oasis.opendocument.text', - 'ods'=>'application/vnd.oasis.opendocument.spreadsheet', - 'odg'=>'application/vnd.oasis.opendocument.graphics', - 'odp'=>'application/vnd.oasis.opendocument.presentation', - 'pl'=>'text/x-script.perl', - 'py'=>'text/x-script.phyton', - 'vcf' => 'text/vcard', - 'vcard' => 'text/vcard', - 'doc'=>'application/msword', - 'docx'=>'application/msword', - 'xls'=>'application/msexcel', - 'xlsx'=>'application/msexcel', - 'ppt'=>'application/mspowerpoint', - 'pptx'=>'application/mspowerpoint', - 'sgf' => 'application/sgf', - 'cdr' => 'application/coreldraw' -); diff --git a/lib/mimetypes.list.php b/lib/mimetypes.list.php index ccf47999b1c..f7207493f7f 100644 --- a/lib/mimetypes.list.php +++ b/lib/mimetypes.list.php @@ -78,5 +78,16 @@ return array( 'mpeg'=>'video/mpeg', 'mov'=>'video/quicktime', 'webm'=>'video/webm', - 'wmv'=>'video/x-ms-asf' + 'wmv'=>'video/x-ms-asf', + 'py'=>'text/x-script.phyton', + 'vcf' => 'text/vcard', + 'vcard' => 'text/vcard', + 'doc'=>'application/msword', + 'docx'=>'application/msword', + 'xls'=>'application/msexcel', + 'xlsx'=>'application/msexcel', + 'ppt'=>'application/mspowerpoint', + 'pptx'=>'application/mspowerpoint', + 'sgf' => 'application/sgf', + 'cdr' => 'application/coreldraw', ); diff --git a/lib/minimizer.php b/lib/minimizer.php index 3bf5ff9980b..3dc89e331a6 100644 --- a/lib/minimizer.php +++ b/lib/minimizer.php @@ -46,3 +46,13 @@ abstract class OC_Minimizer { echo $out; } } + +if (!function_exists('gzdecode')) { + function gzdecode($data,$maxlength=null,&$filename='',&$error='') + { + if (strcmp(substr($data,0,9),"\x1f\x8b\x8\0\0\0\0\0\0")) { + return null; // Not the GZIP format we expect (See RFC 1952) + } + return gzinflate(substr($data,10,-8)); + } +} diff --git a/lib/ocs.php b/lib/ocs.php index 1be41202d78..3157aae99e6 100644 --- a/lib/ocs.php +++ b/lib/ocs.php @@ -4,7 +4,9 @@ * ownCloud * * @author Frank Karlitschek +* @author Michael Gapczynski * @copyright 2012 Frank Karlitschek frank@owncloud.org +* @copyright 2012 Michael Gapczynski mtgap@owncloud.com * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE @@ -29,429 +31,453 @@ */ class OC_OCS { - /** - * reads input date from get/post/cookies and converts the date to a special data-type - * - * @param variable $key - * @param variable-type $type - * @param priority $getpriority - * @param default $default - * @return data - */ - public static function readData($key,$type='raw',$getpriority=false,$default='') { - if($getpriority) { - if(isset($_GET[$key])) { - $data=$_GET[$key]; - } elseif(isset($_POST[$key])) { - $data=$_POST[$key]; - } else { - if($default=='') { - if(($type=='int') or ($type=='float')) $data=0; else $data=''; - } else { - $data=$default; - } - } - } else { - if(isset($_POST[$key])) { - $data=$_POST[$key]; - } elseif(isset($_GET[$key])) { - $data=$_GET[$key]; - } elseif(isset($_COOKIE[$key])) { - $data=$_COOKIE[$key]; - } else { - if($default=='') { - if(($type=='int') or ($type=='float')) $data=0; else $data=''; - } else { - $data=$default; - } - } - } - - if($type=='raw') return($data); - elseif($type=='text') return(addslashes(strip_tags($data))); - elseif($type=='int') { $data = (int) $data; return($data); } - elseif($type=='float') { $data = (float) $data; return($data); } - elseif($type=='array') { $data = $data; return($data); } - } - - - /** - main function to handle the REST request - **/ - public static function handle() { - - // overwrite the 404 error page returncode - header("HTTP/1.0 200 OK"); - - - if($_SERVER['REQUEST_METHOD'] == 'GET') { - $method='get'; - }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { - $method='put'; - parse_str(file_get_contents("php://input"),$put_vars); - }elseif($_SERVER['REQUEST_METHOD'] == 'POST') { - $method='post'; - }else{ - echo('internal server error: method not supported'); - exit(); - } - - // preprocess url - $url=$_SERVER['REQUEST_URI']; - if(substr($url,(strlen($url)-1))<>'/') $url.='/'; - $ex=explode('/',$url); - $paracount=count($ex); - - // eventhandler - // CONFIG - // apiconfig - GET - CONFIG - if(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php') and (strtolower($ex[$paracount-2])=='config')){ - $format=OC_OCS::readdata('format','text'); - OC_OCS::apiconfig($format); - - // PERSON - // personcheck - POST - PERSON/CHECK - }elseif(($method=='post') and (strtolower($ex[$paracount-4])=='v1.php') and (strtolower($ex[$paracount-3])=='person') and (strtolower($ex[$paracount-2])=='check')){ - $format=OC_OCS::readdata('format','text'); - $login=OC_OCS::readdata('login','text'); - $passwd=OC_OCS::readdata('password','text'); - OC_OCS::personcheck($format,$login,$passwd); - - // ACTIVITY - // activityget - GET ACTIVITY page,pagesize als urlparameter - }elseif(($method=='get') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ - $format=OC_OCS::readdata('format','text'); - $page=OC_OCS::readdata('page','int'); - $pagesize=OC_OCS::readdata('pagesize','int'); - if($pagesize<1 or $pagesize>100) $pagesize=10; - OC_OCS::activityget($format,$page,$pagesize); - - // activityput - POST ACTIVITY - }elseif(($method=='post') and (strtolower($ex[$paracount-3])=='v1.php')and (strtolower($ex[$paracount-2])=='activity')){ - $format=OC_OCS::readdata('format','text'); - $message=OC_OCS::readdata('message','text'); - OC_OCS::activityput($format,$message); - - // PRIVATEDATA - // get - GET DATA - }elseif(($method=='get') and (strtolower($ex[$paracount-4])=='v1.php')and (strtolower($ex[$paracount-2])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - OC_OCS::privateDataGet($format); - - }elseif(($method=='get') and (strtolower($ex[$paracount-5])=='v1.php')and (strtolower($ex[$paracount-3])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - $app=$ex[$paracount-2]; - OC_OCS::privateDataGet($format, $app); - }elseif(($method=='get') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='getattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - OC_OCS::privateDataGet($format, $app,$key); - - // set - POST DATA - }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='setattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - $value=OC_OCS::readdata('value','text'); - OC_OCS::privatedataset($format, $app, $key, $value); - // delete - POST DATA - }elseif(($method=='post') and (strtolower($ex[$paracount-6])=='v1.php')and (strtolower($ex[$paracount-4])=='deleteattribute')){ - $format=OC_OCS::readdata('format','text'); - $key=$ex[$paracount-2]; - $app=$ex[$paracount-3]; - OC_OCS::privatedatadelete($format, $app, $key); - - }else{ - $format=OC_OCS::readdata('format','text'); - $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n"; - $txt.=OC_OCS::getdebugoutput(); - echo(OC_OCS::generatexml($format,'failed',999,$txt)); - } - exit(); - } - - /** - * generated some debug information to make it easier to find faild API calls - * @return debug data string - */ - private static function getDebugOutput() { - $txt=''; - $txt.="debug output:\n"; - if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n"; - if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n"; - if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n"; - if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n"; - return($txt); - } - - /** - * checks if the user is authenticated - * checks the IP whitlist, apikeys and login/password combination - * if $forceuser is true and the authentication failed it returns an 401 http response. - * if $forceuser is false and authentification fails it returns an empty username string - * @param bool $forceuser - * @return username string - */ - private static function checkPassword($forceuser=true) { - //valid user account ? - if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; - if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; - - if(empty($authuser)) { - if($forceuser){ - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - if(!OC_User::login($authuser,$authpw)){ - if($forceuser){ - header('WWW-Authenticate: Basic realm="your valid user account or api key"'); - header('HTTP/1.0 401 Unauthorized'); - exit; - }else{ - $identifieduser=''; - } - }else{ - $identifieduser=$authuser; - } - } - - return($identifieduser); - } - - - /** - * generates the xml or json response for the API call from an multidimenional data array. - * @param string $format - * @param string $status - * @param string $statuscode - * @param string $message - * @param array $data - * @param string $tag - * @param string $tagattribute - * @param int $dimension - * @param int $itemscount - * @param int $itemsperpage - * @return string xml/json - */ - private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') { - if($format=='json') { - - $json=array(); - $json['status']=$status; - $json['statuscode']=$statuscode; - $json['message']=$message; - $json['totalitems']=$itemscount; - $json['itemsperpage']=$itemsperpage; - $json['data']=$data; - return(json_encode($json)); - - - }else{ - $txt=''; - $writer = xmlwriter_open_memory(); - xmlwriter_set_indent( $writer, 2 ); - xmlwriter_start_document($writer ); - xmlwriter_start_element($writer,'ocs'); - xmlwriter_start_element($writer,'meta'); - xmlwriter_write_element($writer,'status',$status); - xmlwriter_write_element($writer,'statuscode',$statuscode); - xmlwriter_write_element($writer,'message',$message); - if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount); - if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage); - xmlwriter_end_element($writer); - if($dimension=='0') { - // 0 dimensions - xmlwriter_write_element($writer,'data',$data); - - }elseif($dimension=='1') { - xmlwriter_start_element($writer,'data'); - foreach($data as $key=>$entry) { - xmlwriter_write_element($writer,$key,$entry); - } - xmlwriter_end_element($writer); - - }elseif($dimension=='2') { - xmlwriter_start_element($writer,'data'); - foreach($data as $entry) { - xmlwriter_start_element($writer,$tag); - if(!empty($tagattribute)) { - xmlwriter_write_attribute($writer,'details',$tagattribute); - } - foreach($entry as $key=>$value) { - if(is_array($value)){ - foreach($value as $k=>$v) { - xmlwriter_write_element($writer,$k,$v); - } - } else { - xmlwriter_write_element($writer,$key,$value); - } - } - xmlwriter_end_element($writer); - } - xmlwriter_end_element($writer); - - }elseif($dimension=='3') { - xmlwriter_start_element($writer,'data'); - foreach($data as $entrykey=>$entry) { - xmlwriter_start_element($writer,$tag); - if(!empty($tagattribute)) { - xmlwriter_write_attribute($writer,'details',$tagattribute); - } - foreach($entry as $key=>$value) { - if(is_array($value)){ - xmlwriter_start_element($writer,$entrykey); - foreach($value as $k=>$v) { - xmlwriter_write_element($writer,$k,$v); - } - xmlwriter_end_element($writer); - } else { - xmlwriter_write_element($writer,$key,$value); - } - } - xmlwriter_end_element($writer); - } - xmlwriter_end_element($writer); - }elseif($dimension=='dynamic') { - xmlwriter_start_element($writer,'data'); - OC_OCS::toxml($writer,$data,'comment'); - xmlwriter_end_element($writer); - } - - xmlwriter_end_element($writer); - - xmlwriter_end_document( $writer ); - $txt.=xmlwriter_output_memory( $writer ); - unset($writer); - return($txt); - } - } - - public static function toXml($writer,$data,$node) { - foreach($data as $key => $value) { - if (is_numeric($key)) { - $key = $node; - } - if (is_array($value)){ - xmlwriter_start_element($writer,$key); - OC_OCS::toxml($writer,$value,$node); - xmlwriter_end_element($writer); - }else{ - xmlwriter_write_element($writer,$key,$value); - } - - } - } - - - - - /** - * return the config data of this server - * @param string $format - * @return string xml/json - */ - private static function apiConfig($format) { - $user=OC_OCS::checkpassword(false); - $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).''; - - $xml['version']='1.5'; - $xml['website']='ownCloud'; - $xml['host']=OCP\Util::getServerHost(); - $xml['contact']=''; - $xml['ssl']='false'; - echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1)); - } - - - /** - * check if the provided login/apikey/password is valid - * @param string $format - * @param string $login - * @param string $passwd - * @return string xml/json - */ - private static function personCheck($format,$login,$passwd) { - if($login<>''){ - if(OC_User::login($login,$passwd)){ - $xml['person']['personid']=$login; - echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2)); - }else{ - echo(OC_OCS::generatexml($format,'failed',102,'login not valid')); - } - }else{ - echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields')); - } - } - - - - // ACTIVITY API ############################################# - - /** - * get my activities - * @param string $format - * @param string $page - * @param string $pagesize - * @return string xml/json - */ - private static function activityGet($format,$page,$pagesize) { - $user=OC_OCS::checkpassword(); - - //TODO - - $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize); - echo($txt); - } - - /** - * submit a activity - * @param string $format - * @param string $message - * @return string xml/json - */ - private static function activityPut($format,$message) { - // not implemented in ownCloud - $user=OC_OCS::checkpassword(); - echo(OC_OCS::generatexml($format,'ok',100,'')); - } - - // PRIVATEDATA API ############################################# - - /** - * get private data and create the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @return string xml/json - */ - private static function privateDataGet($format,$app="",$key="") { - $user=OC_OCS::checkpassword(); - $result=OC_OCS::getData($user,$app,$key); - $xml=array(); - foreach($result as $i=>$log) { - $xml[$i]['key']=$log['key']; - $xml[$i]['app']=$log['app']; - $xml[$i]['value']=$log['value']; - } - - - $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it - echo($txt); - } - - /** - * set private data referenced by $key to $value and generate the xml for ocs - * @param string $format - * @param string $app - * @param string $key - * @param string $value - * @return string xml/json - */ + /** + * reads input date from get/post/cookies and converts the date to a special data-type + * + * @param string HTTP method to read the key from + * @param string Parameter to read + * @param string Variable type to format data + * @param mixed Default value to return if the key is not found + * @return mixed Data or if the key is not found and no default is set it will exit with a 400 Bad request + */ + public static function readData($method, $key, $type = 'raw', $default = null) { + if ($method == 'get') { + if (isset($_GET[$key])) { + $data = $_GET[$key]; + } else if (isset($default)) { + return $default; + } else { + $data = false; + } + } else if ($method == 'post') { + if (isset($_POST[$key])) { + $data = $_POST[$key]; + } else if (isset($default)) { + return $default; + } else { + $data = false; + } + } + if ($data === false) { + echo self::generateXml('', 'fail', 400, 'Bad request. Please provide a valid '.$key); + exit(); + } else { + // NOTE: Is the raw type necessary? It might be a little risky without sanitization + if ($type == 'raw') return $data; + elseif ($type == 'text') return OC_Util::sanitizeHTML($data); + elseif ($type == 'int') return (int) $data; + elseif ($type == 'float') return (float) $data; + elseif ($type == 'array') return OC_Util::sanitizeHTML($data); + else return OC_Util::sanitizeHTML($data); + } + } + + /** + main function to handle the REST request + **/ + public static function handle() { + // overwrite the 404 error page returncode + header("HTTP/1.0 200 OK"); + + + if($_SERVER['REQUEST_METHOD'] == 'GET') { + $method='get'; + }elseif($_SERVER['REQUEST_METHOD'] == 'PUT') { + $method='put'; + parse_str(file_get_contents("php://input"),$put_vars); + }elseif($_SERVER['REQUEST_METHOD'] == 'POST') { + $method='post'; + }else{ + echo('internal server error: method not supported'); + exit(); + } + + // preprocess url + $url = strtolower($_SERVER['REQUEST_URI']); + if(substr($url,(strlen($url)-1))<>'/') $url.='/'; + $ex=explode('/',$url); + $paracount=count($ex); + $format = self::readData($method, 'format', 'text', ''); + + // eventhandler + // CONFIG + // apiconfig - GET - CONFIG + if(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'config')){ + OC_OCS::apiconfig($format); + + // PERSON + // personcheck - POST - PERSON/CHECK + }elseif(($method=='post') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-3]=='person') and ($ex[$paracount-2] == 'check')){ + $login = self::readData($method, 'login', 'text'); + $passwd = self::readData($method, 'password', 'text'); + OC_OCS::personcheck($format,$login,$passwd); + + // ACTIVITY + // activityget - GET ACTIVITY page,pagesize als urlparameter + }elseif(($method=='get') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){ + $page = self::readData($method, 'page', 'int', 0); + $pagesize = self::readData($method, 'pagesize','int', 10); + if($pagesize<1 or $pagesize>100) $pagesize=10; + OC_OCS::activityget($format,$page,$pagesize); + + // activityput - POST ACTIVITY + }elseif(($method=='post') and ($ex[$paracount-3] == 'v1.php') and ($ex[$paracount-2] == 'activity')){ + $message = self::readData($method, 'message', 'text'); + OC_OCS::activityput($format,$message); + + + // PRIVATEDATA + // get - GET DATA + }elseif(($method=='get') and ($ex[$paracount-4] == 'v1.php') and ($ex[$paracount-2] == 'getattribute')){ + OC_OCS::privateDataGet($format); + + }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-3] == 'getattribute')){ + $app=$ex[$paracount-2]; + OC_OCS::privateDataGet($format, $app); + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'getattribute')){ + + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + OC_OCS::privateDataGet($format, $app,$key); + + // set - POST DATA + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-4] == 'setattribute')){ + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + $value = self::readData($method, 'value', 'text'); + OC_OCS::privatedataset($format, $app, $key, $value); + // delete - POST DATA + }elseif(($method=='post') and ($ex[$paracount-6] =='v1.php') and ($ex[$paracount-4] == 'deleteattribute')){ + $key=$ex[$paracount-2]; + $app=$ex[$paracount-3]; + OC_OCS::privatedatadelete($format, $app, $key); + + // CLOUD + // systemWebApps + }elseif(($method=='get') and ($ex[$paracount-5] == 'v1.php') and ($ex[$paracount-4]=='cloud') and ($ex[$paracount-3] == 'system') and ($ex[$paracount-2] == 'webapps')){ + OC_OCS::systemwebapps($format); + + // quotaget + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){ + $user=$ex[$paracount-3]; + OC_OCS::quotaget($format,$user); + + // quotaset + }elseif(($method=='post') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'quota')){ + $user=$ex[$paracount-3]; + $quota = self::readData('post', 'quota', 'int'); + OC_OCS::quotaset($format,$user,$quota); + + // keygetpublic + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'publickey')){ + $user=$ex[$paracount-3]; + OC_OCS::publicKeyGet($format,$user); + + // keygetprivate + }elseif(($method=='get') and ($ex[$paracount-6] == 'v1.php') and ($ex[$paracount-5]=='cloud') and ($ex[$paracount-4] == 'user') and ($ex[$paracount-2] == 'privatekey')){ + $user=$ex[$paracount-3]; + OC_OCS::privateKeyGet($format,$user); + + +// add more calls here +// please document all the call in the draft spec +// http://www.freedesktop.org/wiki/Specifications/open-collaboration-services-1.7#CLOUD + +// TODO: +// users +// groups +// bookmarks +// sharing +// versioning +// news (rss) + + + + }else{ + $txt='Invalid query, please check the syntax. API specifications are here: http://www.freedesktop.org/wiki/Specifications/open-collaboration-services. DEBUG OUTPUT:'."\n"; + $txt.=OC_OCS::getdebugoutput(); + echo(OC_OCS::generatexml($format,'failed',999,$txt)); + } + exit(); + } + + /** + * generated some debug information to make it easier to find faild API calls + * @return debug data string + */ + private static function getDebugOutput() { + $txt=''; + $txt.="debug output:\n"; + if(isset($_SERVER['REQUEST_METHOD'])) $txt.='http request method: '.$_SERVER['REQUEST_METHOD']."\n"; + if(isset($_SERVER['REQUEST_URI'])) $txt.='http request uri: '.$_SERVER['REQUEST_URI']."\n"; + if(isset($_GET)) foreach($_GET as $key=>$value) $txt.='get parameter: '.$key.'->'.$value."\n"; + if(isset($_POST)) foreach($_POST as $key=>$value) $txt.='post parameter: '.$key.'->'.$value."\n"; + return($txt); + } + + /** + * checks if the user is authenticated + * checks the IP whitlist, apikeys and login/password combination + * if $forceuser is true and the authentication failed it returns an 401 http response. + * if $forceuser is false and authentification fails it returns an empty username string + * @param bool $forceuser + * @return username string + */ + private static function checkPassword($forceuser=true) { + //valid user account ? + if(isset($_SERVER['PHP_AUTH_USER'])) $authuser=$_SERVER['PHP_AUTH_USER']; else $authuser=''; + if(isset($_SERVER['PHP_AUTH_PW'])) $authpw=$_SERVER['PHP_AUTH_PW']; else $authpw=''; + + if(empty($authuser)) { + if($forceuser){ + header('WWW-Authenticate: Basic realm="your valid user account or api key"'); + header('HTTP/1.0 401 Unauthorized'); + exit; + }else{ + $identifieduser=''; + } + }else{ + if(!OC_User::login($authuser,$authpw)){ + if($forceuser){ + header('WWW-Authenticate: Basic realm="your valid user account or api key"'); + header('HTTP/1.0 401 Unauthorized'); + exit; + }else{ + $identifieduser=''; + } + }else{ + $identifieduser=$authuser; + } + } + + return($identifieduser); + } + + + /** + * generates the xml or json response for the API call from an multidimenional data array. + * @param string $format + * @param string $status + * @param string $statuscode + * @param string $message + * @param array $data + * @param string $tag + * @param string $tagattribute + * @param int $dimension + * @param int $itemscount + * @param int $itemsperpage + * @return string xml/json + */ + private static function generateXml($format,$status,$statuscode,$message,$data=array(),$tag='',$tagattribute='',$dimension=-1,$itemscount='',$itemsperpage='') { + if($format=='json') { + $json=array(); + $json['status']=$status; + $json['statuscode']=$statuscode; + $json['message']=$message; + $json['totalitems']=$itemscount; + $json['itemsperpage']=$itemsperpage; + $json['data']=$data; + return(json_encode($json)); + }else{ + $txt=''; + $writer = xmlwriter_open_memory(); + xmlwriter_set_indent( $writer, 2 ); + xmlwriter_start_document($writer ); + xmlwriter_start_element($writer,'ocs'); + xmlwriter_start_element($writer,'meta'); + xmlwriter_write_element($writer,'status',$status); + xmlwriter_write_element($writer,'statuscode',$statuscode); + xmlwriter_write_element($writer,'message',$message); + if($itemscount<>'') xmlwriter_write_element($writer,'totalitems',$itemscount); + if(!empty($itemsperpage)) xmlwriter_write_element($writer,'itemsperpage',$itemsperpage); + xmlwriter_end_element($writer); + if($dimension=='0') { + // 0 dimensions + xmlwriter_write_element($writer,'data',$data); + + }elseif($dimension=='1') { + xmlwriter_start_element($writer,'data'); + foreach($data as $key=>$entry) { + xmlwriter_write_element($writer,$key,$entry); + } + xmlwriter_end_element($writer); + + }elseif($dimension=='2') { + xmlwriter_start_element($writer,'data'); + foreach($data as $entry) { + xmlwriter_start_element($writer,$tag); + if(!empty($tagattribute)) { + xmlwriter_write_attribute($writer,'details',$tagattribute); + } + foreach($entry as $key=>$value) { + if(is_array($value)){ + foreach($value as $k=>$v) { + xmlwriter_write_element($writer,$k,$v); + } + } else { + xmlwriter_write_element($writer,$key,$value); + } + } + xmlwriter_end_element($writer); + } + xmlwriter_end_element($writer); + + }elseif($dimension=='3') { + xmlwriter_start_element($writer,'data'); + foreach($data as $entrykey=>$entry) { + xmlwriter_start_element($writer,$tag); + if(!empty($tagattribute)) { + xmlwriter_write_attribute($writer,'details',$tagattribute); + } + foreach($entry as $key=>$value) { + if(is_array($value)){ + xmlwriter_start_element($writer,$entrykey); + foreach($value as $k=>$v) { + xmlwriter_write_element($writer,$k,$v); + } + xmlwriter_end_element($writer); + } else { + xmlwriter_write_element($writer,$key,$value); + } + } + xmlwriter_end_element($writer); + } + xmlwriter_end_element($writer); + }elseif($dimension=='dynamic') { + xmlwriter_start_element($writer,'data'); + OC_OCS::toxml($writer,$data,'comment'); + xmlwriter_end_element($writer); + } + + xmlwriter_end_element($writer); + + xmlwriter_end_document( $writer ); + $txt.=xmlwriter_output_memory( $writer ); + unset($writer); + return($txt); + } + } + + public static function toXml($writer,$data,$node) { + foreach($data as $key => $value) { + if (is_numeric($key)) { + $key = $node; + } + if (is_array($value)){ + xmlwriter_start_element($writer,$key); + OC_OCS::toxml($writer,$value,$node); + xmlwriter_end_element($writer); + }else{ + xmlwriter_write_element($writer,$key,$value); + } + } + } + + + + + /** + * return the config data of this server + * @param string $format + * @return string xml/json + */ + private static function apiConfig($format) { + $user=OC_OCS::checkpassword(false); + $url=substr(OCP\Util::getServerHost().$_SERVER['SCRIPT_NAME'],0,-11).''; + + $xml['version']='1.7'; + $xml['website']='ownCloud'; + $xml['host']=OCP\Util::getServerHost(); + $xml['contact']=''; + $xml['ssl']='false'; + echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'config','',1)); + } + + + /** + * check if the provided login/apikey/password is valid + * @param string $format + * @param string $login + * @param string $passwd + * @return string xml/json + */ + private static function personCheck($format,$login,$passwd) { + if($login<>''){ + if(OC_User::login($login,$passwd)){ + $xml['person']['personid']=$login; + echo(OC_OCS::generatexml($format,'ok',100,'',$xml,'person','check',2)); + }else{ + echo(OC_OCS::generatexml($format,'failed',102,'login not valid')); + } + }else{ + echo(OC_OCS::generatexml($format,'failed',101,'please specify all mandatory fields')); + } + } + + + + // ACTIVITY API ############################################# + + /** + * get my activities + * @param string $format + * @param string $page + * @param string $pagesize + * @return string xml/json + */ + private static function activityGet($format,$page,$pagesize) { + $user=OC_OCS::checkpassword(); + + //TODO + + $txt=OC_OCS::generatexml($format,'ok',100,'',$xml,'activity','full',2,$totalcount,$pagesize); + echo($txt); + } + + /** + * submit a activity + * @param string $format + * @param string $message + * @return string xml/json + */ + private static function activityPut($format,$message) { + // not implemented in ownCloud + $user=OC_OCS::checkpassword(); + echo(OC_OCS::generatexml($format,'ok',100,'')); + } + + // PRIVATEDATA API ############################################# + + /** + * get private data and create the xml for ocs + * @param string $format + * @param string $app + * @param string $key + * @return string xml/json + */ + private static function privateDataGet($format,$app="",$key="") { + $user=OC_OCS::checkpassword(); + $result=OC_OCS::getData($user,$app,$key); + $xml=array(); + foreach($result as $i=>$log) { + $xml[$i]['key']=$log['key']; + $xml[$i]['app']=$log['app']; + $xml[$i]['value']=$log['value']; + } + + + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'privatedata', 'full', 2, count($xml), 0);//TODO: replace 'privatedata' with 'attribute' once a new libattice has been released that works with it + echo($txt); + } + + /** + * set private data referenced by $key to $value and generate the xml for ocs + * @param string $format + * @param string $app + * @param string $key + * @param string $value + * @return string xml/json + */ private static function privateDataSet($format, $app, $key, $value) { $user=OC_OCS::checkpassword(); if(OC_OCS::setData($user,$app,$key,$value)){ @@ -529,4 +555,134 @@ class OC_OCS { public static function deleteData($user, $app, $key) { return OC_Preferences::deleteKey($user,$app,$key); } + + + // CLOUD API ############################################# + + /** + * get a list of installed web apps + * @param string $format + * @return string xml/json + */ + private static function systemWebApps($format) { + $login=OC_OCS::checkpassword(); + $apps=OC_App::getEnabledApps(); + $values=array(); + foreach($apps as $app) { + $info=OC_App::getAppInfo($app); + if(isset($info['standalone'])) { + $newvalue=array('name'=>$info['name'],'url'=>OC_Helper::linkToAbsolute($app,''),'icon'=>''); + $values[]=$newvalue; + } + + } + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $values, 'cloud', '', 2, 0, 0); + echo($txt); + + } + + + /** + * get the quota of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function quotaGet($format,$user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + + if(OC_User::userExists($user)){ + // calculate the disc space + $user_dir = '/'.$user.'/files'; + OC_Filesystem::init($user_dir); + $rootInfo=OC_FileCache::get(''); + $sharedInfo=OC_FileCache::get('/Shared'); + $used=$rootInfo['size']-$sharedInfo['size']; + $free=OC_Filesystem::free_space(); + $total=$free+$used; + if($total==0) $total=1; // prevent division by zero + $relative=round(($used/$total)*10000)/100; + + $xml=array(); + $xml['quota']=$total; + $xml['free']=$free; + $xml['used']=$used; + $xml['relative']=$relative; + + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * set the quota of a user + * @param string $format + * @param string $user + * @param string $quota + * @return string xml/json + */ + private static function quotaSet($format,$user,$quota) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin')) { + + // todo + // not yet implemented + // add logic here + error_log('OCS call: user:'.$user.' quota:'.$quota); + + $xml=array(); + $txt=OC_OCS::generatexml($format, 'ok', 100, '', $xml, 'cloud', '', 1, 0, 0); + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + /** + * get the public key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function publicKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the public key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + } + + /** + * get the private key of a user + * @param string $format + * @param string $user + * @return string xml/json + */ + private static function privateKeyGet($format,$user) { + $login=OC_OCS::checkpassword(); + if(OC_Group::inGroup($login, 'admin') or ($login==$user)) { + + if(OC_User::userExists($user)){ + // calculate the disc space + $txt='this is the private key of '.$user; + echo($txt); + }else{ + echo self::generateXml('', 'fail', 300, 'User does not exist'); + } + }else{ + echo self::generateXml('', 'fail', 300, 'You don´t have permission to access this ressource.'); + } + } + + } diff --git a/lib/ocsclient.php b/lib/ocsclient.php index 951d761d7e6..ae35470cff6 100644 --- a/lib/ocsclient.php +++ b/lib/ocsclient.php @@ -71,7 +71,7 @@ class OC_OCSClient{ $tmp=$data->data; $cats=array(); - foreach($tmp->category as $key=>$value) { + foreach($tmp->category as $value) { $id= (int) $value->id; $name= (string) $value->name; diff --git a/lib/preferences.php b/lib/preferences.php index f72378ce94f..c91423e69bc 100644 --- a/lib/preferences.php +++ b/lib/preferences.php @@ -165,7 +165,7 @@ class OC_Preferences{ public static function deleteKey( $user, $app, $key ){ // No need for more comments $query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ? AND appid = ? AND configkey = ?' ); - $result = $query->execute( array( $user, $app, $key )); + $query->execute( array( $user, $app, $key )); return true; } @@ -181,7 +181,7 @@ class OC_Preferences{ public static function deleteApp( $user, $app ){ // No need for more comments $query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ? AND appid = ?' ); - $result = $query->execute( array( $user, $app )); + $query->execute( array( $user, $app )); return true; } @@ -196,7 +196,7 @@ class OC_Preferences{ public static function deleteUser( $user ){ // No need for more comments $query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE userid = ?' ); - $result = $query->execute( array( $user )); + $query->execute( array( $user )); return true; } @@ -211,7 +211,7 @@ class OC_Preferences{ public static function deleteAppFromAllUsers( $app ){ // No need for more comments $query = OC_DB::prepare( 'DELETE FROM *PREFIX*preferences WHERE appid = ?' ); - $result = $query->execute( array( $app )); + $query->execute( array( $app )); return true; } diff --git a/lib/public/app.php b/lib/public/app.php index 38c51af9cdb..28411933beb 100644 --- a/lib/public/app.php +++ b/lib/public/app.php @@ -34,28 +34,6 @@ namespace OCP; * This class provides functions to manage apps in ownCloud */ class App { - - /** - * @brief Makes owncloud aware of this app - * @brief This call is deprecated and not necessary to use. - * @param $data array with all information - * @returns true/false - * - * This function registers the application. $data is an associative array. - * The following keys are required: - * - id: id of the application, has to be unique ('addressbook') - * - name: Human readable name ('Addressbook') - * - version: array with Version (major, minor, bugfix) ( array(1, 0, 2)) - * - * The following keys are optional: - * - order: integer, that influences the position of your application in - * a list of applications. Lower values come first. - * - */ - public static function register( $data ){ - } - - /** * @brief adds an entry to the navigation * @param $data array containing the data diff --git a/lib/public/groupinterface.php b/lib/public/groupinterface.php new file mode 100644 index 00000000000..97833028118 --- /dev/null +++ b/lib/public/groupinterface.php @@ -0,0 +1,31 @@ +<?php +/** +* ownCloud +* +* @author Arthur Schiwon +* @copyright 2012 Arthur Schiwon blizzz@owncloud.org +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * Public interface of ownCloud for apps to use. + * Group Class. + * + */ + +namespace OCP; + +interface GroupInterface extends \OC_Group_Interface {}
\ No newline at end of file diff --git a/lib/public/json.php b/lib/public/json.php index 1bc1e3ab4d5..99df79173eb 100644 --- a/lib/public/json.php +++ b/lib/public/json.php @@ -35,70 +35,137 @@ namespace OCP; */ class JSON { - /** * @brief Encode and print $data in JSON format * @param array $data The data to use * @param string $setContentType the optional content type + * @return string json formatted string. */ public static function encodedPrint( $data, $setContentType=true ){ return(\OC_JSON::encodedPrint( $data, $setContentType )); } - /** - * @brief Check if the user is logged in, send json error msg if not + * Check if the user is logged in, send json error msg if not. + * + * This method checks if a user is logged in. If not, a json error + * response will be return and the method will exit from execution + * of the script. + * The returned json will be in the format: + * + * {"status":"error","data":{"message":"Authentication error."}} + * + * Add this call to the start of all ajax method files that requires + * an authenticated user. + * + * @return string json formatted error string if not authenticated. */ public static function checkLoggedIn(){ return(\OC_JSON::checkLoggedIn()); } /** - * @brief Check an ajax get/post call if the request token is valid. - * @return json Error msg if not valid. - */ + * Check an ajax get/post call if the request token is valid. + * + * This method checks for a valid variable 'requesttoken' in $_GET, + * $_POST and $_SERVER. If a valid token is not found, a json error + * response will be return and the method will exit from execution + * of the script. + * The returned json will be in the format: + * + * {"status":"error","data":{"message":"Token expired. Please reload page."}} + * + * Add this call to the start of all ajax method files that creates, + * updates or deletes anything. + * In cases where you e.g. use an ajax call to load a dialog containing + * a submittable form, you will need to add the requesttoken first as a + * parameter to the ajax call, then assign it to the template and finally + * add a hidden input field also named 'requesttoken' containing the value. + * + * @return string json formatted error string if not valid. + */ public static function callCheck(){ return(\OC_JSON::callCheck()); } /** - * @brief Send json success msg + * Send json success msg + * + * Return a json success message with optional extra data. + * @see OCP\JSON::error() for the format to use. + * * @param array $data The data to use + * @return string json formatted string. */ public static function success( $data = array() ){ return(\OC_JSON::success( $data )); } - /** - * @brief Send json error msg + * Send json error msg + * + * Return a json error message with optional extra data for + * error message or app specific data. + * + * Example use: + * + * $id = [some value] + * OCP\JSON::error(array('data':array('message':'An error happened', 'id': $id))); + * + * Will return the json formatted string: + * + * {"status":"error","data":{"message":"An error happened", "id":[some value]}} + * * @param array $data The data to use + * @return string json formatted error string. */ public static function error( $data = array() ){ return(\OC_JSON::error( $data )); } - /** - * @brief set Content-Type header to jsonrequest - * @param array $type The contwnt type header - */ + * @brief set Content-Type header to jsonrequest + * @param array $type The contwnt type header + * @return string json formatted string. + */ public static function setContentTypeHeader( $type='application/json' ){ return(\OC_JSON::setContentTypeHeader( $type )); } - /** - * @brief Check if the App is enabled and send JSON error message instead - * @param string $app The app to check - */ + * Check if the App is enabled and send JSON error message instead + * + * This method checks if a specific app is enabled. If not, a json error + * response will be return and the method will exit from execution + * of the script. + * The returned json will be in the format: + * + * {"status":"error","data":{"message":"Application is not enabled."}} + * + * Add this call to the start of all ajax method files that requires + * a specific app to be enabled. + * + * @param string $app The app to check + * @return string json formatted string if not enabled. + */ public static function checkAppEnabled( $app ){ return(\OC_JSON::checkAppEnabled( $app )); } - /** - * @brief Check if the user is a admin, send json error msg if not + * Check if the user is a admin, send json error msg if not + * + * This method checks if the current user has admin rights. If not, a json error + * response will be return and the method will exit from execution + * of the script. + * The returned json will be in the format: + * + * {"status":"error","data":{"message":"Authentication error."}} + * + * Add this call to the start of all ajax method files that requires + * administrative rights. + * + * @return string json formatted string if not admin user. */ public static function checkAdminUser(){ return(\OC_JSON::checkAdminUser()); diff --git a/lib/public/userinterface.php b/lib/public/userinterface.php new file mode 100644 index 00000000000..b73a8f8d8b0 --- /dev/null +++ b/lib/public/userinterface.php @@ -0,0 +1,31 @@ +<?php +/** +* ownCloud +* +* @author Arthur Schiwon +* @copyright 2012 Arthur Schiwon blizzz@owncloud.org +* +* This library is free software; you can redistribute it and/or +* modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE +* License as published by the Free Software Foundation; either +* version 3 of the License, or any later version. +* +* This library is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU AFFERO GENERAL PUBLIC LICENSE for more details. +* +* You should have received a copy of the GNU Affero General Public +* License along with this library. If not, see <http://www.gnu.org/licenses/>. +* +*/ + +/** + * Public interface of ownCloud for apps to use. + * User Class. + * + */ + +namespace OCP; + +interface UserInterface extends \OC_User_Interface {}
\ No newline at end of file diff --git a/lib/public/util.php b/lib/public/util.php index 43f9e3cee5d..75ca29f7129 100644 --- a/lib/public/util.php +++ b/lib/public/util.php @@ -320,4 +320,15 @@ class Util { public static function mb_str_replace($search, $replace, $subject, $encoding = 'UTF-8', &$count = null) { return(\OC_Helper::mb_str_replace($search, $replace, $subject, $encoding, $count)); } + + /** + * @brief performs a search in a nested array + * @param haystack the array to be searched + * @param needle the search string + * @param $index optional, only search this key name + * @return the key of the matching field, otherwise false + */ + public static function recursiveArraySearch($haystack, $needle, $index = null) { + return(\OC_Helper::recursiveArraySearch($haystack, $needle, $index)); + } } diff --git a/lib/search/provider.php b/lib/search/provider.php index 838ab696d04..b3ee79b4770 100644 --- a/lib/search/provider.php +++ b/lib/search/provider.php @@ -2,13 +2,17 @@ /** * provides search functionalty */ -class OC_Search_Provider { - public function __construct($options){} +abstract class OC_Search_Provider { + private $options; + + public function __construct($options){ + $this->options=$options; + } /** * search for $query * @param string $query * @return array An array of OC_Search_Result's */ - public function search($query){} + abstract public function search($query); } diff --git a/lib/setup.php b/lib/setup.php index 2f73c486c9c..4d71bed86e2 100644 --- a/lib/setup.php +++ b/lib/setup.php @@ -102,7 +102,6 @@ class OC_Setup { } else { $oldUser=OC_Config::getValue('dbuser', false); - $oldPassword=OC_Config::getValue('dbpassword', false); $query="SELECT user FROM mysql.user WHERE user='$dbuser'"; //this should be enough to check for admin rights in mysql if(mysql_query($query, $connection)) { @@ -257,7 +256,7 @@ class OC_Setup { OC_Installer::installShippedApps(); //create htaccess files for apache hosts - if (strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { + if (isset($_SERVER['SERVER_SOFTWARE']) && strstr($_SERVER['SERVER_SOFTWARE'], 'Apache')) { self::createHtaccess(); } diff --git a/lib/streamwrappers.php b/lib/streamwrappers.php index f1e0fa0e1d9..f502c6170bd 100644 --- a/lib/streamwrappers.php +++ b/lib/streamwrappers.php @@ -1,6 +1,4 @@ <?php -global $FAKEDIRS; -$FAKEDIRS=array(); class OC_FakeDirStream{ public static $dirs=array(); @@ -8,8 +6,6 @@ class OC_FakeDirStream{ private $index; public function dir_opendir($path,$options){ - global $FAKEDIRS; - $url=parse_url($path); $this->name=substr($path,strlen('fakedir://')); $this->index=0; if(!isset(self::$dirs[$this->name])){ @@ -161,7 +157,6 @@ class OC_StaticStreamWrapper { public function stream_write($data) { if (!$this->writable) return 0; $size = strlen($data); - $len = strlen(self::$data[$this->path]); if ($this->stream_eof()) { self::$data[$this->path] .= $data; } else { diff --git a/lib/template.php b/lib/template.php index 3b48c27b9b4..5b6999af533 100644 --- a/lib/template.php +++ b/lib/template.php @@ -82,7 +82,6 @@ function relative_modified_date($timestamp) { $diffhours = round($diffminutes/60); $diffdays = round($diffhours/24); $diffmonths = round($diffdays/31); - $diffyears = round($diffdays/365); if($timediff < 60) { return $l->t('seconds ago'); } else if($timediff < 120) { return $l->t('1 minute ago'); } diff --git a/lib/templatelayout.php b/lib/templatelayout.php index d33a87e9e4c..588a7845997 100644 --- a/lib/templatelayout.php +++ b/lib/templatelayout.php @@ -123,7 +123,7 @@ class OC_TemplateLayout extends OC_Template { elseif(self::appendIfExist($files, $apps_dir['path'], $apps_dir['url'], "$style.css")) { $append =true; break; } } if(! $append) { - echo('css file not found: style:'.$script.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); + echo('css file not found: style:'.$style.' formfactor:'.$fext.' webroot:'.OC::$WEBROOT.' serverroot:'.OC::$SERVERROOT); die(); } } diff --git a/lib/user.php b/lib/user.php index f1903093d6d..e3c9c23effa 100644 --- a/lib/user.php +++ b/lib/user.php @@ -21,7 +21,7 @@ */ /** - * This class provides wrapper methods for user management. Multiple backends are + * This class provides wrapper methods for user management. Multiple backends are * supported. User management operations are delegated to the configured backend for * execution. * @@ -50,8 +50,8 @@ class OC_User { * * Makes a list of backends that can be used by other modules */ - public static function registerBackend( $name ){ - self::$_backends[] = $name; + public static function registerBackend( $backend ){ + self::$_backends[] = $backend; return true; } @@ -83,28 +83,38 @@ class OC_User { * Set the User Authentication Module */ public static function useBackend( $backend = 'database' ){ - // You'll never know what happens - if( null === $backend OR !is_string( $backend )){ - $backend = 'database'; - } + if($backend instanceof OC_User_Interface){ + self::$_usedBackends[get_class($backend)]=$backend; + }else{ + // You'll never know what happens + if( null === $backend OR !is_string( $backend )){ + $backend = 'database'; + } - // Load backend - switch( $backend ){ - case 'database': - case 'mysql': - case 'sqlite': - self::$_usedBackends[$backend] = new OC_User_Database(); - break; - default: - $className = 'OC_USER_' . strToUpper($backend); - self::$_usedBackends[$backend] = new $className(); - break; + // Load backend + switch( $backend ){ + case 'database': + case 'mysql': + case 'sqlite': + self::$_usedBackends[$backend] = new OC_User_Database(); + break; + default: + $className = 'OC_USER_' . strToUpper($backend); + self::$_usedBackends[$backend] = new $className(); + break; + } } - true; } /** + * remove all used backends + */ + public static function clearBackends(){ + self::$_usedBackends=array(); + } + + /** * @brief Create a new user * @param $uid The username of the user to create * @param $password The password of the new user @@ -200,7 +210,7 @@ class OC_User { if( $run ){ $uid=self::checkPassword( $uid, $password ); if($uid){ - session_regenerate_id(); + session_regenerate_id(true); self::setUserId($uid); OC_Hook::emit( "OC_User", "post_login", array( "uid" => $uid, 'password'=>$password )); return true; diff --git a/lib/user/backend.php b/lib/user/backend.php index be068a63ce0..daa942d261c 100644 --- a/lib/user/backend.php +++ b/lib/user/backend.php @@ -42,7 +42,7 @@ define('OC_USER_BACKEND_CHECK_PASSWORD', 0x000100); * * Subclass this for your own backends, and see OC_User_Example for descriptions */ -abstract class OC_User_Backend { +abstract class OC_User_Backend implements OC_User_Interface { protected $possibleActions = array( OC_USER_BACKEND_CREATE_USER => 'createUser', diff --git a/lib/user/database.php b/lib/user/database.php index a48b8357d64..cc27b3ddbfd 100644 --- a/lib/user/database.php +++ b/lib/user/database.php @@ -39,7 +39,6 @@ require_once 'phpass/PasswordHash.php'; * Class for user management in a SQL Database (e.g. MySQL, SQLite) */ class OC_User_Database extends OC_User_Backend { - static private $userGroupCache=array(); /** * @var PasswordHash */ @@ -87,7 +86,7 @@ class OC_User_Database extends OC_User_Backend { public function deleteUser( $uid ){ // Delete user-group-relation $query = OC_DB::prepare( "DELETE FROM `*PREFIX*users` WHERE uid = ?" ); - $result = $query->execute( array( $uid )); + $query->execute( array( $uid )); return true; } @@ -104,11 +103,10 @@ class OC_User_Database extends OC_User_Backend { $hasher=$this->getHasher(); $hash = $hasher->HashPassword($password.OC_Config::getValue('passwordsalt', '')); $query = OC_DB::prepare( "UPDATE *PREFIX*users SET password = ? WHERE uid = ?" ); - $result = $query->execute( array( $hash, $uid )); + $query->execute( array( $hash, $uid )); return true; - } - else{ + }else{ return false; } } diff --git a/lib/user/example.php b/lib/user/example.php index 7f3fd1b8578..77246d8136c 100644 --- a/lib/user/example.php +++ b/lib/user/example.php @@ -35,9 +35,7 @@ abstract class OC_User_Example extends OC_User_Backend { * Creates a new user. Basic checking of username is done in OC_User * itself, not in its subclasses. */ - public function createUser($uid, $password){ - return OC_USER_BACKEND_NOT_IMPLEMENTED; - } + abstract public function createUser($uid, $password); /** * @brief Set password @@ -47,9 +45,7 @@ abstract class OC_User_Example extends OC_User_Backend { * * Change the password of a user */ - public function setPassword($uid, $password){ - return OC_USER_BACKEND_NOT_IMPLEMENTED; - } + abstract public function setPassword($uid, $password); /** * @brief Check if the password is correct @@ -60,7 +56,5 @@ abstract class OC_User_Example extends OC_User_Backend { * Check if the password is correct without logging in the user * returns the user id or false */ - public function checkPassword($uid, $password){ - return OC_USER_BACKEND_NOT_IMPLEMENTED; - } + abstract public function checkPassword($uid, $password); } diff --git a/lib/user/interface.php b/lib/user/interface.php new file mode 100644 index 00000000000..dc3685dc20d --- /dev/null +++ b/lib/user/interface.php @@ -0,0 +1,60 @@ +<?php + +/** + * ownCloud - user interface + * + * @author Arthur Schiwon + * @copyright 2012 Arthur Schiwon blizzz@owncloud.org + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU AFFERO GENERAL PUBLIC LICENSE + * License as published by the Free Software Foundation; either + * version 3 of the License, or any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU AFFERO GENERAL PUBLIC LICENSE for more details. + * + * You should have received a copy of the GNU Affero General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + */ + +interface OC_User_Interface { + + /** + * @brief Check if backend implements actions + * @param $actions bitwise-or'ed actions + * @returns boolean + * + * Returns the supported actions as int to be + * compared with OC_USER_BACKEND_CREATE_USER etc. + */ + public function implementsActions($actions); + + /** + * @brief delete a user + * @param $uid The username of the user to delete + * @returns true/false + * + * Deletes a user + */ + public function deleteUser($uid); + + /** + * @brief Get a list of all users + * @returns array with all uids + * + * Get a list of all users. + */ + public function getUsers(); + + /** + * @brief check if a user exists + * @param string $uid the username + * @return boolean + */ + public function userExists($uid); + +}
\ No newline at end of file diff --git a/lib/util.php b/lib/util.php index 2a7b8a922f9..0c563278cc5 100755 --- a/lib/util.php +++ b/lib/util.php @@ -77,13 +77,13 @@ class OC_Util { return '5 pre alpha'; } - /** - * 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 - */ - public static function getEditionString(){ - return ''; - } + /** + * 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 + */ + public static function getEditionString(){ + return ''; + } /** * add a javascript file @@ -131,12 +131,12 @@ class OC_Util { self::$headers[]=array('tag'=>$tag,'attributes'=>$attributes,'text'=>$text); } - /** - * formats a timestamp in the "right" way - * - * @param int timestamp $timestamp - * @param bool dateOnly option to ommit time from the result - */ + /** + * formats a timestamp in the "right" way + * + * @param int timestamp $timestamp + * @param bool dateOnly option to ommit time from the result + */ public static function formatDate( $timestamp,$dateOnly=false){ if(isset($_SESSION['timezone'])){//adjust to clients timezone if we know it $systemTimeZone = intval(date('O')); @@ -189,8 +189,6 @@ class OC_Util { if(!(is_callable('sqlite_open') or class_exists('SQLite3')) and !is_callable('mysql_connect') and !is_callable('pg_connect')){ $errors[]=array('error'=>'No database drivers (sqlite, mysql, or postgresql) installed.<br/>','hint'=>'');//TODO: sane hint } - $CONFIG_DBTYPE = OC_Config::getValue( "dbtype", "sqlite" ); - $CONFIG_DBNAME = OC_Config::getValue( "dbname", "owncloud" ); //common hint for all file permissons error messages $permissionsHint="Permissions can usually be fixed by giving the webserver write access to the ownCloud directory"; @@ -440,26 +438,25 @@ 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 - */ - public static function ishtaccessworking() { - + /** + * 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() { // testdata $filename='/htaccesstest.txt'; $testcontent='testcontent'; // creating a test file - $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename; - $fp = @fopen($testfile, 'w'); - @fwrite($fp, $testcontent); - @fclose($fp); + $testfile = OC_Config::getValue( "datadirectory", OC::$SERVERROOT."/data" ).'/'.$filename; + $fp = @fopen($testfile, 'w'); + @fwrite($fp, $testcontent); + @fclose($fp); // accessing the file via http - $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename; - $fp = @fopen($url, 'r'); - $content=@fread($fp, 2048); - @fclose($fp); + $url = OC_Helper::serverProtocol(). '://' . OC_Helper::serverHost() . OC::$WEBROOT.'/data'.$filename; + $fp = @fopen($url, 'r'); + $content=@fread($fp, 2048); + @fclose($fp); // cleanup @unlink($testfile); @@ -469,13 +466,7 @@ class OC_Util { return(false); }else{ return(true); - } - - } - - - - + } } |