Merge branch 'master' into calendar_repeat

This commit is contained in:
Georg Ehrke 2012-05-25 10:30:00 +02:00
commit bc9accd26e
87 changed files with 1445 additions and 365 deletions

439
3rdparty/smb4php/smb.php vendored Normal file
View file

@ -0,0 +1,439 @@
<?php
###################################################################
# smb.php
# This class implements a SMB stream wrapper based on 'smbclient'
#
# Date: lun oct 22 10:35:35 CEST 2007
#
# Homepage: http://www.phpclasses.org/smb4php
#
# Copyright (c) 2007 Victor M. Varela <vmvarela@gmail.com>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program 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 General Public License for more details.
#
###################################################################
define ('SMB4PHP_VERSION', '0.8');
###################################################################
# CONFIGURATION SECTION - Change for your needs
###################################################################
define ('SMB4PHP_SMBCLIENT', 'smbclient');
define ('SMB4PHP_SMBOPTIONS', 'TCP_NODELAY IPTOS_LOWDELAY SO_KEEPALIVE SO_RCVBUF=8192 SO_SNDBUF=8192');
define ('SMB4PHP_AUTHMODE', 'arg'); # set to 'env' to use USER enviroment variable
###################################################################
# SMB - commands that does not need an instance
###################################################################
$GLOBALS['__smb_cache'] = array ('stat' => array (), 'dir' => array ());
class smb {
function parse_url ($url) {
$pu = parse_url (trim($url));
foreach (array ('domain', 'user', 'pass', 'host', 'port', 'path') as $i)
if (! isset($pu[$i])) $pu[$i] = '';
if (count ($userdomain = explode (';', urldecode ($pu['user']))) > 1)
@list ($pu['domain'], $pu['user']) = $userdomain;
$path = preg_replace (array ('/^\//', '/\/$/'), '', urldecode ($pu['path']));
list ($pu['share'], $pu['path']) = (preg_match ('/^([^\/]+)\/(.*)/', $path, $regs))
? array ($regs[1], preg_replace ('/\//', '\\', $regs[2]))
: array ($path, '');
$pu['type'] = $pu['path'] ? 'path' : ($pu['share'] ? 'share' : ($pu['host'] ? 'host' : '**error**'));
if (! ($pu['port'] = intval(@$pu['port']))) $pu['port'] = 139;
return $pu;
}
function look ($purl) {
return smb::client ('-L ' . escapeshellarg ($purl['host']), $purl);
}
function execute ($command, $purl) {
return smb::client ('-d 0 '
. escapeshellarg ('//' . $purl['host'] . '/' . $purl['share'])
. ' -c ' . escapeshellarg ($command), $purl
);
}
function client ($params, $purl) {
static $regexp = array (
'^added interface ip=(.*) bcast=(.*) nmask=(.*)$' => 'skip',
'Anonymous login successful' => 'skip',
'^Domain=\[(.*)\] OS=\[(.*)\] Server=\[(.*)\]$' => 'skip',
'^\tSharename[ ]+Type[ ]+Comment$' => 'shares',
'^\t---------[ ]+----[ ]+-------$' => 'skip',
'^\tServer [ ]+Comment$' => 'servers',
'^\t---------[ ]+-------$' => 'skip',
'^\tWorkgroup[ ]+Master$' => 'workg',
'^\t(.*)[ ]+(Disk|IPC)[ ]+IPC.*$' => 'skip',
'^\tIPC\\\$(.*)[ ]+IPC' => 'skip',
'^\t(.*)[ ]+(Disk)[ ]+(.*)$' => 'share',
'^\t(.*)[ ]+(Printer)[ ]+(.*)$' => 'skip',
'([0-9]+) blocks of size ([0-9]+)\. ([0-9]+) blocks available' => 'skip',
'Got a positive name query response from ' => 'skip',
'^(session setup failed): (.*)$' => 'error',
'^(.*): ERRSRV - ERRbadpw' => 'error',
'^Error returning browse list: (.*)$' => 'error',
'^tree connect failed: (.*)$' => 'error',
'^(Connection to .* failed)$' => 'error',
'^NT_STATUS_(.*) ' => 'error',
'^NT_STATUS_(.*)\$' => 'error',
'ERRDOS - ERRbadpath \((.*).\)' => 'error',
'cd (.*): (.*)$' => 'error',
'^cd (.*): NT_STATUS_(.*)' => 'error',
'^\t(.*)$' => 'srvorwg',
'^([0-9]+)[ ]+([0-9]+)[ ]+(.*)$' => 'skip',
'^Job ([0-9]+) cancelled' => 'skip',
'^[ ]+(.*)[ ]+([0-9]+)[ ]+(Mon|Tue|Wed|Thu|Fri|Sat|Sun)[ ](Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)[ ]+([0-9]+)[ ]+([0-9]{2}:[0-9]{2}:[0-9]{2})[ ]([0-9]{4})$' => 'files',
'^message start: ERRSRV - (ERRmsgoff)' => 'error'
);
if (SMB4PHP_AUTHMODE == 'env') {
putenv("USER={$purl['user']}%{$purl['pass']}");
$auth = '';
} else {
$auth = ($purl['user'] <> '' ? (' -U ' . escapeshellarg ($purl['user'] . '%' . $purl['pass'])) : '');
}
if ($purl['domain'] <> '') {
$auth .= ' -W ' . escapeshellarg ($purl['domain']);
}
$port = ($purl['port'] <> 139 ? ' -p ' . escapeshellarg ($purl['port']) : '');
$options = '-O ' . escapeshellarg(SMB4PHP_SMBOPTIONS);
$output = popen (SMB4PHP_SMBCLIENT." -N {$auth} {$options} {$port} {$options} {$params} 2>/dev/null", 'r');
$info = array ();
$info['info']= array ();
while ($line = fgets ($output, 4096)) {
list ($tag, $regs, $i) = array ('skip', array (), array ());
reset ($regexp);
foreach ($regexp as $r => $t) if (preg_match ('/'.$r.'/', $line, $regs)) {
$tag = $t;
break;
}
switch ($tag) {
case 'skip': continue;
case 'shares': $mode = 'shares'; break;
case 'servers': $mode = 'servers'; break;
case 'workg': $mode = 'workgroups'; break;
case 'share':
list($name, $type) = array (
trim(substr($line, 1, 15)),
trim(strtolower(substr($line, 17, 10)))
);
$i = ($type <> 'disk' && preg_match('/^(.*) Disk/', $line, $regs))
? array(trim($regs[1]), 'disk')
: array($name, 'disk');
break;
case 'srvorwg':
list ($name, $master) = array (
strtolower(trim(substr($line,1,21))),
strtolower(trim(substr($line, 22)))
);
$i = ($mode == 'servers') ? array ($name, "server") : array ($name, "workgroup", $master);
break;
case 'files':
list ($attr, $name) = preg_match ("/^(.*)[ ]+([D|A|H|S|R]+)$/", trim ($regs[1]), $regs2)
? array (trim ($regs2[2]), trim ($regs2[1]))
: array ('', trim ($regs[1]));
list ($his, $im) = array (
explode(':', $regs[6]), 1 + strpos("JanFebMarAprMayJunJulAugSepOctNovDec", $regs[4]) / 3);
$i = ($name <> '.' && $name <> '..')
? array (
$name,
(strpos($attr,'D') === FALSE) ? 'file' : 'folder',
'attr' => $attr,
'size' => intval($regs[2]),
'time' => mktime ($his[0], $his[1], $his[2], $im, $regs[5], $regs[7])
)
: array();
break;
case 'error':
if(substr($regs[0],0,22)=='NT_STATUS_NO_SUCH_FILE'){
return false;
}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_NAME_COLLISION'){
return false;
}elseif(substr($regs[0],0,31)=='NT_STATUS_OBJECT_PATH_NOT_FOUND'){
return false;
}
trigger_error($regs[0].' params('.$params.')', E_USER_ERROR);
}
if ($i) switch ($i[1]) {
case 'file':
case 'folder': $info['info'][$i[0]] = $i;
case 'disk':
case 'server':
case 'workgroup': $info[$i[1]][] = $i[0];
}
}
pclose($output);
return $info;
}
# stats
function url_stat ($url, $flags = STREAM_URL_STAT_LINK) {
if ($s = smb::getstatcache($url)) { return $s; }
list ($stat, $pu) = array (array (), smb::parse_url ($url));
switch ($pu['type']) {
case 'host':
if ($o = smb::look ($pu))
$stat = stat ("/tmp");
else
trigger_error ("url_stat(): list failed for host '{$host}'", E_USER_WARNING);
break;
case 'share':
if ($o = smb::look ($pu)) {
$found = FALSE;
$lshare = strtolower ($pu['share']); # fix by Eric Leung
foreach ($o['disk'] as $s) if ($lshare == strtolower($s)) {
$found = TRUE;
$stat = stat ("/tmp");
break;
}
if (! $found)
trigger_error ("url_stat(): disk resource '{$share}' not found in '{$host}'", E_USER_WARNING);
}
break;
case 'path':
if ($o = smb::execute ('dir "'.$pu['path'].'"', $pu)) {
$p = explode('\\', $pu['path']);
$name = $p[count($p)-1];
if (isset ($o['info'][$name])) {
$stat = smb::addstatcache ($url, $o['info'][$name]);
} else {
trigger_error ("url_stat(): path '{$pu['path']}' not found", E_USER_WARNING);
}
} else {
return false;
// trigger_error ("url_stat(): dir failed for path '{$pu['path']}'", E_USER_WARNING);
}
break;
default: trigger_error ('error in URL', E_USER_ERROR);
}
return $stat;
}
function addstatcache ($url, $info) {
global $__smb_cache;
$is_file = (strpos ($info['attr'],'D') === FALSE);
$s = ($is_file) ? stat ('/etc/passwd') : stat ('/tmp');
$s[7] = $s['size'] = $info['size'];
$s[8] = $s[9] = $s[10] = $s['atime'] = $s['mtime'] = $s['ctime'] = $info['time'];
return $__smb_cache['stat'][$url] = $s;
}
function getstatcache ($url) {
global $__smb_cache;
return isset ($__smb_cache['stat'][$url]) ? $__smb_cache['stat'][$url] : FALSE;
}
function clearstatcache ($url='') {
global $__smb_cache;
if ($url == '') $__smb_cache['stat'] = array (); else unset ($__smb_cache['stat'][$url]);
}
# commands
function unlink ($url) {
$pu = smb::parse_url($url);
if ($pu['type'] <> 'path') trigger_error('unlink(): error in URL', E_USER_ERROR);
smb::clearstatcache ($url);
smb_stream_wrapper::cleardircache (dirname($url));
return smb::execute ('del "'.$pu['path'].'"', $pu);
}
function rename ($url_from, $url_to) {
list ($from, $to) = array (smb::parse_url($url_from), smb::parse_url($url_to));
if ($from['host'] <> $to['host'] ||
$from['share'] <> $to['share'] ||
$from['user'] <> $to['user'] ||
$from['pass'] <> $to['pass'] ||
$from['domain'] <> $to['domain']) {
trigger_error('rename(): FROM & TO must be in same server-share-user-pass-domain', E_USER_ERROR);
}
if ($from['type'] <> 'path' || $to['type'] <> 'path') {
trigger_error('rename(): error in URL', E_USER_ERROR);
}
smb::clearstatcache ($url_from);
return smb::execute ('rename "'.$from['path'].'" "'.$to['path'].'"', $to);
}
function mkdir ($url, $mode, $options) {
$pu = smb::parse_url($url);
if ($pu['type'] <> 'path') trigger_error('mkdir(): error in URL', E_USER_ERROR);
return smb::execute ('mkdir "'.$pu['path'].'"', $pu)!==false;
}
function rmdir ($url) {
$pu = smb::parse_url($url);
if ($pu['type'] <> 'path') trigger_error('rmdir(): error in URL', E_USER_ERROR);
smb::clearstatcache ($url);
smb_stream_wrapper::cleardircache (dirname($url));
return smb::execute ('rmdir "'.$pu['path'].'"', $pu)!==false;
}
}
###################################################################
# SMB_STREAM_WRAPPER - class to be registered for smb:// URLs
###################################################################
class smb_stream_wrapper extends smb {
# variables
private $stream, $url, $parsed_url = array (), $mode, $tmpfile;
private $need_flush = FALSE;
private $dir = array (), $dir_index = -1;
# directories
function dir_opendir ($url, $options) {
if ($d = $this->getdircache ($url)) {
$this->dir = $d;
$this->dir_index = 0;
return TRUE;
}
$pu = smb::parse_url ($url);
switch ($pu['type']) {
case 'host':
if ($o = smb::look ($pu)) {
$this->dir = $o['disk'];
$this->dir_index = 0;
} else {
trigger_error ("dir_opendir(): list failed for host '{$pu['host']}'", E_USER_WARNING);
return false;
}
break;
case 'share':
case 'path':
if (is_array($o = smb::execute ('dir "'.$pu['path'].'\*"', $pu))) {
$this->dir = array_keys($o['info']);
$this->dir_index = 0;
$this->adddircache ($url, $this->dir);
foreach ($o['info'] as $name => $info) {
smb::addstatcache($url . '/' . urlencode($name), $info);
}
} else {
trigger_error ("dir_opendir(): dir failed for path '".$pu['path']."'", E_USER_WARNING);
return false;
}
break;
default:
trigger_error ('dir_opendir(): error in URL', E_USER_ERROR);
return false;
}
return TRUE;
}
function dir_readdir () {
return ($this->dir_index < count($this->dir)) ? $this->dir[$this->dir_index++] : FALSE;
}
function dir_rewinddir () { $this->dir_index = 0; }
function dir_closedir () { $this->dir = array(); $this->dir_index = -1; return TRUE; }
# cache
function adddircache ($url, $content) {
global $__smb_cache;
return $__smb_cache['dir'][$url] = $content;
}
function getdircache ($url) {
global $__smb_cache;
return isset ($__smb_cache['dir'][$url]) ? $__smb_cache['dir'][$url] : FALSE;
}
function cleardircache ($url='') {
global $__smb_cache;
if ($url == ''){
$__smb_cache['dir'] = array ();
}else{
unset ($__smb_cache['dir'][$url]);
}
}
# streams
function stream_open ($url, $mode, $options, $opened_path) {
$this->url = $url;
$this->mode = $mode;
$this->parsed_url = $pu = smb::parse_url($url);
if ($pu['type'] <> 'path') trigger_error('stream_open(): error in URL', E_USER_ERROR);
switch ($mode) {
case 'r':
case 'r+':
case 'rb':
case 'a':
case 'a+': $this->tmpfile = tempnam('/tmp', 'smb.down.');
smb::execute ('get "'.$pu['path'].'" "'.$this->tmpfile.'"', $pu);
break;
case 'w':
case 'w+':
case 'wb':
case 'x':
case 'x+': $this->cleardircache();
$this->tmpfile = tempnam('/tmp', 'smb.up.');
$this->need_flush=true;
}
$this->stream = fopen ($this->tmpfile, $mode);
return TRUE;
}
function stream_close () { return fclose($this->stream); }
function stream_read ($count) { return fread($this->stream, $count); }
function stream_write ($data) { $this->need_flush = TRUE; return fwrite($this->stream, $data); }
function stream_eof () { return feof($this->stream); }
function stream_tell () { return ftell($this->stream); }
function stream_seek ($offset, $whence=null) { return fseek($this->stream, $offset, $whence); }
function stream_flush () {
if ($this->mode <> 'r' && $this->need_flush) {
smb::clearstatcache ($this->url);
smb::execute ('put "'.$this->tmpfile.'" "'.$this->parsed_url['path'].'"', $this->parsed_url);
$this->need_flush = FALSE;
}
}
function stream_stat () { return smb::url_stat ($this->url); }
function __destruct () {
if ($this->tmpfile <> '') {
if ($this->need_flush) $this->stream_flush ();
unlink ($this->tmpfile);
}
}
}
###################################################################
# Register 'smb' protocol !
###################################################################
stream_wrapper_register('smb', 'smb_stream_wrapper')
or die ('Failed to register protocol');

