diff options
author | Georg Ehrke <dev@georgswebsite.de> | 2012-04-21 22:12:31 +0200 |
---|---|---|
committer | Georg Ehrke <dev@georgswebsite.de> | 2012-04-21 22:12:31 +0200 |
commit | e29ae46609f42a03ade20c7f935e2cded84db51f (patch) | |
tree | b896f79353e792c5d34d7dc8dc9220c49bbfd6df /apps | |
parent | cf492a96496920c42f3ad384f5ca0886a5323c72 (diff) | |
parent | 6bfe2289be05e9f54272a86a0f957ec41ef32e28 (diff) | |
download | nextcloud-server-e29ae46609f42a03ade20c7f935e2cded84db51f.tar.gz nextcloud-server-e29ae46609f42a03ade20c7f935e2cded84db51f.zip |
fix merge conflicts
Diffstat (limited to 'apps')
-rw-r--r-- | apps/calendar/ajax/import/import.php | 134 | ||||
-rw-r--r-- | apps/calendar/export.php | 4 | ||||
-rw-r--r-- | apps/files_encryption/lib/crypt.php | 55 | ||||
-rw-r--r-- | apps/files_encryption/lib/cryptstream.php | 38 | ||||
-rw-r--r-- | apps/files_encryption/lib/proxy.php | 7 | ||||
-rw-r--r-- | apps/files_encryption/tests/encryption.php | 42 | ||||
-rw-r--r-- | apps/files_encryption/tests/stream.php | 56 | ||||
-rw-r--r-- | apps/files_external/appinfo/app.php | 1 | ||||
-rw-r--r-- | apps/files_external/lib/swift.php | 516 | ||||
-rw-r--r-- | apps/files_external/tests/config.php | 9 | ||||
-rw-r--r-- | apps/files_external/tests/swift.php | 32 |
11 files changed, 779 insertions, 115 deletions
diff --git a/apps/calendar/ajax/import/import.php b/apps/calendar/ajax/import/import.php index d0bdab4f0d5..4d5e7340aef 100644 --- a/apps/calendar/ajax/import/import.php +++ b/apps/calendar/ajax/import/import.php @@ -7,11 +7,12 @@ */ //check for calendar rights or create new one ob_start(); -require_once('../../../../lib/base.php'); +require_once ('../../../../lib/base.php'); OC_JSON::checkLoggedIn(); OC_Util::checkAppEnabled('calendar'); -$nl = "\n\r"; -$progressfile = OC::$APPSROOT . '/apps/calendar/import_tmp/' . md5(session_id()) . '.txt'; +$nl="\r\n"; +$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true); +$progressfile = 'import_tmp/' . md5(session_id()) . '.txt'; if(is_writable('import_tmp/')){ $progressfopen = fopen($progressfile, 'w'); fwrite($progressfopen, '10'); @@ -29,85 +30,94 @@ if($_POST['method'] == 'new'){ } $id = $_POST['id']; } -//analyse the calendar file if(is_writable('import_tmp/')){ $progressfopen = fopen($progressfile, 'w'); fwrite($progressfopen, '20'); fclose($progressfopen); } -$searchfor = array('VEVENT', 'VTODO', 'VJOURNAL'); -$parts = $searchfor; -$filearr = explode($nl, $file); -$inelement = false; -$parts = array(); +// normalize the newlines +$file = str_replace(array("\r","\n\n"), array("\n","\n"), $file); +$lines = explode("\n", $file); +unset($file); +if(is_writable('import_tmp/')){ + $progressfopen = fopen($progressfile, 'w'); + fwrite($progressfopen, '30'); + fclose($progressfopen); +} +// analyze the file, group components by uid, and keep refs to originating calendar object +// $cals is array calendar objects, keys are 1st line# $cal, ie array( $cal => $caldata ) +// $caldata is array( 'first' => 1st component line#, 'last' => last comp line#, 'end' => end line# ) +// $caldata is used to create prefix/suffix strings when building import text +// $uids is array of component arrays, keys are $uid, ie array( $uid => array( $beginlineno => $component ) ) +// $component is array( 'end' => end line#, 'cal'=> $cal ) +$comp=$uid=$cal=false; +$cals=$uids=array(); $i = 0; -foreach($filearr as $line){ - foreach($searchfor as $search){ - if(substr_count($line, $search) == 1){ - list($attr, $val) = explode(':', $line); - if($attr == 'BEGIN'){ - $parts[]['begin'] = $i; - $inelement = true; +foreach($lines as $line) { + + if(strpos($line, ':')!==false) { + list($attr, $val) = explode(':', strtoupper($line)); + if ($attr == 'BEGIN' && $val == 'VCALENDAR') { + $cal = $i; + $cals[$cal] = array('first'=>$i,'last'=>$i,'end'=>$i); + } elseif ($attr =='BEGIN' && $cal!==false && isset($comps[$val])) { + $comp = $val; + $beginNo = $i; + } elseif ($attr == 'END' && $cal!==false && $val == 'VCALENDAR') { + if($comp!==false) { + unset($cals[$cal]); // corrupt calendar, unset it + } else { + $cals[$cal]['end'] = $i; + } + $comp=$uid=$cal=false; // reset calendar + } elseif ($attr == 'END' && $comp!==false && $val == $comp) { + if(! $uid) { + $uid = OC_Calendar_Object::createUID(); } - if($attr == 'END'){ - $parts[count($parts) - 1]['end'] = $i; - $inelement = false; + $uids[$uid][$beginNo] = array('end'=>$i, 'cal'=>$cal); + if ($cals[$cal]['first'] == $cal) { + $cals[$cal]['first'] = $beginNo; } + $cals[$cal]['last'] = $i; + $comp=$uid=false; // reset component + } elseif ($attr =="UID" && $comp!==false) { + list($attr, $uid) = explode(':', $line); } } $i++; } -//import the calendar +// import the calendar if(is_writable('import_tmp/')){ $progressfopen = fopen($progressfile, 'w'); - fwrite($progressfopen, '40'); + fwrite($progressfopen, '60'); fclose($progressfopen); } -$start = ''; -for ($i = 0; $i < $parts[0]['begin']; $i++) { - if($i == 0){ - $start = $filearr[0]; - }else{ - $start .= $nl . $filearr[$i]; - } -} -$end = ''; -for($i = $parts[count($parts) - 1]['end'] + 1;$i <= count($filearr) - 1; $i++){ - if($i == $parts[count($parts) - 1]['end'] + 1){ - $end = $filearr[$parts[count($parts) - 1]['end'] + 1]; - }else{ - $end .= $nl . $filearr[$i]; - } -} -if(is_writable('import_tmp/')){ - $progressfopen = fopen($progressfile, 'w'); - fwrite($progressfopen, '50'); - fclose($progressfopen); -} -$importready = array(); -foreach($parts as $part){ - for($i = $part['begin']; $i <= $part['end'];$i++){ - if($i == $part['begin']){ - $content = $filearr[$i]; - }else{ - $content .= $nl . $filearr[$i]; +foreach($uids as $uid) { + + $prefix=$suffix=$content=array(); + foreach($uid as $begin=>$details) { + + $cal = $details['cal']; + if(!isset($cals[$cal])) { + continue; // from corrupt/incomplete calendar + } + $cdata = $cals[$cal]; + // if we have multiple components from different calendar objects, + // we should really merge their elements (enhancement?) -- 1st one wins for now. + if(! count($prefix)) { + $prefix = array_slice($lines, $cal, $cdata['first'] - $cal); } + if(! count($suffix)) { + $suffix = array_slice($lines, $cdata['last']+1, $cdata['end'] - $cdata['last']); + } + $content = array_merge($content, array_slice($lines, $begin, $details['end'] - $begin + 1)); } - $importready[] = $start . $nl . $content . $nl . $end; -} -if(is_writable('import_tmp/')){ - $progressfopen = fopen($progressfile, 'w'); - fwrite($progressfopen, '70'); - fclose($progressfopen); -} -if(count($parts) == 1){ - OC_Calendar_Object::add($id, $file); -}else{ - foreach($importready as $import){ + if(count($content)) { + $import = join($nl, array_merge($prefix, $content, $suffix)) . $nl; OC_Calendar_Object::add($id, $import); } } -//done the import +// finished import if(is_writable('import_tmp/')){ $progressfopen = fopen($progressfile, 'w'); fwrite($progressfopen, '100'); @@ -117,4 +127,4 @@ sleep(3); if(is_writable('import_tmp/')){ unlink($progressfile); } -OC_JSON::success(); +OC_JSON::success();
\ No newline at end of file diff --git a/apps/calendar/export.php b/apps/calendar/export.php index e4caa1bde75..95cba03906f 100644 --- a/apps/calendar/export.php +++ b/apps/calendar/export.php @@ -11,7 +11,7 @@ OC_Util::checkLoggedIn(); OC_Util::checkAppEnabled('calendar'); $cal = isset($_GET['calid']) ? $_GET['calid'] : NULL; $event = isset($_GET['eventid']) ? $_GET['eventid'] : NULL; -$nl = "\n\r"; +$nl = "\r\n"; if(isset($cal)){ $calendar = OC_Calendar_App::getCalendar($cal, true); $calobjects = OC_Calendar_Object::all($cal); @@ -28,4 +28,4 @@ if(isset($cal)){ header('Content-Disposition: inline; filename=' . $data['summary'] . '.ics'); echo $data['calendardata']; } -?>
\ No newline at end of file +?> diff --git a/apps/files_encryption/lib/crypt.php b/apps/files_encryption/lib/crypt.php index 246d4f672db..8cf9451c63c 100644 --- a/apps/files_encryption/lib/crypt.php +++ b/apps/files_encryption/lib/crypt.php @@ -119,7 +119,7 @@ class OC_Crypt { */ public static function encrypt( $content, $key='') { $bf = self::getBlowfish($key); - return($bf->encrypt($content)); + return $bf->encrypt($content); } /** @@ -132,61 +132,62 @@ class OC_Crypt { */ public static function decrypt( $content, $key='') { $bf = self::getBlowfish($key); - return($bf->decrypt($content)); + $data=$bf->decrypt($content); + return rtrim($data, "\0"); } /** * @brief encryption of a file - * @param $filename - * @param $key the encryption key + * @param string $source + * @param string $target + * @param string $key the decryption key * * This function encrypts a file */ - public static function encryptfile( $filename, $key) { - $handleread = fopen($filename, "rb"); - if($handleread<>FALSE) { - $handlewrite = fopen($filename.OC_Crypt::$encription_extension, "wb"); + public static function encryptFile( $source, $target, $key='') { + $handleread = fopen($source, "rb"); + if($handleread!=FALSE) { + $handlewrite = fopen($target, "wb"); while (!feof($handleread)) { $content = fread($handleread, 8192); $enccontent=OC_CRYPT::encrypt( $content, $key); fwrite($handlewrite, $enccontent); } fclose($handlewrite); - unlink($filename); + fclose($handleread); } - fclose($handleread); } - /** - * @brief decryption of a file - * @param $filename - * @param $key the decryption key - * - * This function decrypts a file - */ - public static function decryptfile( $filename, $key) { - $handleread = fopen($filename.OC_Crypt::$encription_extension, "rb"); - if($handleread<>FALSE) { - $handlewrite = fopen($filename, "wb"); + /** + * @brief decryption of a file + * @param string $source + * @param string $target + * @param string $key the decryption key + * + * This function decrypts a file + */ + public static function decryptFile( $source, $target, $key='') { + $handleread = fopen($source, "rb"); + if($handleread!=FALSE) { + $handlewrite = fopen($target, "wb"); while (!feof($handleread)) { $content = fread($handleread, 8192); $enccontent=OC_CRYPT::decrypt( $content, $key); fwrite($handlewrite, $enccontent); } fclose($handlewrite); - unlink($filename.OC_Crypt::$encription_extension); + fclose($handleread); } - fclose($handleread); } /** * encrypt data in 8192b sized blocks */ - public static function blockEncrypt($data){ + public static function blockEncrypt($data, $key=''){ $result=''; while(strlen($data)){ - $result=self::encrypt(substr($data,0,8192)); + $result.=self::encrypt(substr($data,0,8192),$key); $data=substr($data,8192); } return $result; @@ -195,10 +196,10 @@ class OC_Crypt { /** * decrypt data in 8192b sized blocks */ - public static function blockDecrypt($data){ + public static function blockDecrypt($data, $key=''){ $result=''; while(strlen($data)){ - $result=self::decrypt(substr($data,0,8192)); + $result.=self::decrypt(substr($data,0,8192),$key); $data=substr($data,8192); } return $result; diff --git a/apps/files_encryption/lib/cryptstream.php b/apps/files_encryption/lib/cryptstream.php index 86583096f1d..21fa38e4b59 100644 --- a/apps/files_encryption/lib/cryptstream.php +++ b/apps/files_encryption/lib/cryptstream.php @@ -64,29 +64,19 @@ class OC_CryptStream{ } public function stream_read($count){ - $pos=0; - $currentPos=ftell($this->source); - $offset=$currentPos%8192; - $result=''; - if($offset>0){ - if($this->meta['seekable']){ - fseek($this->source,-$offset,SEEK_CUR);//if seeking isnt supported the internal read buffer will be used - }else{ - $pos=strlen($this->readBuffer); - $result=$this->readBuffer; - } + //$count will always be 8192 https://bugs.php.net/bug.php?id=21641 + //This makes this function a lot simpler but will breake everything the moment it's fixed + if($count!=8192){ + OC_Log::write('files_encryption','php bug 21641 no longer holds, decryption will not work',OC_Log::FATAL); + die(); } - while($count>$pos){ - $data=fread($this->source,8192); - $pos+=8192; - if(strlen($data)){ - $result.=OC_Crypt::decrypt($data); - } - } - if(!$this->meta['seekable']){ - $this->readBuffer=substr($result,$count); + $data=fread($this->source,8192); + if(strlen($data)){ + $result=OC_Crypt::decrypt($data); + }else{ + $result=''; } - return substr($result,0,$count); + return $result; } public function stream_write($data){ @@ -107,8 +97,10 @@ class OC_CryptStream{ $oldPos=ftell($this->source); $encryptedBlock=fread($this->source,8192); fseek($this->source,$oldPos); - $block=OC_Crypt::decrypt($encryptedBlock); - $data.=substr($block,strlen($data)); + if($encryptedBlock){ + $block=OC_Crypt::decrypt($encryptedBlock); + $data.=substr($block,strlen($data)); + } } $encrypted=OC_Crypt::encrypt(substr($data,0,8192)); fwrite($this->source,$encrypted); diff --git a/apps/files_encryption/lib/proxy.php b/apps/files_encryption/lib/proxy.php index c68df06f9fa..a0de411a7b6 100644 --- a/apps/files_encryption/lib/proxy.php +++ b/apps/files_encryption/lib/proxy.php @@ -28,6 +28,7 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ private static $blackList=null; //mimetypes blacklisted from encryption private static $metaData=array(); //metadata cache + private static $enableEncryption=null; /** * check if a file should be encrypted during write @@ -35,6 +36,12 @@ class OC_FileProxy_Encryption extends OC_FileProxy{ * @return bool */ private static function shouldEncrypt($path){ + if(is_null($this->enableEncryption)){ + $this->enableEncryption=(OC_Appconfig::getValue('files_encryption','enabled','true')=='true'); + } + if(!$this->enableEncryption){ + return false; + } if(is_null(self::$blackList)){ self::$blackList=explode(',',OC_Appconfig::getValue('files_encryption','type_blacklist','jpg,png,jpeg,avi,mpg,mpeg,mkv,mp3,oga,ogv,ogg')); } diff --git a/apps/files_encryption/tests/encryption.php b/apps/files_encryption/tests/encryption.php new file mode 100644 index 00000000000..13093256717 --- /dev/null +++ b/apps/files_encryption/tests/encryption.php @@ -0,0 +1,42 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_Encryption extends UnitTestCase { + function testEncryption(){ + $key=uniqid(); + $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; + $source=file_get_contents($file); //nice large text file + $encrypted=OC_Crypt::encrypt($source,$key); + $decrypted=OC_Crypt::decrypt($encrypted,$key); + $this->assertNotEqual($encrypted,$source); + $this->assertEqual($decrypted,$source); + + $chunk=substr($source,0,8192); + $encrypted=OC_Crypt::encrypt($chunk,$key); + $this->assertEqual(strlen($chunk),strlen($encrypted)); + $decrypted=OC_Crypt::decrypt($encrypted,$key); + $this->assertEqual($decrypted,$chunk); + + $encrypted=OC_Crypt::blockEncrypt($source,$key); + $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); + $this->assertNotEqual($encrypted,$source); + $this->assertEqual($decrypted,$source); + + $tmpFileEncrypted=OC_Helper::tmpFile(); + OC_Crypt::encryptfile($file,$tmpFileEncrypted,$key); + $encrypted=file_get_contents($tmpFileEncrypted); + $decrypted=OC_Crypt::blockDecrypt($encrypted,$key); + $this->assertNotEqual($encrypted,$source); + $this->assertEqual($decrypted,$source); + + $tmpFileDecrypted=OC_Helper::tmpFile(); + OC_Crypt::decryptfile($tmpFileEncrypted,$tmpFileDecrypted,$key); + $decrypted=file_get_contents($tmpFileDecrypted); + $this->assertEqual($decrypted,$source); + } +} diff --git a/apps/files_encryption/tests/stream.php b/apps/files_encryption/tests/stream.php new file mode 100644 index 00000000000..578b091a36c --- /dev/null +++ b/apps/files_encryption/tests/stream.php @@ -0,0 +1,56 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +class Test_CryptStream extends UnitTestCase { + private $tmpFiles=array(); + + function testStream(){ + $stream=$this->getStream('test1','w'); + fwrite($stream,'foobar'); + fclose($stream); + + $stream=$this->getStream('test1','r'); + $data=fread($stream,6); + fclose($stream); + $this->assertEqual('foobar',$data); + + $file=OC::$SERVERROOT.'/3rdparty/MDB2.php'; + $source=fopen($file,'r'); + $target=$this->getStream('test2','w'); + OC_Helper::streamCopy($source,$target); + fclose($target); + fclose($source); + + $stream=$this->getStream('test2','r'); + $data=stream_get_contents($stream); + $original=file_get_contents($file); + $this->assertEqual(strlen($original),strlen($data)); + $this->assertEqual($original,$data); + } + + /** + * get a cryptstream to a temporary file + * @param string $id + * @param string $mode + * @return resource + */ + function getStream($id,$mode){ + if($id===''){ + $id=uniqid(); + } + if(!isset($this->tmpFiles[$id])){ + $file=OC_Helper::tmpFile(); + $this->tmpFiles[$id]=$file; + }else{ + $file=$this->tmpFiles[$id]; + } + $stream=fopen($file,$mode); + OC_CryptStream::$sourceStreams[$id]=array('path'=>'dummy','stream'=>$stream); + return fopen('crypt://streams/'.$id,$mode); + } +} diff --git a/apps/files_external/appinfo/app.php b/apps/files_external/appinfo/app.php index 95770b44b75..784ed032d47 100644 --- a/apps/files_external/appinfo/app.php +++ b/apps/files_external/appinfo/app.php @@ -9,3 +9,4 @@ OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php'; OC::$CLASSPATH['OC_Filestorage_DAV']='apps/files_external/lib/webdav.php'; OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php'; +OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php'; diff --git a/apps/files_external/lib/swift.php b/apps/files_external/lib/swift.php new file mode 100644 index 00000000000..e53eb1ff3b6 --- /dev/null +++ b/apps/files_external/lib/swift.php @@ -0,0 +1,516 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +require_once('php-cloudfiles/cloudfiles.php'); + +class OC_FileStorage_SWIFT extends OC_Filestorage_Common{ + private $host; + private $root; + private $user; + private $token; + private $secure; + /** + * @var CF_Authentication auth + */ + private $auth; + /** + * @var CF_Connection conn + */ + private $conn; + /** + * @var CF_Container rootContainer + */ + private $rootContainer; + + private static $tempFiles=array(); + + const SUBCONTAINER_FILE='.subcontainers'; + + /** + * translate directory path to container name + * @param string path + * @return string + */ + private function getContainerName($path){ + $path=trim($this->root.$path,'/'); + return md5($path); + } + + /** + * get container by path + * @param string path + * @return CF_Container + */ + private function getContainer($path){ + if($path=='' or $path=='/'){ + return $this->rootContainer; + } + try{ + $container=$this->conn->get_container($this->getContainerName($path)); + return $container; + }catch(NoSuchContainerException $e){ + return null; + } + } + + /** + * create container + * @param string path + * @return CF_Container + */ + private function createContainer($path){ + if($path=='' or $path=='/'){ + return $this->conn->create_container($this->getContainerName($path)); + } + $parent=dirname($path); + if($parent=='' or $parent=='/'){ + $parentContainer=$this->rootContainer; + }else{ + if(!$this->containerExists($parent)){ + $parentContainer=$this->createContainer($parent); + }else{ + $parentContainer=$this->getContainer($parent); + } + } + $this->addSubContainer($parentContainer,basename($path)); + return $this->conn->create_container($this->getContainerName($path)); + } + + /** + * get object by path + * @param string path + * @return CF_Object + */ + private function getObject($path){ + $container=$this->getContainer(dirname($path)); + if(is_null($container)){ + return null; + }else{ + try{ + $obj=$container->get_object(basename($path)); + return $obj; + }catch(NoSuchObjectException $e){ + return null; + } + } + } + + /** + * get the names of all objects in a container + * @param CF_Container + * @return array + */ + private function getObjects($container){ + if(is_null($container)){ + return array(); + }else{ + $files=$container->get_objects(); + foreach($files as &$file){ + $file=$file->name; + } + return $files; + } + } + + /** + * create object + * @param string path + * @return CF_Object + */ + private function createObject($path){ + $container=$this->getContainer(dirname($path)); + if(!is_null($container)){ + $container=$this->createContainer($path); + } + return $container->create_object(basename($path)); + } + + /** + * check if an object exists + * @param string + * @return bool + */ + private function objectExists($path){ + return !is_null($this->getObject($path)); + } + + /** + * check if container for path exists + * @param string path + * @return bool + */ + private function containerExists($path){ + return !is_null($this->getContainer($path)); + } + + /** + * get the list of emulated sub containers + * @param CF_Container container + * @return array + */ + private function getSubContainers($container){ + $tmpFile=OC_Helper::tmpFile(); + $obj=$this->getSubContainerFile($container); + try{ + $obj->save_to_filename($tmpFile); + }catch(Exception $e){ + return array(); + } + $obj->save_to_filename($tmpFile); + $containers=file($tmpFile); + unlink($tmpFile); + foreach($containers as &$sub){ + $sub=trim($sub); + } + return $containers; + } + + /** + * add an emulated sub container + * @param CF_Container container + * @param string name + * @return bool + */ + private function addSubContainer($container,$name){ + if(!$name){ + return false; + } + $tmpFile=OC_Helper::tmpFile(); + $obj=$this->getSubContainerFile($container); + try{ + $obj->save_to_filename($tmpFile); + $containers=file($tmpFile); + foreach($containers as &$sub){ + $sub=trim($sub); + } + if(array_search($name,$containers)!==false){ + unlink($tmpFile); + return false; + }else{ + $fh=fopen($tmpFile,'a'); + fwrite($fh,$name."\n"); + } + }catch(Exception $e){ + $containers=array(); + file_put_contents($tmpFile,$name."\n"); + } + + $obj->load_from_filename($tmpFile); + unlink($tmpFile); + return true; + } + + /** + * remove an emulated sub container + * @param CF_Container container + * @param string name + * @return bool + */ + private function removeSubContainer($container,$name){ + if(!$name){ + return false; + } + $tmpFile=OC_Helper::tmpFile(); + $obj=$this->getSubContainerFile($container); + try{ + $obj->save_to_filename($tmpFile); + $containers=file($tmpFile); + }catch(Exception $e){ + return false; + } + foreach($containers as &$sub){ + $sub=trim($sub); + } + $i=array_search($name,$containers); + if($i===false){ + unlink($tmpFile); + return false; + }else{ + unset($containers[$i]); + file_put_contents($tmpFile,implode("\n",$containers)."\n"); + } + + $obj->load_from_filename($tmpFile); + unlink($tmpFile); + return true; + } + + /** + * ensure a subcontainer file exists and return it's object + * @param CF_Container container + * @return CF_Object + */ + private function getSubContainerFile($container){ + try{ + return $container->get_object(self::SUBCONTAINER_FILE); + }catch(NoSuchObjectException $e){ + return $container->create_object(self::SUBCONTAINER_FILE); + } + } + + public function __construct($params){ + $this->token=$params['token']; + $this->host=$params['host']; + $this->user=$params['user']; + $this->root=isset($params['root'])?$params['root']:'/'; + $this->secure=isset($params['secure'])?(bool)$params['secure']:true; + if(substr($this->root,0,1)!='/'){ + $this->root='/'.$this->root; + } + $this->auth = new CF_Authentication($this->user, $this->token, null, $this->host); + $this->auth->authenticate(); + + $this->conn = new CF_Connection($this->auth); + + if(!$this->containerExists($this->root)){ + $this->rootContainer=$this->createContainer('/'); + }else{ + $this->rootContainer=$this->getContainer('/'); + } + } + + + public function mkdir($path){ + if($this->containerExists($path)){ + return false; + }else{ + $this->createContainer($path); + return true; + } + } + + public function rmdir($path){ + if(!$this->containerExists($path)){ + return false; + }else{ + $this->emptyContainer($path); + if($path!='' and $path!='/'){ + $parentContainer=$this->getContainer(dirname($path)); + $this->removeSubContainer($parentContainer,basename($path)); + } + + $this->conn->delete_container($this->getContainerName($path)); + return true; + } + } + + private function emptyContainer($path){ + $container=$this->getContainer($path); + if(is_null($container)){ + return; + } + $subContainers=$this->getSubContainers($container); + foreach($subContainers as $sub){ + if($sub){ + $this->emptyContainer($path.'/'.$sub); + $this->conn->delete_container($this->getContainerName($path.'/'.$sub)); + } + } + + $objects=$this->getObjects($container); + foreach($objects as $object){ + $container->delete_object($object); + } + } + + public function opendir($path){ + $container=$this->getContainer($path); + $files=$this->getObjects($container); + $i=array_search(self::SUBCONTAINER_FILE,$files); + if($i!==false){ + unset($files[$i]); + } + $subContainers=$this->getSubContainers($container); + $files=array_merge($files,$subContainers); + $id=$this->getContainerName($path); + OC_FakeDirStream::$dirs[$id]=$files; + return opendir('fakedir://'.$id); + } + + public function filetype($path){ + if($this->containerExists($path)){ + return 'dir'; + }else{ + return 'file'; + } + } + + public function is_readable($path){ + return true; + } + + public function is_writable($path){ + return true; + } + + public function file_exists($path){ + if($this->is_dir($path)){ + return true; + }else{ + return $this->objectExists($path); + } + } + + public function file_get_contents($path){ + $obj=$this->getObject($path); + if(is_null($obj)){ + return false; + } + return $obj->read(); + } + + public function file_put_contents($path,$content){ + $obj=$this->getObject($path); + if(is_null($obj)){ + $container=$this->getContainer(dirname($path)); + if(is_null($container)){ + return false; + } + $obj=$container->create_object(basename($path)); + } + $this->resetMTime($obj); + return $obj->write($content); + } + + public function unlink($path){ + if($this->objectExists($path)){ + $container=$this->getContainer(dirname($path)); + $container->delete_object(basename($path)); + }else{ + return false; + } + } + + public function fopen($path,$mode){ + $obj=$this->getObject($path); + if(is_null($obj)){ + return false; + } + switch($mode){ + case 'r': + case 'rb': + $fp = fopen('php://temp', 'r+'); + $obj->stream($fp); + + rewind($fp); + return $fp; + case 'w': + case 'wb': + case 'a': + case 'ab': + case 'r+': + case 'w+': + case 'wb+': + case 'a+': + case 'x': + case 'x+': + case 'c': + case 'c+': + $tmpFile=$this->getTmpFile($path); + OC_CloseStreamWrapper::$callBacks[$tmpFile]=array($this,'writeBack'); + self::$tempFiles[$tmpFile]=$path; + return fopen('close://'.$tmpFile,$mode); + } + } + + public function writeBack($tmpFile){ + if(isset(self::$tempFiles[$tmpFile])){ + $this->fromTmpFile($tmpFile,self::$tempFiles[$tmpFile]); + unlink($tmpFile); + } + } + + public function free_space($path){ + return 0; + } + + public function touch($path,$mtime=null){ + $obj=$this->getObject($path); + if(is_null($obj)){ + return false; + } + if(is_null($mtime)){ + $mtime=time(); + } + + //emulate setting mtime with metadata + $obj->metadata['Mtime']=$mtime; + $obj->sync_metadata(); + } + + public function rename($path1,$path2){ + $sourceContainer=$this->getContainer(dirname($path1)); + $targetContainer=$this->getContainer(dirname($path2)); + $result=$sourceContainer->move_object_to(basename($path1),$targetContainer,basename($path2)); + if($result){ + $targetObj=$this->getObject($path2); + $this->resetMTime($targetObj); + } + return $result; + } + + public function copy($path1,$path2){ + $sourceContainer=$this->getContainer(dirname($path1)); + $targetContainer=$this->getContainer(dirname($path2)); + $result=$sourceContainer->copy_object_to(basename($path1),$targetContainer,basename($path2)); + if($result){ + $targetObj=$this->getObject($path2); + $this->resetMTime($targetObj); + } + return $result; + } + + public function stat($path){ + $obj=$this->getObject($path); + if(is_null($obj)){ + return false; + } + + if(isset($obj->metadata['Mtime']) and $obj->metadata['Mtime']>-1){ + $mtime=$obj->metadata['Mtime']; + }else{ + $mtime=strtotime($obj->last_modified); + } + return array( + 'mtime'=>$mtime, + 'size'=>$obj->content_length, + 'ctime'=>-1, + ); + } + + private function getTmpFile($path){ + $obj=$this->getObject($path); + if(!is_null($obj)){ + $tmpFile=OC_Helper::tmpFile(); + $obj->save_to_filename($tmpFile); + return $tmpFile; + }else{ + return false; + } + } + + private function fromTmpFile($tmpFile,$path){ + $obj=$this->getObject($path); + if(is_null($obj)){ + $obj=$this->createObject($path); + } + $obj->load_from_filename($tmpFile); + $this->resetMTime($obj); + } + + /** + * remove custom mtime metadata + * @param CF_Object obj + */ + private function resetMTime($obj){ + if(isset($obj->metadata['Mtime'])){ + $obj->metadata['Mtime']=-1; + $obj->sync_metadata(); + } + } +} diff --git a/apps/files_external/tests/config.php b/apps/files_external/tests/config.php index fa4c74a6e26..edbbe9dfec8 100644 --- a/apps/files_external/tests/config.php +++ b/apps/files_external/tests/config.php @@ -21,5 +21,12 @@ return array( 'token'=>'test', 'token_secret'=>'test', 'root'=>'/google', - ) + ), + 'swift'=>array( + 'run'=>true, + 'user'=>'test:tester', + 'token'=>'testing', + 'host'=>'localhost:8080/auth', + 'root'=>'/', + ), ); diff --git a/apps/files_external/tests/swift.php b/apps/files_external/tests/swift.php new file mode 100644 index 00000000000..f0bde6ed605 --- /dev/null +++ b/apps/files_external/tests/swift.php @@ -0,0 +1,32 @@ +<?php +/** + * Copyright (c) 2012 Robin Appelman <icewind@owncloud.com> + * This file is licensed under the Affero General Public License version 3 or + * later. + * See the COPYING-README file. + */ + +$config=include('apps/files_external/tests/config.php'); +if(!is_array($config) or !isset($config['swift']) or !$config['swift']['run']){ + abstract class Test_Filestorage_SWIFT extends Test_FileStorage{} + return; +}else{ + class Test_Filestorage_SWIFT extends Test_FileStorage { + private $config; + private $id; + + public function setUp(){ + $id=uniqid(); + $this->config=include('apps/files_external/tests/config.php'); + $this->config['swift']['root'].='/'.$id;//make sure we have an new empty folder to work in + $this->instance=new OC_Filestorage_SWIFT($this->config['swift']); + } + + + public function tearDown(){ + $this->instance->rmdir(''); + } + + } +} + |