View file

@ -1,9 +1,10 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>admin_dependencies_chk</id> <id>admin_dependencies_chk</id>
<name>Owncloud dependencies info</name> <name>ownCloud dependencies info</name>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Brice Maron (eMerzh)</author> <author>Brice Maron (eMerzh)</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<description>Display OwnCloud's dependencies informations (missings modules, ...)</description> <description>Display OwnCloud's dependencies informations (missings modules, ...)</description>
</info> </info>

View file

@ -5,6 +5,7 @@
<description>Import/Export your owncloud instance</description> <description>Import/Export your owncloud instance</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Thomas Schmidt and Tom Needham</author> <author>Thomas Schmidt and Tom Needham</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
</info> </info>

View file

@ -6,5 +6,6 @@
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Arthur Schiwon, Marvin Thomas Rabe</author> <author>Arthur Schiwon, Marvin Thomas Rabe</author>
<standalone/> <standalone/>
<require>2</require> <require>4</require>
<shipped>true</shipped>
</info> </info>

View file

@ -0,0 +1,74 @@
<?php
$data = $_POST['data'];
$data = explode(',', $data);
$data = end($data);
$data = base64_decode($data);
OCP\JSON::checkLoggedIn();
OCP\App::checkAppEnabled('calendar');
$nl="\r\n";
$comps = array('VEVENT'=>true, 'VTODO'=>true, 'VJOURNAL'=>true);
$data = str_replace(array("\r","\n\n"), array("\n","\n"), $data);
$lines = explode("\n", $data);
unset($data);
$comp=$uid=$cal=false;
$cals=$uids=array();
$i = 0;
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();
}
$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++;
}
$calendars = OC_Calendar_Calendar::allCalendars(OCP\USER::getUser(), 1);
$id = $calendars[0]['id'];
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));
}
if(count($content)) {
$import = join($nl, array_merge($prefix, $content, $suffix)) . $nl;
OC_Calendar_Object::add($id, $import);
}
}
OCP\JSON::success();
?>

View file

@ -5,8 +5,7 @@
* later. * later.
* See the COPYING-README file. * See the COPYING-README file.
*/ */
require_once('../../../../lib/base.php');
$id = strip_tags($_GET['id']); $id = strip_tags($_GET['id']);
$activation = strip_tags($_GET['activation']); $activation = strip_tags($_GET['activation']);
OC_Calendar_Share::set_active(OCP\USER::getUser(), $id, $activation); OC_Calendar_Share::set_active(OCP\USER::getUser(), $id, $activation);
OCP\JSON::success(); OCP\JSON::success();

View file

@ -4,7 +4,8 @@
<name>Calendar</name> <name>Calendar</name>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Georg Ehrke, Bart Visscher, Jakob Sack</author> <author>Georg Ehrke, Bart Visscher, Jakob Sack</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<description>Calendar with CalDAV support</description> <description>Calendar with CalDAV support</description>
<default_enable/> <default_enable/>
<remote> <remote>

View file

@ -602,6 +602,50 @@ Calendar={
}); });
/*var permissions = (this.checked) ? 1 : 0;*/ /*var permissions = (this.checked) ? 1 : 0;*/
} }
},
Drop:{
init:function(){
if (typeof window.FileReader === 'undefined') {
console.log('The drop-import feature is not supported in your browser :(');
return false;
}
droparea = document.getElementById('calendar_holder');
droparea.ondrop = function(e){
e.preventDefault();
Calendar.UI.Drop.drop(e);
}
console.log('Drop initialized successfully');
},
drop:function(e){
var files = e.dataTransfer.files;
for(var i = 0;i < files.length;i++){
var file = files[i]
reader = new FileReader();
reader.onload = function(event){
if(file.type != 'text/calendar'){
$('#notification').html('At least one file don\'t seems to be a calendar file. File skipped.');
$('#notification').slideDown();
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
return false;
}else{
Calendar.UI.Drop.import(event.target.result);
$('#calendar_holder').fullCalendar('refetchEvents');
}
}
reader.readAsDataURL(file);
}
},
import:function(data){
$.post(OC.filePath('calendar', 'ajax/import', 'dropimport.php'), {'data':data},function(result) {
if(result.status == 'success'){
return true;
}else{
$('#notification').html('ownCloud wasn\'t able to import at least one file. File skipped.');
$('#notification').slideDown();
window.setTimeout(function(){$('#notification').slideUp();}, 5000);
}
});
}
} }
} }
} }
@ -859,4 +903,5 @@ $(document).ready(function(){
$('#calendar_holder').fullCalendar('next'); $('#calendar_holder').fullCalendar('next');
}); });
Calendar.UI.Share.init(); Calendar.UI.Share.init();
Calendar.UI.Drop.init();
}); });

View file

@ -19,9 +19,6 @@
* License along with this library. If not, see <http://www.gnu.org/licenses/>. * License along with this library. If not, see <http://www.gnu.org/licenses/>.
* *
*/ */
// Init owncloud
require_once('lib/base.php');
// Check if we are a user // Check if we are a user
// Firefox and Konqueror tries to download application/json for me. --Arthur // Firefox and Konqueror tries to download application/json for me. --Arthur
OCP\JSON::setContentTypeHeader('text/plain'); OCP\JSON::setContentTypeHeader('text/plain');

View file

@ -32,7 +32,7 @@ function debug($msg) {
OCP\Util::writeLog('contacts','ajax/uploadimport.php: '.$msg, OCP\Util::DEBUG); OCP\Util::writeLog('contacts','ajax/uploadimport.php: '.$msg, OCP\Util::DEBUG);
} }
$view = OCP\App::getStorage('contacts'); $view = OCP\Files::getStorage('contacts');
$tmpfile = md5(rand()); $tmpfile = md5(rand());
// If it is a Drag'n'Drop transfer it's handled here. // If it is a Drag'n'Drop transfer it's handled here.

View file

@ -4,7 +4,8 @@
<name>Contacts</name> <name>Contacts</name>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Jakob Sack</author> <author>Jakob Sack</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<description>Address book with CardDAV support.</description> <description>Address book with CardDAV support.</description>
<standalone/> <standalone/>
<default_enable/> <default_enable/>

View file

@ -91,7 +91,7 @@ dl.addresscard .action { float: right; }
#file_upload_form { width: 0; height: 0; } #file_upload_form { width: 0; height: 0; }
#file_upload_target, #import_upload_target, #crop_target { display:none; } #file_upload_target, #import_upload_target, #crop_target { display:none; }
#file_upload_start, #import_upload_start { opacity:0; filter:alpha(opacity=0); z-index:1001; /*position:absolute; left:0; top:0;*/ width:0; height:0;} #file_upload_start, #import_upload_start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1001; width:0; height:0;}
#import_upload_start { width: 16px; height: 16px; margin: 0 0 0 0; } #import_upload_start { width: 16px; height: 16px; margin: 0 0 0 0; }
input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; } input[type="checkbox"] { width: 20px; height: 20px; vertical-align: bottom; }
.big { font-weight:bold; font-size:1.2em; } .big { font-weight:bold; font-size:1.2em; }

View file

@ -23,7 +23,7 @@ function writeProgress($pct) {
writeProgress('10'); writeProgress('10');
$view = $file = null; $view = $file = null;
if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') { if(isset($_POST['fstype']) && $_POST['fstype'] == 'OC_FilesystemView') {
$view = OCP\App::getStorage('contacts'); $view = OCP\Files::getStorage('contacts');
$file = $view->file_get_contents('/' . $_POST['file']); $file = $view->file_get_contents('/' . $_POST['file']);
} else { } else {
$file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']); $file = OC_Filesystem::file_get_contents($_POST['path'] . '/' . $_POST['file']);

View file

@ -188,6 +188,9 @@ class OC_Contacts_VCard{
if($upgrade && in_array($property->name, $stringprops)) { if($upgrade && in_array($property->name, $stringprops)) {
self::decodeProperty($property); self::decodeProperty($property);
} }
if(in_array($property->name, $stringprops)) {
$property->value = strip_tags($property->value);
}
// Fix format of type parameters. // Fix format of type parameters.
if($upgrade && in_array($property->name, $typeprops)) { if($upgrade && in_array($property->name, $typeprops)) {
OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. before: '.$property->serialize(),OCP\Util::DEBUG); OCP\Util::writeLog('contacts','OC_Contacts_VCard::updateValuesFromAdd. before: '.$property->serialize(),OCP\Util::DEBUG);

View file

@ -5,5 +5,6 @@
<description>Show external Application in the ownCloud menu</description> <description>Show external Application in the ownCloud menu</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Frank Karlitschek</author> <author>Frank Karlitschek</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
</info> </info>

View file

@ -33,5 +33,5 @@ OCP\User::checkLoggedIn();
$files = $_GET["files"]; $files = $_GET["files"];
$dir = $_GET["dir"]; $dir = $_GET["dir"];
OC_Files::get($dir,$files); OC_Files::get($dir, $files, $_SERVER['REQUEST_METHOD'] == 'HEAD' ? true : false);
?> ?>

View file

@ -5,7 +5,8 @@
<description>File Management</description> <description>File Management</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<standalone/> <standalone/>
<default_enable/> <default_enable/>
<types> <types>

View file

@ -28,7 +28,7 @@
.file_upload_start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1; position:absolute; left:0; top:0; width:100%; cursor:pointer;} .file_upload_start { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; z-index:1; position:absolute; left:0; top:0; width:100%; cursor:pointer;}
.file_upload_filename.active { border-bottom-right-radius:0 } .file_upload_filename.active { border-bottom-right-radius:0 }
.file_upload_filename { position: relative; z-index:100; padding-left: 0.8em; padding-right: 0.8em; cursor:pointer; border-top-left-radius:0; border-bottom-left-radius:0; } .file_upload_filename { z-index:100; padding-left: 0.8em; padding-right: 0.8em; cursor:pointer; border-top-left-radius:0; border-bottom-left-radius:0; }
.file_upload_filename img { position: absolute; top: 0.4em; left: 0.4em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; } .file_upload_filename img { position: absolute; top: 0.4em; left: 0.4em; -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
#upload { position:absolute; right:13.5em; top:0em; } #upload { position:absolute; right:13.5em; top:0em; }
@ -72,7 +72,7 @@ table thead.fixed { height:2em; }
#fileList tr td.filename>input[type=checkbox]:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 200ms; -moz-transition:opacity 200ms; -o-transition:opacity 200ms; transition:opacity 200ms; } #fileList tr td.filename>input[type=checkbox]:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=0)"; filter:alpha(opacity=0); opacity:0; float:left; margin:.7em 0 0 1em; /* bigger clickable area doesnt work in FF width:2.8em; height:2.4em;*/ -webkit-transition:opacity 200ms; -moz-transition:opacity 200ms; -o-transition:opacity 200ms; transition:opacity 200ms; }
#fileList tr td.filename>input[type="checkbox"]:hover:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; filter:alpha(opacity=80); opacity:.8; } #fileList tr td.filename>input[type="checkbox"]:hover:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=80)"; filter:alpha(opacity=80); opacity:.8; }
#fileList tr td.filename>input[type="checkbox"]:checked:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; } #fileList tr td.filename>input[type="checkbox"]:checked:first-child { -ms-filter:"progid:DXImageTransform.Microsoft.Alpha(Opacity=100)"; filter:alpha(opacity=100); opacity:1; }
#fileList tr td.filename { -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; } #fileList tr td.filename { -webkit-transition:background-image 500ms; -moz-transition:background-image 500ms; -o-transition:background-image 500ms; transition:background-image 500ms; position:relative; }
#select_all { float:left; margin:.3em 0.6em 0 .5em; } #select_all { float:left; margin:.3em 0.6em 0 .5em; }
#uploadsize-message,#delete-confirm { display:none; } #uploadsize-message,#delete-confirm { display:none; }
.fileactions { position:relative; top:.3em; font-size:.8em; float:right; } .fileactions { position:relative; top:.3em; font-size:.8em; float:right; }

View file

@ -194,6 +194,11 @@ $(document).ready(function() {
var totalSize=0; var totalSize=0;
if(files){ if(files){
for(var i=0;i<files.length;i++){ for(var i=0;i<files.length;i++){
if(files[i].size ==0 && files[i].type== '')
{
OC.dialogs.alert(t('files', 'Unable to upload your file as it is a directory or has 0 bytes'), t('files', 'Upload Error'));
return;
}
totalSize+=files[i].size; totalSize+=files[i].size;
if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file if(FileList.deleteFiles && FileList.deleteFiles.indexOf(files[i].name)!=-1){//finish delete if we are uploading a deleted file
FileList.finishDelete(function(){ FileList.finishDelete(function(){
@ -213,115 +218,6 @@ $(document).ready(function() {
} }
}); });
}else{ }else{
if($.support.xhrFileUpload) {
for(var i=0;i<files.length;i++){
var fileName = files[i].name
var dropTarget = $(e.originalEvent.target).closest('tr');
if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
var dirName = dropTarget.attr('data-file')
var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
formData: function(form) {
var formArray = form.serializeArray();
formArray[1]['value'] = dirName;
return formArray;
}}).success(function(result, textStatus, jqXHR) {
var response;
response=jQuery.parseJSON(result);
if(response[0] == undefined || response[0].status != 'success') {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
}
var file=response[0];
delete uploadingFiles[dirName][file.name];
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
currentUploads -= 1;
uploadtext.attr('currentUploads', currentUploads);
if(currentUploads === 0) {
var img = OC.imagePath('core', 'filetypes/folder.png');
var tr=$('tr').filterAttr('data-file',dirName);
tr.find('td.filename').attr('style','background-image:url('+img+')');
uploadtext.text('');
uploadtext.hide();
} else {
uploadtext.text(currentUploads + ' files uploading')
}
})
.error(function(jqXHR, textStatus, errorThrown) {
if(errorThrown === 'abort') {
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
currentUploads -= 1;
uploadtext.attr('currentUploads', currentUploads);
if(currentUploads === 0) {
var img = OC.imagePath('core', 'filetypes/folder.png');
var tr=$('tr').filterAttr('data-file',dirName);
tr.find('td.filename').attr('style','background-image:url('+img+')');
uploadtext.text('');
uploadtext.hide();
} else {
uploadtext.text(currentUploads + ' files uploading')
}
$('#notification').hide();
$('#notification').text(t('files', 'Upload cancelled.'));
$('#notification').fadeIn();
}
});
//TODO test with filenames containing slashes
if(uploadingFiles[dirName] === undefined) {
uploadingFiles[dirName] = {};
}
uploadingFiles[dirName][fileName] = jqXHR;
} else {
var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i]})
.success(function(result, textStatus, jqXHR) {
var response;
response=jQuery.parseJSON(result);
if(response[0] != undefined && response[0].status == 'success') {
var file=response[0];
delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
} else {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
$('#fileList > tr').not('[data-mime]').fadeOut();
$('#fileList > tr').not('[data-mime]').remove();
}
})
.error(function(jqXHR, textStatus, errorThrown) {
if(errorThrown === 'abort') {
$('#notification').hide();
$('#notification').text(t('files', 'Upload cancelled.'));
$('#notification').fadeIn();
}
});
uploadingFiles[files[i].name] = jqXHR;
}
}
}else{
data.submit().success(function(data, status) {
response = jQuery.parseJSON(data[0].body.innerText);
if(response[0] != undefined && response[0].status == 'success') {
var file=response[0];
delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
} else {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
$('#fileList > tr').not('[data-mime]').fadeOut();
$('#fileList > tr').not('[data-mime]').remove();
}
});
}
var date=new Date(); var date=new Date();
if(files){ if(files){
for(var i=0;i<files.length;i++){ for(var i=0;i<files.length;i++){
@ -331,7 +227,7 @@ $(document).ready(function() {
var size=t('files','Pending'); var size=t('files','Pending');
} }
if(files && !dirName){ if(files && !dirName){
FileList.addFile(getUniqueName(files[i].name),size,date,true); FileList.addFile(getUniqueName(files[i].name),size,date,true);
} else if(dirName) { } else if(dirName) {
var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext') var uploadtext = $('tr').filterAttr('data-type', 'dir').filterAttr('data-file', dirName).find('.uploadtext')
var currentUploads = parseInt(uploadtext.attr('currentUploads')); var currentUploads = parseInt(uploadtext.attr('currentUploads'));
@ -350,7 +246,115 @@ $(document).ready(function() {
} }
}else{ }else{
var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename var filename=this.value.split('\\').pop(); //ie prepends C:\fakepath\ in front of the filename
FileList.addFile(getUniqueName(filename),'Pending',date,true); FileList.addFile(getUniqueName(filename),'Pending',date,true);
}
if($.support.xhrFileUpload) {
for(var i=0;i<files.length;i++){
var fileName = files[i].name
var dropTarget = $(e.originalEvent.target).closest('tr');
if(dropTarget && dropTarget.attr('data-type') === 'dir') { // drag&drop upload to folder
var dirName = dropTarget.attr('data-file')
var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i],
formData: function(form) {
var formArray = form.serializeArray();
formArray[1]['value'] = dirName;
return formArray;
}}).success(function(result, textStatus, jqXHR) {
var response;
response=jQuery.parseJSON(result);
if(response[0] == undefined || response[0].status != 'success') {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
}
var file=response[0];
delete uploadingFiles[dirName][file.name];
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
currentUploads -= 1;
uploadtext.attr('currentUploads', currentUploads);
if(currentUploads === 0) {
var img = OC.imagePath('core', 'filetypes/folder.png');
var tr=$('tr').filterAttr('data-file',dirName);
tr.find('td.filename').attr('style','background-image:url('+img+')');
uploadtext.text('');
uploadtext.hide();
} else {
uploadtext.text(currentUploads + ' files uploading')
}
})
.error(function(jqXHR, textStatus, errorThrown) {
if(errorThrown === 'abort') {
var currentUploads = parseInt(uploadtext.attr('currentUploads'));
currentUploads -= 1;
uploadtext.attr('currentUploads', currentUploads);
if(currentUploads === 0) {
var img = OC.imagePath('core', 'filetypes/folder.png');
var tr=$('tr').filterAttr('data-file',dirName);
tr.find('td.filename').attr('style','background-image:url('+img+')');
uploadtext.text('');
uploadtext.hide();
} else {
uploadtext.text(currentUploads + ' files uploading')
}
$('#notification').hide();
$('#notification').text(t('files', 'Upload cancelled.'));
$('#notification').fadeIn();
}
});
//TODO test with filenames containing slashes
if(uploadingFiles[dirName] === undefined) {
uploadingFiles[dirName] = {};
}
uploadingFiles[dirName][fileName] = jqXHR;
} else {
var jqXHR = $('.file_upload_start').fileupload('send', {files: files[i]})
.success(function(result, textStatus, jqXHR) {
var response;
response=jQuery.parseJSON(result);
if(response[0] != undefined && response[0].status == 'success') {
var file=response[0];
delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
} else {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
$('#fileList > tr').not('[data-mime]').fadeOut();
$('#fileList > tr').not('[data-mime]').remove();
}
})
.error(function(jqXHR, textStatus, errorThrown) {
if(errorThrown === 'abort') {
$('#notification').hide();
$('#notification').text(t('files', 'Upload cancelled.'));
$('#notification').fadeIn();
}
});
uploadingFiles[files[i].name] = jqXHR;
}
}
}else{
data.submit().success(function(data, status) {
response = jQuery.parseJSON(data[0].body.innerText);
if(response[0] != undefined && response[0].status == 'success') {
var file=response[0];
delete uploadingFiles[file.name];
$('tr').filterAttr('data-file',file.name).data('mime',file.mime);
var size = $('tr').filterAttr('data-file',file.name).find('td.filesize').text();
if(size==t('files','Pending')){
$('tr').filterAttr('data-file',file.name).find('td.filesize').text(file.size);
}
FileList.loadingDone(file.name);
} else {
$('#notification').text(t('files', response.data.message));
$('#notification').fadeIn();
$('#fileList > tr').not('[data-mime]').fadeOut();
$('#fileList > tr').not('[data-mime]').remove();
}
});
} }
} }
}, },

View file

@ -5,7 +5,8 @@
<description>Transparent opening of archives</description> <description>Transparent opening of archives</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>3</require> <require>4</require>
<shipped>true</shipped>
<types> <types>
<filesystem/> <filesystem/>
</types> </types>

View file

@ -89,7 +89,7 @@ class OC_Filestorage_Archive extends OC_Filestorage_Common{
if($path==''){ if($path==''){
return file_exists($this->path); return file_exists($this->path);
} }
return $this->archive->fileExists($path) or $this->archive->fileExists($path.'/'); return $this->archive->fileExists($path);
} }
public function unlink($path){ public function unlink($path){
$path=$this->stripPath($path); $path=$this->stripPath($path);

View file

@ -22,4 +22,18 @@ class Test_Filestorage_Archive_Zip extends Test_FileStorage {
} }
} }
?> class Test_Filestorage_Archive_Tar extends Test_FileStorage {
/**
* @var string tmpDir
*/
private $tmpFile;
public function setUp(){
$this->tmpFile=OCP\Files::tmpFile('.tar.gz');
$this->instance=new OC_Filestorage_Archive(array('archive'=>$this->tmpFile));
}
public function tearDown(){
unlink($this->tmpFile);
}
}

View file

@ -2,10 +2,11 @@
<info> <info>
<id>files_encryption</id> <id>files_encryption</id>
<name>Encryption</name> <name>Encryption</name>
<description>Server side encryption of files</description> <description>Server side encryption of files. Warning: You will lose your data if you enable this App and forget your password. Encryption is not yet compatible with LDAP.</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>3</require> <require>4</require>
<shipped>true</shipped>
<types> <types>
<filesystem/> <filesystem/>
</types> </types>

View file

@ -6,7 +6,11 @@
* See the COPYING-README file. * See the COPYING-README file.
*/ */
OC::$CLASSPATH['OC_FileStorage_StreamWrapper']='apps/files_external/lib/streamwrapper.php';
OC::$CLASSPATH['OC_Filestorage_FTP']='apps/files_external/lib/ftp.php'; 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_DAV']='apps/files_external/lib/webdav.php';
OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php'; OC::$CLASSPATH['OC_Filestorage_Google']='apps/files_external/lib/google.php';
OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php'; OC::$CLASSPATH['OC_Filestorage_SWIFT']='apps/files_external/lib/swift.php';
OC::$CLASSPATH['OC_Filestorage_SMB']='apps/files_external/lib/smb.php';
OCP\App::registerAdmin('files_external', 'settings');

View file

@ -4,8 +4,9 @@
<name>External storage support</name> <name>External storage support</name>
<description>Mount external storage sources</description> <description>Mount external storage sources</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman, Michael Gapczynski</author>
<require>3</require> <require>4</require>
<shipped>true</shipped>
<types> <types>
<filesystem/> <filesystem/>
</types> </types>

View file

@ -0,0 +1,6 @@
.error { color: #FF3B3B; }
td.type { width:8em; }
td.mount, td.options, td.applicable { width:10em; }
#addStorage>td { border:none; }
#addStorage>td:not(.selectStorage) { visibility:hidden; }
#selectStorage { margin-left:-10px; }

View file

@ -0,0 +1,59 @@
$(document).ready(function(){
function applicableChange(applicable) {
if (applicable == 'Global') {
}
console.log(applicable);
}
$('#selectStorage').live('change', function() {
var tr = $(this).parent().parent();
$('#externalStorage tbody').last().append($(tr).clone());
var selected = $(this).val();
$(this).parent().text(selected);
var backends = $(this).data('configurations').split(';');
var configuration = [];
// Find selected backend configuration parameters
$.each(backends, function(index, backend) {
if (backend.split(':')[0] == selected) {
configuration = backend.split(':')[1].split(',');
// break;
}
});
var td = $(tr).find('td.configuration');
$.each(configuration, function(index, config) {
if (config.indexOf('*') != -1) {
td.append('<input type="password" placeholder="'+config.substring(1)+'" />');
} else {
td.append('<input type="text" placeholder="'+config+'" />');
}
});
$(tr).find('td').last().attr('class', 'remove');
$(tr).removeAttr('id');
$(this).remove();
});
$('td.remove>img').live('click', function() {
$(this).parent().parent().remove();
// TODO remove storage
});
$('#externalStorage select[multiple]').each(function(index,element){
applyMultiplySelect($(element));
});
function applyMultiplySelect(element) {
var checkHandeler=false;
element.multiSelect({
oncheck:applicableChange,
onuncheck:applicableChange,
minWidth: 120,
});
}
$('#allowUserMounting').bind('change', function() {
// TODO save setting
});
});

View file

@ -6,7 +6,7 @@
* See the COPYING-README file. * See the COPYING-README file.
*/ */
class OC_FileStorage_FTP extends OC_Filestorage_Common{ class OC_FileStorage_FTP extends OC_FileStorage_StreamWrapper{
private $password; private $password;
private $user; private $user;
private $host; private $host;
@ -42,47 +42,6 @@ class OC_FileStorage_FTP extends OC_Filestorage_Common{
$url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path; $url.='://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
return $url; return $url;
} }
public function mkdir($path){
return mkdir($this->constructUrl($path));
}
public function rmdir($path){
if($this->file_exists($path)){
$succes=rmdir($this->constructUrl($path));
clearstatcache();
return $succes;
}else{
return false;
}
}
public function opendir($path){
return opendir($this->constructUrl($path));
}
public function filetype($path){
return filetype($this->constructUrl($path));
}
public function is_readable($path){
return true;//not properly supported
}
public function is_writable($path){
return true;//not properly supported
}
public function file_exists($path){
return file_exists($this->constructUrl($path));
}
public function unlink($path){
$succes=unlink($this->constructUrl($path));
clearstatcache();
return $succes;
}
public function fopen($path,$mode){ public function fopen($path,$mode){
switch($mode){ switch($mode){
case 'r': case 'r':
@ -124,34 +83,4 @@ class OC_FileStorage_FTP extends OC_Filestorage_Common{
unlink($tmpFile); unlink($tmpFile);
} }
} }
public function free_space($path){
return 0;
}
public function touch($path,$mtime=null){
if(is_null($mtime)){
$fh=$this->fopen($path,'a');
fwrite($fh,'');
fclose($fh);
}else{
return false;//not supported
}
}
public function getFile($path,$target){
return copy($this->constructUrl($path),$target);
}
public function uploadFile($path,$target){
return copy($path,$this->constructUrl($target));
}
public function rename($path1,$path2){
return rename($this->constructUrl($path1),$this->constructUrl($path2));
}
public function stat($path){
return stat($this->constructUrl($path));
}
} }

View file

@ -0,0 +1,36 @@
<?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('smb4php/smb.php');
class OC_FileStorage_SMB extends OC_FileStorage_StreamWrapper{
private $password;
private $user;
private $host;
private $root;
private static $tempFiles=array();
public function __construct($params){
$this->host=$params['host'];
$this->user=$params['user'];
$this->password=$params['password'];
$this->root=isset($params['root'])?$params['root']:'/';
//create the root folder if necesary
$this->mkdir('');
}
public function constructUrl($path){
if(substr($path,-1)=='/'){
$path=substr($path,0,-1);
}
return 'smb://'.$this->user.':'.$this->password.'@'.$this->host.$this->root.$path;
}
}

View file

@ -0,0 +1,89 @@
<?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.
*/
abstract class OC_FileStorage_StreamWrapper extends OC_Filestorage_Common{
abstract public function constructUrl($path);
public function mkdir($path){
return mkdir($this->constructUrl($path));
}
public function rmdir($path){
if($this->file_exists($path)){
$succes=rmdir($this->constructUrl($path));
clearstatcache();
return $succes;
}else{
return false;
}
}
public function opendir($path){
return opendir($this->constructUrl($path));
}
public function filetype($path){
return filetype($this->constructUrl($path));
}
public function is_readable($path){
return true;//not properly supported
}
public function is_writable($path){
return true;//not properly supported
}
public function file_exists($path){
return file_exists($this->constructUrl($path));
}
public function unlink($path){
$succes=unlink($this->constructUrl($path));
clearstatcache();
return $succes;
}
public function fopen($path,$mode){
return fopen($this->constructUrl($path),$mode);
}
public function free_space($path){
return 0;
}
public function touch($path,$mtime=null){
if(is_null($mtime)){
$fh=$this->fopen($path,'a');
fwrite($fh,'');
fclose($fh);
}else{
return false;//not supported
}
}
public function getFile($path,$target){
return copy($this->constructUrl($path),$target);
}
public function uploadFile($path,$target){
return copy($path,$this->constructUrl($target));
}
public function rename($path1,$path2){
return rename($this->constructUrl($path1),$this->constructUrl($path2));
}
public function stat($path){
return stat($this->constructUrl($path));
}
}

View file

@ -0,0 +1,35 @@
<?php
/**
* ownCloud
*
* @author Michael Gapczynski
* @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
* 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/>.
*/
OCP\Util::addscript('files_external', 'settings');
OCP\Util::addstyle('files_external', 'settings');
$tmpl = new OCP\Template('files_external', 'settings');
$tmpl->assign('allowUserMounting', 'yes');
$tmpl->assign('isAdminPage', true);
$tmpl->assign('storage', array());
$tmpl->assign('groups', OC_Group::getGroups());
$tmpl->assign('backends', array('Amazon S3', 'FTP', 'Google Drive', 'SWIFT', 'WebDAV'));
$tmpl->assign('configurations', '');
$tmpl->assign('options', array('Encrypt', 'Version control', 'Allow sharing'));
return $tmpl->fetchPage();
?>

View file

@ -0,0 +1,74 @@
<form id="files_external">
<fieldset class="personalblock">
<legend><strong><?php echo $l->t('External Storage'); ?></strong></legend>
<?php if (isset($_['storage'])): ?>
<table id="externalStorage">
<thead>
<tr>
<th><?php echo $l->t('Type'); ?></th>
<th><?php echo $l->t('Configuration'); ?></th>
<th><?php echo $l->t('Mount Location'); ?></th>
<th><?php echo $l->t('Options'); ?></th>
<?php if ($_['isAdminPage'] == true) echo '<th>'.$l->t('Applicable').'</th>'; ?>
<th>&nbsp;</th>
</tr>
</thead>
<tbody>
<?php $_['storage'] = array_merge($_['storage'], array(array('id' => 'addStorage', 'mount' => ''))); ?>
<?php foreach($_['storage'] as $storage): ?>
<tr <?php if ($storage['id'] == 'addStorage') echo 'id="addStorage"'; ?> data-storage-id="<?php echo $storage['id']; ?>">
<?php if ($storage['id'] == 'addStorage'): ?>
<td class="selectStorage">
<select id="selectStorage" data-configurations="<?php echo $_['configurations']; ?>">
<option value="" disabled selected style="display:none;"><?php echo $l->t('Add storage'); ?></option>
<?php foreach($_['backends'] as $backend): ?>
<option value="<?php echo $backend; ?>"><?php echo $backend; ?></option>
<?php endforeach; ?>
</select>
</td>
<?php else: ?>
<td class="type" <?php if ($storage['status'] == 'error') echo 'class="error"'; ?>><?php echo $storage['type']; ?></td>
<?php endif; ?>
<td class ="configuration">
<?php if (isset($storage['configuration'])): ?>
<?php foreach($storage['configuration'] as $parameter => $value): ?>
<?php if (strpos($parameter, '*') !== false): ?>
<input type="password" value="<?php echo $value; ?>" placeholder="<?php echo $l->t(substr($parameter, 1)); ?>" />
<?php else: ?>
<input type="text" value="<?php echo $value; ?>" placeholder="<?php echo $l->t($parameter); ?>" />
<?php endif; ?>
<?php endforeach; ?>
<?php endif; ?>
</td>
<td class="mount"><input type="text" name="storageMountLocation" value="<?php echo $storage['mount']; ?>" placeholder="<?php echo $l->t('Mount Location'); ?>" /></td>
<td class="options">
<select class="selectOptions" title="<?php echo $l->t('None set')?>" multiple="multiple">
<?php if (OCP\App::isEnabled('files_encryption')) echo '<option value="Encrypt">Encrypt</option>'; ?>
<?php if (OCP\App::isEnabled('files_versions')) echo '<option value="Version control">Version control</option>'; ?>
<?php if (OCP\App::isEnabled('files_sharing')) echo '<option value="Allow sharing">Allow sharing</option>'; ?>
</select>
</td>
<?php if ($_['isAdminPage'] == true): ?>
<td class="applicable">
<select class="selectApplicable" data-storage-applicable="<?php echo $storage['applicable']; ?>" title="<?php echo $l->t('None set'); ?>" multiple="multiple">
<option value="Global"><?php echo $l->t('Global'); ?></option>
<?php foreach($_['groups'] as $group): ?>
<option value="<?php echo $group; ?>"><?php echo $group; ?></option>
<?php endforeach; ?>
</select>
</td>
<?php endif; ?>
<td <?php if ($storage['id'] != 'addStorage') echo 'class="remove"'; ?>><img alt="<?php echo $l->t('Delete'); ?>" title="<?php echo $l->t('Delete'); ?>" class="svg action" src="<?php echo image_path('core', 'actions/delete.svg'); ?>" /></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php endif; ?>
<?php if ($_['isAdminPage'] == true): ?>
<br />
<input type="checkbox" name="allowUserMounting" id="allowUserMounting" value="1" <?php if ($_['allowUserMounting'] == 'yes') echo ' checked="checked"'; ?> />
<label for="allowUserMounting"><?php echo $l->t('Enable User External Storage'); ?></label><br/>
<em><?php echo $l->t('Allow users to mount their own external storage'); ?></em>
<?php endif; ?>
</fieldset>
</form>

View file

@ -29,4 +29,11 @@ return array(
'host'=>'localhost:8080/auth', 'host'=>'localhost:8080/auth',
'root'=>'/', 'root'=>'/',
), ),
'smb'=>array(
'run'=>false,
'user'=>'test',
'password'=>'test',
'host'=>'localhost',
'root'=>'/test',
),
); );

View file

@ -0,0 +1,30 @@
<?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['smb']) or !$config['smb']['run']){
abstract class Test_Filestorage_SMB extends Test_FileStorage{}
return;
}else{
class Test_Filestorage_SMB extends Test_FileStorage {
private $config;
private $id;
public function setUp(){
$id=uniqid();
$this->config=include('apps/files_external/tests/config.php');
$this->config['smb']['root'].='/'.$id;//make sure we have an new empty folder to work in
$this->instance=new OC_Filestorage_SMB($this->config['smb']);
}
public function tearDown(){
OCP\Files::rmdirr($this->instance->constructUrl(''));
}
}
}

View file

@ -5,6 +5,7 @@
<description>Simple image viewer for owncloud</description> <description>Simple image viewer for owncloud</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
</info> </info>

View file

@ -5,6 +5,7 @@
<description>Inline PDF viewer (pdfjs-based)</description> <description>Inline PDF viewer (pdfjs-based)</description>
<licence>GPL</licence> <licence>GPL</licence>
<author>Joan Creus</author> <author>Joan Creus</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
</info> </info>

View file

@ -5,7 +5,8 @@
<description>File sharing between users</description> <description>File sharing between users</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Michael Gapczynski</author> <author>Michael Gapczynski</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
<types> <types>
<filesystem/> <filesystem/>

View file

@ -361,7 +361,6 @@ $(document).ready(function() {
}); });
$('#emailPrivateLink').live('submit', function() { $('#emailPrivateLink').live('submit', function() {
event.preventDefault();
OC.Share.emailPrivateLink(); OC.Share.emailPrivateLink();
}); });
}); });

View file

@ -171,6 +171,26 @@ class OC_Share {
return $in; return $in;
} }
private static function updateFolder($uid_shared_with) {
if ($uid_shared_with != self::PUBLICLINK) {
if (OC_Group::groupExists($uid_shared_with)) {
$uid_shared_with = OC_Group::usersInGroup($uid_shared_with);
// Remove the owner from the list of users in the group
$uid_shared_with = array_diff($uid_shared_with, array(OCP\USER::getUser()));
} else if ($uid = strstr($uid_shared_with, '@', true)) {
$uid_shared_with = array($uid);
} else {
$uid_shared_with = array($uid_shared_with);
}
foreach ($uid_shared_with as $uid) {
$sharedFolder = $uid.'/files/Shared';
// Update mtime of shared folder to invoke a file cache rescan
$rootView = new OC_FilesystemView('/');
$rootView->touch($sharedFolder);
}
}
}
/** /**
* Create a new entry in the database for a file inside a shared folder * Create a new entry in the database for a file inside a shared folder
* *
@ -396,21 +416,7 @@ class OC_Share {
$uid_owner = OCP\USER::getUser(); $uid_owner = OCP\USER::getUser();
$query = OCP\DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ? AND uid_shared_with ".self::getUsersAndGroups($uid_shared_with, false)); $query = OCP\DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ? AND uid_shared_with ".self::getUsersAndGroups($uid_shared_with, false));
$query->execute(array(strlen($source), $source, $uid_owner)); $query->execute(array(strlen($source), $source, $uid_owner));
if ($uid_shared_with != self::PUBLICLINK) { self::updateFolder($uid_shared_with);
if (OC_Group::groupExists($uid_shared_with)) {
$uid_shared_with = OC_Group::usersInGroup($uid_shared_with);
// Remove the owner from the list of users in the group
$uid_shared_with = array_diff($uid_shared_with, array($uid_owner));
} else {
$uid_shared_with = array($uid_shared_with);
}
foreach ($uid_shared_with as $uid) {
$sharedFolder = '/'.$uid.'/files/'.'Shared';
// Update mtime of shared folder to invoke a file cache rescan
$rootView=new OC_FilesystemView('/');
$rootView->touch($sharedFolder);
}
}
} }
/** /**
@ -438,13 +444,14 @@ class OC_Share {
*/ */
public static function deleteItem($arguments) { public static function deleteItem($arguments) {
$source = "/".OCP\USER::getUser()."/files".self::cleanPath($arguments['path']); $source = "/".OCP\USER::getUser()."/files".self::cleanPath($arguments['path']);
if ($target = self::getTarget($source)) { $result = self::getMySharedItem($source);
// Forward hook to notify of changes to target file if (is_array($result)) {
OCP\Util::emitHook("OC_Filesystem", "post_delete", array('path' => $target)); foreach ($result as $item) {
$query = OCP\DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ?"); self::updateFolder($item['uid_shared_with']);
$query->execute(array(strlen($source), $source, OCP\USER::getUser())); }
} }
$query = OCP\DB::prepare("DELETE FROM *PREFIX*sharing WHERE SUBSTR(source, 1, ?) = ? AND uid_owner = ?");
$query->execute(array(strlen($source), $source, OCP\USER::getUser()));
} }
/** /**
@ -460,15 +467,25 @@ class OC_Share {
public static function updateItem($arguments) { public static function updateItem($arguments) {
$source = "/".OCP\USER::getUser()."/files".self::cleanPath($arguments['path']); $source = "/".OCP\USER::getUser()."/files".self::cleanPath($arguments['path']);
if ($target = self::getTarget($source)) { $result = self::getMySharedItem($source);
// Forward hook to notify of changes to target file if (is_array($result)) {
OCP\Util::emitHook("OC_Filesystem", "post_write", array('path' => $target)); foreach ($result as $item) {
self::updateFolder($item['uid_shared_with']);
}
} }
} }
public static function removeUser($arguments) { public static function removeUser($arguments) {
$query = OCP\DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_owner = ? OR uid_shared_with '.self::getUsersAndGroups($arguments['uid'])); $query = OCP\DB::prepare("SELECT uid_shared_with FROM *PREFIX*sharing WHERE uid_owner = ?");
$query->execute(array($arguments['uid'])); $result = $query->execute(array($arguments['uid']))->fetchAll();
if (is_array($result)) {
$result = array_unique($result);
foreach ($result as $item) {
self::updateFolder($item['uid_shared_with']);
}
$query = OCP\DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_owner = ? OR uid_shared_with '.self::getUsersAndGroups($arguments['uid']));
$query->execute(array($arguments['uid']));
}
} }
public static function addToGroupShare($arguments) { public static function addToGroupShare($arguments) {
@ -490,6 +507,7 @@ class OC_Share {
public static function removeFromGroupShare($arguments) { public static function removeFromGroupShare($arguments) {
$query = OCP\DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?'); $query = OCP\DB::prepare('DELETE FROM *PREFIX*sharing WHERE uid_shared_with = ?');
$query->execute(array($arguments['uid'].'@'.$arguments['gid'])); $query->execute(array($arguments['uid'].'@'.$arguments['gid']));
self::updateFolder($arguments['uid']);
} }
} }

View file

@ -5,6 +5,7 @@
<description>Simple plain text editor based on Ace editor.</description> <description>Simple plain text editor based on Ace editor.</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Tom Needham</author> <author>Tom Needham</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
</info> </info>

File diff suppressed because one or more lines are too long

View file

@ -12,6 +12,4 @@ OCP\App::registerAdmin('files_versions', 'settings');
OCP\Util::addscript('files_versions', 'versions'); OCP\Util::addscript('files_versions', 'versions');
// Listen to write signals // Listen to write signals
OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OCA_Versions\Storage", "write_hook"); OCP\Util::connectHook(OC_Filesystem::CLASSNAME, OC_Filesystem::signal_post_write, "OCA_Versions\Storage", "write_hook");
?>

View file

@ -1,11 +1,12 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>files_versions</id> <id>files_versions</id>
<name>Versions</name> <name>Versions</name>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Frank Karlitschek</author> <author>Frank Karlitschek</author>
<require>3</require> <require>4</require>
<description>Versioning of files</description> <shipped>true</shipped>
<description>Versioning of files</description>
<types> <types>
<filesystem/> <filesystem/>
</types> </types>

View file

@ -16,26 +16,34 @@ $(document).ready(function(){
if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback if (scanFiles.scanning){return;}//workaround to prevent additional http request block scanning feedback
var file = $('#dir').val()+'/'+filename; var file = $('#dir').val()+'/'+filename;
// Check if drop down is already visible for a different file
createVersionsDropdown(filename, file) if (($('#dropdown').length > 0)) {
if (file != $('#dropdown').data('file')) {
$('#dropdown').hide('blind', function() {
$('#dropdown').remove();
$('tr').removeClass('mouseOver');
createVersionsDropdown(filename, file);
});
}
} else {
createVersionsDropdown(filename, file);
}
}); });
} }
}); });
function createVersionsDropdown(filename, files) { function createVersionsDropdown(filename, files) {
var historyUrl = OC.linkTo('files_versions', 'history.php?path='+encodeURIComponent( $( '#dir' ).val() ).replace( /%2F/g, '/' )+'/'+encodeURIComponent( filename ) ) var historyUrl = OC.linkTo('files_versions', 'history.php') + '?path='+encodeURIComponent( $( '#dir' ).val() ).replace( /%2F/g, '/' )+'/'+encodeURIComponent( filename );
var html = '<div id="dropdown" class="drop" data-file="'+files+'">'; var html = '<div id="dropdown" class="drop" data-file="'+files+'">';
html += '<div id="private">'; html += '<div id="private">';
html += '<select data-placeholder="File Version" id="found_versions" class="chzen-select">'; html += '<select data-placeholder="Saved versions" id="found_versions" class="chzen-select" style="width:16em;">';
html += '<option value="">Saved versions</option>'; html += '<option value=""></option>';
html += '</select>'; html += '</select>';
html += '</div>'; html += '</div>';
//html += '<input type="button" value="Revert file" onclick="revertFile()" />'; //html += '<input type="button" value="Revert file" onclick="revertFile()" />';
html += '<input type="button" value="All versions..." onclick="window.location=\''+historyUrl+'\'" name="makelink" id="makelink" />'; html += '<input type="button" value="All versions..." onclick="window.location=\''+historyUrl+'\'" name="makelink" id="makelink" />';
html += '<br />';
html += '<input id="link" style="display:none; width:90%;" />'; html += '<input id="link" style="display:none; width:90%;" />';
if (filename) { if (filename) {
@ -56,11 +64,14 @@ function createVersionsDropdown(filename, files) {
//alert("helo "+OC.linkTo('files_versions', 'ajax/getVersions.php')); //alert("helo "+OC.linkTo('files_versions', 'ajax/getVersions.php'));
if (versions) { if (versions) {
$.each( versions, function(index, row ) { $.each( versions, function(index, row ) {
addVersion( row ); addVersion( row );
}); });
$('#found_versions').chosen();
} else {
$('#found_versions').hide();
$('#makelink').hide();
$('<div style="text-align:center;">No other versions available</div>').appendTo('#dropdown');
} }
$('#found_versions').change(function(){ $('#found_versions').change(function(){
var revision=parseInt($(this).val()); var revision=parseInt($(this).val());
@ -80,10 +91,16 @@ function createVersionsDropdown(filename, files) {
success: function(response) { success: function(response) {
if (response.status=='error') { if (response.status=='error') {
OC.dialogs.alert('Failed to revert '+file+' to revision '+formatDate(revision*1000)+'.','Failed to revert'); OC.dialogs.alert('Failed to revert '+file+' to revision '+formatDate(revision*1000)+'.','Failed to revert');
} else {
$('#dropdown').hide('blind', function() {
$('#dropdown').remove();
$('tr').removeClass('mouseOver');
// TODO also update the modified time in the web ui
});
} }
} }
}); });
} }
function addVersion(revision ) { function addVersion(revision ) {
@ -107,6 +124,6 @@ function createVersionsDropdown(filename, files) {
} }
$('#dropdown').show('blind'); $('#dropdown').show('blind');
$('#share_with').chosen();
} }

View file

@ -23,7 +23,7 @@ if( isset( $_['message'] ) ) {
echo ' '; echo ' ';
echo OCP\Util::formatDate( $v ); echo OCP\Util::formatDate( $v );
echo ' <a href="history.php?path='.urlencode( $_['path'] ).'&revert='. $v .'" class="button">Revert</a><br /><br />'; echo ' <a href="'.OCP\Util::linkTo('files_versions', 'history.php').'?path='.urlencode( $_['path'] ).'&revert='. $v .'" class="button">Revert</a><br /><br />';
} }

View file

@ -69,8 +69,15 @@ class Storage {
*/ */
public static function store($filename) { public static function store($filename) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/files'; $pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
} else {
$uid = \OCP\User::getUser();
}
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
$filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files';
Storage::init(); Storage::init();
// check if filename is a directory // check if filename is a directory
@ -94,20 +101,21 @@ class Storage {
} }
// check mininterval // check mininterval if the file is being modified by the owner (all shared files should be versioned despite mininterval)
$matches=glob($versionsfoldername.$filename.'.v*'); if ($uid == \OCP\User::getUser()) {
sort($matches); $matches=glob($versionsfoldername.$filename.'.v*');
$parts=explode('.v',end($matches)); sort($matches);
if((end($parts)+Storage::DEFAULTMININTERVAL)>time()){ $parts=explode('.v',end($matches));
return false; if((end($parts)+Storage::DEFAULTMININTERVAL)>time()){
return false;
}
} }
// create all parent folders // create all parent folders
$info=pathinfo($filename); $info=pathinfo($filename);
@mkdir($versionsfoldername.$info['dirname'],0700,true); @mkdir($versionsfoldername.$info['dirname'],0700,true);
// store a new version of a file // store a new version of a file
copy($filesfoldername.$filename,$versionsfoldername.$filename.'.v'.time()); copy($filesfoldername.$filename,$versionsfoldername.$filename.'.v'.time());
@ -123,10 +131,16 @@ class Storage {
public static function rollback($filename,$revision) { public static function rollback($filename,$revision) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); $pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
} else {
$uid = \OCP\User::getUser();
}
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'.$uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
$filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/files'; $filesfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/files';
// rollback // rollback
if ( @copy($versionsfoldername.$filename.'.v'.$revision,$filesfoldername.$filename) ) { if ( @copy($versionsfoldername.$filename.'.v'.$revision,$filesfoldername.$filename) ) {
@ -148,7 +162,14 @@ class Storage {
*/ */
public static function isversioned($filename) { public static function isversioned($filename) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
} else {
$uid = \OCP\User::getUser();
}
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
// check for old versions // check for old versions
$matches=glob($versionsfoldername.$filename.'.v*'); $matches=glob($versionsfoldername.$filename.'.v*');
@ -169,7 +190,14 @@ class Storage {
*/ */
public static function getversions($filename,$count=0) { public static function getversions($filename,$count=0) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
} else {
$uid = \OCP\User::getUser();
}
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
$versions=array(); $versions=array();
// fetch for old versions // fetch for old versions
@ -200,8 +228,14 @@ class Storage {
*/ */
public static function expire($filename) { public static function expire($filename) {
if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') { if(\OCP\Config::getSystemValue('files_versions', Storage::DEFAULTENABLED)=='true') {
if (\OCP\App::isEnabled('files_sharing') && $source = \OC_Share::getSource('/'.\OCP\User::getUser().'/files'.$filename)) {
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. \OCP\USER::getUser() .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER); $pos = strpos($source, '/files', 1);
$uid = substr($source, 1, $pos - 1);
$filename = substr($source, $pos + 6);
} else {
$uid = \OCP\User::getUser();
}
$versionsfoldername=\OCP\Config::getSystemValue('datadirectory').'/'. $uid .'/'.\OCP\Config::getSystemValue('files_versionsfolder', Storage::DEFAULTFOLDER);
// check for old versions // check for old versions
$matches=glob($versionsfoldername.$filename.'.v*'); $matches=glob($versionsfoldername.$filename.'.v*');

View file

@ -4,7 +4,8 @@
<name>Pictures</name> <name>Pictures</name>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Bartek Przybylski</author> <author>Bartek Przybylski</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<description>Dedicated pictures application</description> <description>Dedicated pictures application</description>
<standalone/> <standalone/>
<default_enable/> <default_enable/>

View file

@ -21,8 +21,6 @@
* *
*/ */
require_once('base.php');
class OC_Gallery_Album { class OC_Gallery_Album {
public static function create($owner, $name, $path){ public static function create($owner, $name, $path){
$stmt = OCP\DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name, album_path, parent_path) VALUES (?, ?, ?, ?)'); $stmt = OCP\DB::prepare('INSERT INTO *PREFIX*gallery_albums (uid_owner, album_name, album_path, parent_path) VALUES (?, ?, ?, ?)');

View file

@ -5,7 +5,8 @@
<description>Media player and server for ownCloud</description> <description>Media player and server for ownCloud</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<standalone/> <standalone/>
<default_enable/> <default_enable/>
<remote> <remote>

View file

@ -5,5 +5,6 @@
<description>Enables you to use ownCloud as their remote storage for unhosted applications. This app requires the Webfinger app to be installed and enabled correctly. More info on <a href="http://unhosted.org">the website of the unhosted movement</a>.</description> <description>Enables you to use ownCloud as their remote storage for unhosted applications. This app requires the Webfinger app to be installed and enabled correctly. More info on <a href="http://unhosted.org">the website of the unhosted movement</a>.</description>
<licence>AGPL or MIT</licence> <licence>AGPL or MIT</licence>
<author>Michiel de Jong</author> <author>Michiel de Jong</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
</info> </info>

View file

@ -5,6 +5,7 @@
<version>0.1</version> <version>0.1</version>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Bart Visscher</author> <author>Bart Visscher</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<description>Tasks view from calendar</description> <description>Tasks view from calendar</description>
</info> </info>

View file

@ -32,7 +32,7 @@
.task .completed {position:absolute;left:3em;top:0.3em;} .task .completed {position:absolute;left:3em;top:0.3em;}
.task .summary{padding-left:4em;} .task .summary{padding-left:4em;height:2em;}
.task .summary input{position:relative;left:5px;} .task .summary input{position:relative;left:5px;}
.task.done .summary{text-decoration:line-through;} .task.done .summary{text-decoration:line-through;}

View file

@ -27,12 +27,6 @@ require_once('apps/user_ldap/group_ldap.php');
OCP\App::registerAdmin('user_ldap','settings'); OCP\App::registerAdmin('user_ldap','settings');
// define LDAP_DEFAULT_PORT
define('OC_USER_BACKEND_LDAP_DEFAULT_PORT', 389);
// define OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME
define('OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME', 'uid');
// register user backend // register user backend
OC_User::useBackend( 'LDAP' ); OC_User::useBackend( 'LDAP' );
OC_Group::useBackend( new OC_GROUP_LDAP() ); OC_Group::useBackend( new OC_GROUP_LDAP() );

View file

@ -1,11 +1,12 @@
<?xml version="1.0"?> <?xml version="1.0"?>
<info> <info>
<id>user_ldap</id> <id>user_ldap</id>
<name>LDAP user backend</name> <name>LDAP user and group backend</name>
<description>Authenticate Users by LDAP</description> <description>Authenticate Users by LDAP</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Dominik Schmidt</author> <author>Dominik Schmidt and Arthur Schiwon</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<types> <types>
<authentication/> <authentication/>
</types> </types>

View file

@ -0,0 +1,6 @@
<?php
$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doSet');
if($state == 'doSet'){
OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
}

View file

@ -1,9 +1,36 @@
<?php <?php
//from version 0.1 to 0.2 //from version 0.1 to 0.2
//settings
$pw = OCP\Config::getAppValue('user_ldap', 'ldap_password'); $pw = OCP\Config::getAppValue('user_ldap', 'ldap_password');
if(!is_null($pw)) { if(!is_null($pw)) {
$pwEnc = base64_encode($pw); $pwEnc = base64_encode($pw);
OCP\Config::setAppValue('user_ldap', 'ldap_agent_password', $pwEnc); OCP\Config::setAppValue('user_ldap', 'ldap_agent_password', $pwEnc);
OC_Appconfig::deleteKey('user_ldap', 'ldap_password'); OC_Appconfig::deleteKey('user_ldap', 'ldap_password');
}
//detect if we can switch on naming guidelines. We won't do it on conflicts.
//it's a bit spaghetti, but hey.
$state = OCP\Config::getSystemValue('ldapIgnoreNamingRules', 'doCheck');
if($state == 'doCheck'){
$sqlCleanMap = 'DELETE FROM *PREFIX*ldap_user_mapping';
require_once(OC::$APPSROOT.'/apps/user_ldap/lib_ldap.php');
require_once(OC::$APPSROOT.'/apps/user_ldap/user_ldap.php');
OCP\Config::setSystemValue('ldapIgnoreNamingRules', true);
$LDAP_USER = new OC_USER_LDAP();
$users_old = $LDAP_USER->getUsers();
$query = OCP\DB::prepare($sqlCleanMap);
$query->execute();
OCP\Config::setSystemValue('ldapIgnoreNamingRules', false);
OC_LDAP::init(true);
$users_new = $LDAP_USER->getUsers();
$query = OCP\DB::prepare($sqlCleanMap);
$query->execute();
if($users_old !== $users_new) {
//we don't need to check Groups, because they were not supported in 3'
OCP\Config::setSystemValue('ldapIgnoreNamingRules', true);
}
} }

View file

@ -1 +1 @@
0.1.92 0.2

View file

@ -45,14 +45,21 @@ class OC_LDAP {
static protected $ldapAgentPassword; static protected $ldapAgentPassword;
static protected $ldapTLS; static protected $ldapTLS;
static protected $ldapNoCase; static protected $ldapNoCase;
static protected $ldapIgnoreNamingRules;
// user and group settings, that are needed in both backends // user and group settings, that are needed in both backends
static protected $ldapUserDisplayName; static protected $ldapUserDisplayName;
static protected $ldapUserFilter; static protected $ldapUserFilter;
static protected $ldapGroupDisplayName; static protected $ldapGroupDisplayName;
static protected $ldapLoginFilter; static protected $ldapLoginFilter;
static public function init() { /**
self::readConfiguration(); * @brief initializes the LDAP backend
* @param $force read the config settings no matter what
*
* initializes the LDAP backend
*/
static public function init($force = false) {
self::readConfiguration($force);
self::establishConnection(); self::establishConnection();
} }
@ -527,6 +534,10 @@ class OC_LDAP {
} }
static private function sanitizeUsername($name) { static private function sanitizeUsername($name) {
if(self::$ldapIgnoreNamingRules) {
return $name;
}
//REPLACEMENTS //REPLACEMENTS
$name = str_replace(' ', '_', $name); $name = str_replace(' ', '_', $name);
@ -594,21 +605,22 @@ class OC_LDAP {
/** /**
* Caches the general LDAP configuration. * Caches the general LDAP configuration.
*/ */
static private function readConfiguration() { static private function readConfiguration($force = false) {
if(!self::$configured) { if(!self::$configured || $force) {
self::$ldapHost = OCP\Config::getAppValue('user_ldap', 'ldap_host', ''); self::$ldapHost = OCP\Config::getAppValue('user_ldap', 'ldap_host', '');
self::$ldapPort = OCP\Config::getAppValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT); self::$ldapPort = OCP\Config::getAppValue('user_ldap', 'ldap_port', 389);
self::$ldapAgentName = OCP\Config::getAppValue('user_ldap', 'ldap_dn',''); self::$ldapAgentName = OCP\Config::getAppValue('user_ldap', 'ldap_dn','');
self::$ldapAgentPassword = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password','')); self::$ldapAgentPassword = base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password',''));
self::$ldapBase = OCP\Config::getAppValue('user_ldap', 'ldap_base', ''); self::$ldapBase = OCP\Config::getAppValue('user_ldap', 'ldap_base', '');
self::$ldapBaseUsers = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase); self::$ldapBaseUsers = OCP\Config::getAppValue('user_ldap', 'ldap_base_users',self::$ldapBase);
self::$ldapBaseGroups = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase); self::$ldapBaseGroups = OCP\Config::getAppValue('user_ldap', 'ldap_base_groups', self::$ldapBase);
self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0); self::$ldapTLS = OCP\Config::getAppValue('user_ldap', 'ldap_tls',0);
self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0); self::$ldapNoCase = OCP\Config::getAppValue('user_ldap', 'ldap_nocase', 0);
self::$ldapUserDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME)); self::$ldapUserDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'));
self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person'); self::$ldapUserFilter = OCP\Config::getAppValue('user_ldap', 'ldap_userlist_filter','objectClass=person');
self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)'); self::$ldapLoginFilter = OCP\Config::getAppValue('user_ldap', 'ldap_login_filter', '(uid=%uid)');
self::$ldapGroupDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR)); self::$ldapGroupDisplayName = strtolower(OCP\Config::getAppValue('user_ldap', 'ldap_group_display_name', LDAP_GROUP_DISPLAY_NAME_ATTR));
self::$ldapIgnoreNamingRules = OCP\Config::getSystemValue('ldapIgnoreNamingRules', false);
if(empty(self::$ldapBaseUsers)) { if(empty(self::$ldapBaseUsers)) {
OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO); OCP\Util::writeLog('ldap', 'Base for Users is empty, using Base DN', OCP\Util::INFO);

View file

@ -52,8 +52,8 @@ foreach($params as $param){
} }
// settings with default values // settings with default values
$tmpl->assign( 'ldap_port', OCP\Config::getAppValue('user_ldap', 'ldap_port', OC_USER_BACKEND_LDAP_DEFAULT_PORT)); $tmpl->assign( 'ldap_port', OCP\Config::getAppValue('user_ldap', 'ldap_port', '389'));
$tmpl->assign( 'ldap_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_display_name', OC_USER_BACKEND_LDAP_DEFAULT_DISPLAY_NAME)); $tmpl->assign( 'ldap_display_name', OCP\Config::getAppValue('user_ldap', 'ldap_display_name', 'uid'));
$tmpl->assign( 'ldap_group_member_assoc_attribute', OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember')); $tmpl->assign( 'ldap_group_member_assoc_attribute', OCP\Config::getAppValue('user_ldap', 'ldap_group_member_assoc_attribute', 'uniqueMember'));
$tmpl->assign( 'ldap_agent_password', base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password'))); $tmpl->assign( 'ldap_agent_password', base64_decode(OCP\Config::getAppValue('user_ldap', 'ldap_agent_password')));

View file

@ -5,6 +5,7 @@
<description>Migrate your user accounts</description> <description>Migrate your user accounts</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Tom Needham</author> <author>Tom Needham</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<default_enable/> <default_enable/>
</info> </info>

View file

@ -5,7 +5,8 @@
<description>Allow login through OpenID</description> <description>Allow login through OpenID</description>
<licence>AGPL</licence> <licence>AGPL</licence>
<author>Robin Appelman</author> <author>Robin Appelman</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
<types> <types>
<authentication/> <authentication/>
</types> </types>

View file

@ -36,7 +36,6 @@ if($USERNAME=='' and isset($_SERVER['PHP_AUTH_USER'])){
$RUNTIME_NOAPPS=true; $RUNTIME_NOAPPS=true;
$RUNTIME_NOAPPS=false; $RUNTIME_NOAPPS=false;
require_once '../../lib/base.php';
OCP\App::checkAppEnabled('user_openid'); OCP\App::checkAppEnabled('user_openid');
if(!OCP\User::userExists($USERNAME)){ if(!OCP\User::userExists($USERNAME)){

View file

@ -5,5 +5,6 @@
<description>Provide WebFinger for all users so they get a user address like user@owncloudinstance which can be used for external applications. Other apps can provide information for webfinger requests, such as remoteStorage compatibility.</description> <description>Provide WebFinger for all users so they get a user address like user@owncloudinstance which can be used for external applications. Other apps can provide information for webfinger requests, such as remoteStorage compatibility.</description>
<licence>AGPL or MIT</licence> <licence>AGPL or MIT</licence>
<author>Michiel de Jong, Florian Hülsmann</author> <author>Michiel de Jong, Florian Hülsmann</author>
<require>2</require> <require>4</require>
<shipped>true</shipped>
</info> </info>

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 519 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

View file

@ -1,7 +1,7 @@
<!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]--> <!--[if IE 8]><style>input[type="checkbox"]{padding:0;}</style><![endif]-->
<form action="index.php" method="post"> <form action="index.php" method="post">
<fieldset> <fieldset>
<?php if(!empty($_['redirect'])) { echo '<input type="hidden" name="redirect_url" value="'.$_['redirect'].'" />'; } ?> <?php if(!empty($_['redirect'])) { echo '<input type="hidden" name="redirect_url" value="'.htmlentities($_['redirect']).'" />'; } ?>
<?php if($_['error']): ?> <?php if($_['error']): ?>
<a href="./core/lostpassword/"><?php echo $l->t('Lost your password?'); ?></a> <a href="./core/lostpassword/"><?php echo $l->t('Lost your password?'); ?></a>
<?php endif; ?> <?php endif; ?>

View file

@ -117,6 +117,7 @@ elseif(OC_User::isLoggedIn()) {
if(!array_key_exists('sectoken', $_SESSION) || (array_key_exists('sectoken', $_SESSION) && is_null(OC::$REQUESTEDFILE)) || substr(OC::$REQUESTEDFILE, -3) == 'php'){ if(!array_key_exists('sectoken', $_SESSION) || (array_key_exists('sectoken', $_SESSION) && is_null(OC::$REQUESTEDFILE)) || substr(OC::$REQUESTEDFILE, -3) == 'php'){
$sectoken=rand(1000000,9999999); $sectoken=rand(1000000,9999999);
$_SESSION['sectoken']=$sectoken; $_SESSION['sectoken']=$sectoken;
OC_Template::printGuestPage('', 'login', array('error' => $error, 'sectoken' => $sectoken, 'redirect' => isset($_REQUEST['redirect_url'])?htmlentities($_REQUEST['redirect_url']):'' )); $redirect_url = (isset($_REQUEST['redirect_url'])) ? $_REQUEST['redirect_url'] : $_SERVER['REQUEST_URI'];
OC_Template::printGuestPage('', 'login', array('error' => $error, 'sectoken' => $sectoken, 'redirect' => $redirect_url));
} }
} }

View file

@ -478,7 +478,7 @@ class MDB2_Driver_sqlite3 extends MDB2_Driver_Common
* @return result or error object * @return result or error object
* @access protected * @access protected
*/ */
function &_doQuery($query, $is_manip = false, $connection = null, $database_name = null) function _doQuery($query, $is_manip = false, $connection = null, $database_name = null)
{ {
$this->last_query = $query; $this->last_query = $query;
$result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre')); $result = $this->debug($query, 'query', array('is_manip' => $is_manip, 'when' => 'pre'));
@ -816,7 +816,7 @@ class MDB2_Driver_sqlite3 extends MDB2_Driver_Common
* @access public * @access public
* @see bindParam, execute * @see bindParam, execute
*/ */
function &prepare($query, $types = null, $result_types = null, $lobs = array()) function prepare($query, $types = null, $result_types = null, $lobs = array())
{ {
if ($this->options['emulate_prepared'] if ($this->options['emulate_prepared']
|| $this->supported['prepared_statements'] !== true || $this->supported['prepared_statements'] !== true
@ -928,7 +928,7 @@ class MDB2_Result_sqlite3 extends MDB2_Result_Common
* @return int data array on success, a MDB2 error on failure * @return int data array on success, a MDB2 error on failure
* @access public * @access public
*/ */
function &fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null) function fetchRow($fetchmode = MDB2_FETCHMODE_DEFAULT, $rownum = null)
{ {
if (!is_null($rownum)) { if (!is_null($rownum)) {
$seek = $this->seek($rownum); $seek = $this->seek($rownum);
@ -1193,7 +1193,7 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common
* a MDB2 error on failure * a MDB2 error on failure
* @access private * @access private
*/ */
function &_execute($result_class = true, $result_wrap_class = false){ function _execute($result_class = true, $result_wrap_class = false){
if (is_null($this->statement)) { if (is_null($this->statement)) {
$result =& parent::_execute($result_class, $result_wrap_class); $result =& parent::_execute($result_class, $result_wrap_class);
return $result; return $result;
@ -1305,7 +1305,7 @@ class MDB2_Statement_sqlite3 extends MDB2_Statement_Common
* a MDB2 error on failure * a MDB2 error on failure
* @access public * @access public
*/ */
function &execute($values = null, $result_class = true, $result_wrap_class = false) function execute($values = null, $result_class = true, $result_wrap_class = false)
{ {
if (is_null($this->positions)) { if (is_null($this->positions)) {
return $this->db->raiseError(MDB2_ERROR, null, null, return $this->db->raiseError(MDB2_ERROR, null, null,

View file

@ -63,11 +63,14 @@ class OC_App{
// The rest comes here // The rest comes here
$apps = self::getEnabledApps(); $apps = self::getEnabledApps();
// prevent app.php from printing output
ob_start();
foreach( $apps as $app ){ foreach( $apps as $app ){
if((is_null($types) or self::isType($app,$types))){ if((is_null($types) or self::isType($app,$types))){
self::loadApp($app); self::loadApp($app);
} }
} }
ob_end_clean();
self::$init = true; self::$init = true;
@ -114,7 +117,11 @@ class OC_App{
self::$appTypes=OC_Appconfig::getValues(false,'types'); self::$appTypes=OC_Appconfig::getValues(false,'types');
} }
return explode(',',self::$appTypes[$app]); if(isset(self::$appTypes[$app])){
return explode(',',self::$appTypes[$app]);
}else{
return array();
}
} }
/** /**
@ -155,7 +162,7 @@ class OC_App{
* This function checks whether or not an app is enabled. * This function checks whether or not an app is enabled.
*/ */
public static function isEnabled( $app ){ public static function isEnabled( $app ){
if( 'yes' == OC_Appconfig::getValue( $app, 'enabled' )){ if( 'files'==$app or 'yes' == OC_Appconfig::getValue( $app, 'enabled' )){
return true; return true;
} }
@ -495,7 +502,6 @@ class OC_App{
* check if any apps need updating and update those * check if any apps need updating and update those
*/ */
public static function updateApps(){ public static function updateApps(){
// The rest comes here
$versions = self::getAppVersions(); $versions = self::getAppVersions();
//ensure files app is installed for upgrades //ensure files app is installed for upgrades
if(!isset($versions['files'])){ if(!isset($versions['files'])){
@ -505,6 +511,7 @@ class OC_App{
$currentVersion=OC_App::getAppVersion($app); $currentVersion=OC_App::getAppVersion($app);
if ($currentVersion) { if ($currentVersion) {
if (version_compare($currentVersion, $installedVersion, '>')) { if (version_compare($currentVersion, $installedVersion, '>')) {
OC_Log::write($app,'starting app upgrade from '.$installedVersion.' to '.$currentVersion,OC_Log::DEBUG);
OC_App::updateApp($app); OC_App::updateApp($app);
OC_Appconfig::setValue($app,'installed_version',OC_App::getAppVersion($app)); OC_Appconfig::setValue($app,'installed_version',OC_App::getAppVersion($app));
} }
@ -533,6 +540,9 @@ class OC_App{
if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml')){ if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml')){
OC_DB::updateDbFromStructure(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml'); OC_DB::updateDbFromStructure(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/database.xml');
} }
if(!self::isEnabled($appid)){
return;
}
if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php')){ if(file_exists(OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php')){
include OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php'; include OC::$APPSROOT.'/apps/'.$appid.'/appinfo/update.php';
} }

View file

@ -12,6 +12,8 @@ class OC_Archive_TAR extends OC_Archive{
const PLAIN=0; const PLAIN=0;
const GZIP=1; const GZIP=1;
const BZIP=2; const BZIP=2;
private $fileList;
/** /**
* @var Archive_Tar tar * @var Archive_Tar tar
@ -64,6 +66,7 @@ class OC_Archive_TAR extends OC_Archive{
mkdir($tmpBase.$path); mkdir($tmpBase.$path);
$result=$this->tar->addModify(array($tmpBase.$path),'',$tmpBase); $result=$this->tar->addModify(array($tmpBase.$path),'',$tmpBase);
rmdir($tmpBase.$path); rmdir($tmpBase.$path);
$this->fileList=false;
return $result; return $result;
} }
/** /**
@ -84,6 +87,7 @@ class OC_Archive_TAR extends OC_Archive{
}else{ }else{
$result=$this->tar->addString($path,$source); $result=$this->tar->addString($path,$source);
} }
$this->fileList=false;
return $result; return $result;
} }
@ -103,12 +107,14 @@ class OC_Archive_TAR extends OC_Archive{
$types=array(null,'gz','bz'); $types=array(null,'gz','bz');
$this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]); $this->tar=new Archive_Tar($this->path,$types[self::getTarType($this->path)]);
$this->tar->createModify(array($tmp),'',$tmp.'/'); $this->tar->createModify(array($tmp),'',$tmp.'/');
$this->fileList=false;
return true;
} }
private function getHeader($file){ private function getHeader($file){
$headers=$this->tar->listContent(); $headers=$this->tar->listContent();
foreach($headers as $header){ foreach($headers as $header){
if($file==$header['filename'] or $file.'/'==$header['filename']){ if($file==$header['filename'] or $file.'/'==$header['filename'] or '/'.$file.'/'==$header['filename'] or '/'.$file==$header['filename']){
return $header; return $header;
} }
} }
@ -144,9 +150,16 @@ class OC_Archive_TAR extends OC_Archive{
$folderContent=array(); $folderContent=array();
$pathLength=strlen($path); $pathLength=strlen($path);
foreach($files as $file){ foreach($files as $file){
if(substr($file,0,1)=='/'){
$file=substr($file,1);
}
if(substr($file,0,$pathLength)==$path and $file!=$path){ if(substr($file,0,$pathLength)==$path and $file!=$path){
if(strrpos(substr($file,0,-1),'/')<=$pathLength){ $result=substr($file,$pathLength);
$folderContent[]=substr($file,$pathLength); if($pos=strpos($result,'/')){
$result=substr($result,0,$pos+1);
}
if(array_search($result,$folderContent)===false){
$folderContent[]=$result;
} }
} }
} }
@ -157,11 +170,15 @@ class OC_Archive_TAR extends OC_Archive{
* @return array * @return array
*/ */
function getFiles(){ function getFiles(){
if($this->fileList){
return $this->fileList;
}
$headers=$this->tar->listContent(); $headers=$this->tar->listContent();
$files=array(); $files=array();
foreach($headers as $header){ foreach($headers as $header){
$files[]=$header['filename']; $files[]=$header['filename'];
} }
$this->fileList=$files;
return $files; return $files;
} }
/** /**
@ -183,7 +200,11 @@ class OC_Archive_TAR extends OC_Archive{
if(!$this->fileExists($path)){ if(!$this->fileExists($path)){
return false; return false;
} }
$success=$this->tar->extractList(array($path),$tmp); if($this->fileExists('/'.$path)){
$success=$this->tar->extractList(array('/'.$path),$tmp);
}else{
$success=$this->tar->extractList(array($path),$tmp);
}
if($success){ if($success){
rename($tmp.$path,$dest); rename($tmp.$path,$dest);
} }
@ -205,7 +226,26 @@ class OC_Archive_TAR extends OC_Archive{
* @return bool * @return bool
*/ */
function fileExists($path){ function fileExists($path){
return $this->getHeader($path)!==null; $files=$this->getFiles();
if((array_search($path,$files)!==false) or (array_search($path.'/',$files)!==false)){
return true;
}else{
$folderPath=$path;
if(substr($folderPath,-1,1)!='/'){
$folderPath.='/';
}
$pathLength=strlen($folderPath);
foreach($files as $file){
if(strlen($file)>$pathLength and substr($file,0,$pathLength)==$folderPath){
return true;
}
}
}
if(substr($path,0,1)!='/'){//not all programs agree on the use of a leading /
return $this->fileExists('/'.$path);
}else{
return false;
}
} }
/** /**
@ -217,6 +257,7 @@ class OC_Archive_TAR extends OC_Archive{
if(!$this->fileExists($path)){ if(!$this->fileExists($path)){
return false; return false;
} }
$this->fileList=false;
//no proper way to delete, extract entire archive, delete file and remake archive //no proper way to delete, extract entire archive, delete file and remake archive
$tmp=OCP\Files::tmpFolder(); $tmp=OCP\Files::tmpFolder();
$this->tar->extract($tmp); $this->tar->extract($tmp);

View file

@ -78,6 +78,10 @@ class OC{
* requested file of app * requested file of app
*/ */
public static $REQUESTEDFILE = ''; public static $REQUESTEDFILE = '';
/**
* check if owncloud runs in cli mode
*/
public static $CLI = false;
/** /**
* SPL autoload * SPL autoload
*/ */
@ -223,6 +227,7 @@ class OC{
$installedVersion=OC_Config::getValue('version','0.0.0'); $installedVersion=OC_Config::getValue('version','0.0.0');
$currentVersion=implode('.',OC_Util::getVersion()); $currentVersion=implode('.',OC_Util::getVersion());
if (version_compare($currentVersion, $installedVersion, '>')) { if (version_compare($currentVersion, $installedVersion, '>')) {
OC_Log::write('core','starting upgrade from '.$installedVersion.' to '.$currentVersion,OC_Log::DEBUG);
$result=OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml'); $result=OC_DB::updateDbFromStructure(OC::$SERVERROOT.'/db_structure.xml');
if(!$result){ if(!$result){
echo 'Error while upgrading the database'; echo 'Error while upgrading the database';
@ -319,8 +324,9 @@ class OC{
if (defined('DEBUG') && DEBUG){ if (defined('DEBUG') && DEBUG){
ini_set('display_errors', 1); ini_set('display_errors', 1);
} }
self::$CLI=(php_sapi_name() == 'cli');
date_default_timezone_set('Europe/Berlin'); date_default_timezone_set('UTC');
ini_set('arg_separator.output','&amp;'); ini_set('arg_separator.output','&amp;');
//try to configure php to enable big file uploads. //try to configure php to enable big file uploads.
@ -368,15 +374,17 @@ class OC{
self::checkInstalled(); self::checkInstalled();
self::checkSSL(); self::checkSSL();
// CSRF protection // CSRF protection
if(isset($_SERVER['HTTP_REFERER'])) $referer=$_SERVER['HTTP_REFERER']; else $referer=''; if(isset($_SERVER['HTTP_REFERER'])) $referer=$_SERVER['HTTP_REFERER']; else $referer='';
if(isset($_SERVER['HTTPS']) and $_SERVER['HTTPS']<>'') $protocol='https://'; else $protocol='http://'; if(isset($_SERVER['HTTPS']) and $_SERVER['HTTPS']<>'') $protocol='https://'; else $protocol='http://';
$server=$protocol.$_SERVER['SERVER_NAME']; if(!self::$CLI){
if(($_SERVER['REQUEST_METHOD']=='POST') and (substr($referer,0,strlen($server))<>$server)) { $server=$protocol.$_SERVER['SERVER_NAME'];
$url = $protocol.$_SERVER['SERVER_NAME'].OC::$WEBROOT.'/index.php'; if(($_SERVER['REQUEST_METHOD']=='POST') and (substr($referer,0,strlen($server))<>$server)) {
header("Location: $url"); $url = $protocol.$_SERVER['SERVER_NAME'].OC::$WEBROOT.'/index.php';
exit(); header("Location: $url");
} exit();
}
}
self::initSession(); self::initSession();
self::initTemplateEngine(); self::initTemplateEngine();

View file

@ -52,8 +52,9 @@ class OC_Files {
* *
* @param dir $dir * @param dir $dir
* @param file $file ; seperated list of files to download * @param file $file ; seperated list of files to download
* @param boolean $only_header ; boolean to only send header of the request
*/ */
public static function get($dir,$files){ public static function get($dir,$files, $only_header = false){
if(strpos($files,';')){ if(strpos($files,';')){
$files=explode(';',$files); $files=explode(';',$files);
} }
@ -118,6 +119,11 @@ class OC_Files {
header("HTTP/1.0 403 Forbidden"); header("HTTP/1.0 403 Forbidden");
die('403 Forbidden'); die('403 Forbidden');
} }
if($only_header){
if(!$zip)
header("Content-Length: ".OC_Filesystem::filesize($filename));
return ;
}
if($zip){ if($zip){
$handle=fopen($filename,'r'); $handle=fopen($filename,'r');
if ($handle) { if ($handle) {

View file

@ -130,10 +130,19 @@ class OC_Installer{
// check the code for not allowed calls // check the code for not allowed calls
if(!OC_Installer::checkCode($info['id'],$extractDir)){ 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); OC_Helper::rmdirr($extractDir);
return false; return false;
} }
// check if the app is compatible with this version of ownCloud
$version=OC_Util::getVersion();
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;
}
//check if an app with the same id is already installed //check if an app with the same id is already installed
if(self::isInstalled( $info['id'] )){ if(self::isInstalled( $info['id'] )){
OC_Log::write('core','App already installed',OC_Log::WARN); OC_Log::write('core','App already installed',OC_Log::WARN);
@ -336,7 +345,7 @@ class OC_Installer{
public static function checkCode($appname,$folder){ public static function checkCode($appname,$folder){
$blacklist=array( $blacklist=array(
'fopen(', 'exec(',
'eval(' 'eval('
// more evil pattern will go here later // more evil pattern will go here later
// will will also check if an app is using private api once the public api is in place // will will also check if an app is using private api once the public api is in place

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides functions to manage apps in ownCloud
*/
class App { class App {
/** /**
@ -153,15 +156,6 @@ class App {
} }
/**
* @param string appid
* @param $app app
* @return OC_FilesystemView
*/
public static function getStorage( $app ){
return \OC_App::getStorage( $app );
}
} }

View file

@ -34,6 +34,9 @@
*/ */
namespace OCP; namespace OCP;
/**
* This class provides functions to read and write configuration data. configuration can be on a system, application or user level
*/
class Config { class Config {

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides access to the internal database system. Use this class exlusively if you want to access databases
*/
class DB { class DB {

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides access to the internal filesystem abstraction layer. Use this class exlusively if you want to access files
*/
class Files { class Files {
@ -99,6 +102,15 @@ class Files {
return(\OC_Helper::buildNotExistingFileName( $path, $filename )); return(\OC_Helper::buildNotExistingFileName( $path, $filename ));
} }
/**
* @param string appid
* @param $app app
* @return OC_FilesystemView
*/
public static function getStorage( $app ){
return \OC_App::getStorage( $app );
}

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides convinient functions to generate and send JSON data. Usefull for Ajax calls
*/
class JSON { class JSON {

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides convinient functions to send the correct http response headers
*/
class Response { class Response {

View file

@ -99,7 +99,7 @@ function html_select_options($options, $selected, $params=array()) {
/** /**
* This class provides the templates for owncloud. * This class provides the template system for owncloud. You can use it to load specific templates, add data and generate the html code
*/ */
class Template extends \OC_Template { class Template extends \OC_Template {

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides access to the user management. You can get information about the currently logged in user and the permissions for example
*/
class User { class User {

View file

@ -30,6 +30,9 @@
// This means that they should be used by apps instead of the internal ownCloud classes // This means that they should be used by apps instead of the internal ownCloud classes
namespace OCP; namespace OCP;
/**
* This class provides different helper functions to make the life of a developer easier
*/
class Util { class Util {

View file

@ -74,7 +74,7 @@ class OC_Util {
* @return array * @return array
*/ */
public static function getVersion(){ public static function getVersion(){
return array(3,91,0); return array(4,80,0);
} }
/** /**
@ -82,7 +82,7 @@ class OC_Util {
* @return string * @return string
*/ */
public static function getVersionString(){ public static function getVersionString(){
return '4 RC'; return '5 pre alpha';
} }
/** /**
@ -311,8 +311,8 @@ class OC_Util {
* Redirect to the user default page * Redirect to the user default page
*/ */
public static function redirectToDefaultPage(){ public static function redirectToDefaultPage(){
if(isset($_REQUEST['redirect_url'])) { if(isset($_REQUEST['redirect_url']) && substr($_REQUEST['redirect_url'], 0, strlen(OC::$WEBROOT)) == OC::$WEBROOT) {
header( 'Location: '.htmlentities($_REQUEST['redirect_url'])); header( 'Location: '.$_REQUEST['redirect_url']);
} else { } else {
header( 'Location: '.OC::$WEBROOT.'/'.OC_Appconfig::getValue('core', 'defaultpage', '?app=files')); header( 'Location: '.OC::$WEBROOT.'/'.OC_Appconfig::getValue('core', 'defaultpage', '?app=files'));
} }

View file

@ -39,8 +39,13 @@ foreach($registeredApps as $app){
$info=OC_App::getAppInfo($app); $info=OC_App::getAppInfo($app);
$active=(OC_Appconfig::getValue($app,'enabled','no')=='yes')?true:false; $active=(OC_Appconfig::getValue($app,'enabled','no')=='yes')?true:false;
$info['active']=$active; $info['active']=$active;
$info['internal']=true; if(isset($info['shipped']) and ($info['shipped']=='true')) {
$info['internallabel']='Internal App'; $info['internal']=true;
$info['internallabel']='Internal App';
}else{
$info['internal']=false;
$info['internallabel']='3rd Party App';
}
$info['preview']='trans.png'; $info['preview']='trans.png';
$apps[]=$info; $apps[]=$info;
} }

View file

@ -38,7 +38,13 @@ foreach($apps as $app){
} }
function loadTests($dir=''){ function loadTests($dir=''){
$test=isset($_GET['test'])?$_GET['test']:false; if(OC::$CLI){
$reporter='TextReporter';
$test=isset($_SERVER['argv'][1])?$_SERVER['argv'][1]:false;
}else{
$reporter='HtmlReporter';
$test=isset($_GET['test'])?$_GET['test']:false;
}
if($dh=opendir($dir)){ if($dh=opendir($dir)){
while($name=readdir($dh)){ while($name=readdir($dh)){
if(substr($name,0,1)!='.'){//no hidden files, '.' or '..' if(substr($name,0,1)!='.'){//no hidden files, '.' or '..'
@ -51,7 +57,7 @@ function loadTests($dir=''){
$testCase=new TestSuite($name); $testCase=new TestSuite($name);
$testCase->addFile($file); $testCase->addFile($file);
if($testCase->getSize()>0){ if($testCase->getSize()>0){
$testCase->run(new HtmlReporter()); $testCase->run(new $reporter());
} }
} }
} }

View file

@ -88,6 +88,7 @@ abstract class Test_FileStorage extends UnitTestCase {
//fill a file with string data //fill a file with string data
$this->instance->file_put_contents('/lorem.txt',$sourceText); $this->instance->file_put_contents('/lorem.txt',$sourceText);
$this->assertFalse($this->instance->is_dir('/lorem.txt'));
$this->assertEqual($sourceText,$this->instance->file_get_contents('/lorem.txt'),'data returned from file_get_contents is not equal to the source data'); $this->assertEqual($sourceText,$this->instance->file_get_contents('/lorem.txt'),'data returned from file_get_contents is not equal to the source data');
//empty the file //empty the file